DDD: Aggregation root!?

วันนี้อ่านเจอเทคนิคและหลักการที่ใช้กับการออกแบบ OOD มาจาก DDD (Domain-Driven Development) เรียกว่า Aggregation root

ยกตัวอย่างเช่น Web shopping domain อันนี้

Domain model of a shopping web app

ปกติหลังจากทำ domain diagram เสร็จ เราก็มักจะสร้าง Object ตามหลักการ Low Coupling & High Cohesion และ SoC

Object model by SoC

วิธีนี้ค่อนข้าง work กับเราเกือบทุก case จนกระทั่งในกรณีนี้เราเอามาเตรียมสอน แล้วพบว่าความสัมพันธ์ของ Merchant กับ Product เป็นปัญหาในการเขียนตัวอย่าง load Product จาก database เพราะในการเก็บ object ทั้งสองลง database นั้น ความสัมพันธ์มันจะกลับกัน (คือ Product table จะมี FK ของ Merchant -- ในขณะที่ object model Product ไม่มี link ไปหา Merchant แต่ Merchant มี collection ของ Product :s ) code มันซับซ้อนเกินที่จะใช้เป็นตัวอย่างสอน

สุดท้ายเลยเขียน object class represents database schema ไปเลย ง่ายดี หุหุ

แต่พออ่านเจอเรื่อง Aggregation root แล้ว น่าสนใจมาก ดูเหมือนว่า DDD จะกำหนดรายละเอียดในการ design เพิ่มขึ้น ที่เห็น (จาก wiki) คือเรื่อง Entity, Value Object, และ Aggregation root นี่แหละ

ไอเดียของ Aggregation root นั้น ก็คือการกำหนด aggregation relationship นั่นแหละ แต่มี constraints เพิ่มเติมดังนี้

  1. Aggregation ของ objects ถือเป็น single unit

    change ใดๆที่เกิดขึ้นกับ object ใน Aggregation เสมือนว่ากระทำกับ Aggregation as a whole

  2. Aggregation จะมี root entity เพียงหนึ่งเดียว การ access object ภายใน aggregation นี้ จะต้องผ่าน root entity เท่านั้น

  3. Object ใดๆที่อยู่ใน aggregation และไม่ใช่ root จะมี ID ที่ unique เฉพาะ scope ของ Aggregation นั้น (คือไม่จำเป็นต้อง globally unique)

  4. Aggregation ควรจะ high cohesion (อันนี้ใส่เข้ามาเอง สังเกตุจากตัวอย่าง)

จากหลักการดังกล่าว object model ข้างบนจะมีหน้าตาใหม่ดังนี้

Object model grouped by aggregation

จริงๆ จะสังเกตุได้ว่า มันก็ตรงกับ database schema ที่ควรจะเป็นนั่นแหละ แต่เข้าใจว่าหลักการที่เพิ่มมา จะทำให้การทำ O/R mapping ง่ายขึ้น

ข้อดี (จากหนังสือ)

  • ทำ validation ได่ง่าย โดยผ่าน root object (ในแง่นี้ดูเหมือน root object จะรู้มาก ไม่แน่ใจว่าดีจริงหรือเปล่า)
  • aggregate เทียบเท่าได้กับ atomic unit การทำ transaction หรือ cascade operation จะกระทำกับ unit (ทำให้จำได้ง่ายขึ้น)

น่าลองเอาไปใช้ดูแฮะ

ป.ล. Entity กับ Value Object ก็น่าสนใจ