DDD คืออะไร และทำไมต้องใช้
Domain-Driven Design (DDD)Domain-Driven Design (DDD)แนวทางพัฒนาซอฟต์แวร์ที่เน้นสร้าง domain model ซึ่งเข้าใจกฎและกระบวนการของธุรกิจอย่างลึกซึ้ง แล้วเขียนลงใน code จริง บัญญัติโดย Eric Evans (2003) แบ่งเป็น Strategic และ Tactical DesignStrategic Design คือแนวทางการพัฒนาซอฟต์แวร์ที่ให้ความสำคัญกับการ “สร้างแบบจำลองของธุรกิจ” (Domain ModelDomain ModelModel ของ Domain ที่ฝังกฎและกระบวนการทางธุรกิจไว้ใน code จริง หัวใจของ DDD คือการพัฒนา domain model ที่ “เข้าใจธุรกิจอย่างลึกซึ้ง”Strategic Design) ที่เข้าใจกฎและกระบวนการของ DomainDomainขอบเขตของปัญหาหรือธุรกิจที่ซอฟต์แวร์ของเราเข้าไปแก้ไข เช่น การขนส่งสินค้า การธนาคาร e-commerce — คือ “โลกของผู้ใช้” ที่โปรแกรมต้องเข้าใจStrategic Design อย่างลึกซึ้ง แล้วเขียนแบบจำลองนั้นลงไปใน code จริง ชื่อนี้มาจากหนังสือปี 2003 ของ Eric Evans
flowchart LR D["domain (ธุรกิจจริง)"] --> M["Domain Model"] M --> C["code ที่รันได้"] C -->|ค้นพบความเข้าใจใหม่| M M -->|ปรับ Ubiquitous Language| D
Martin Fowler สรุปไว้ว่า DDD เหมาะอย่างยิ่งกับ DomainDomainขอบเขตของปัญหาหรือธุรกิจที่ซอฟต์แวร์ของเราเข้าไปแก้ไข เช่น การขนส่งสินค้า การธนาคาร e-commerce — คือ “โลกของผู้ใช้” ที่โปรแกรมต้องเข้าใจStrategic Design ที่ “ซับซ้อน” ซึ่งมีตรรกะยุ่งเหยิงจำนวนมากที่ต้องจัดระเบียบ หัวใจไม่ได้อยู่ที่เครื่องมือหรือ framework แต่อยู่ที่ “วิธีคิด” ในการมองธุรกิจและสื่อสารกับผู้เชี่ยวชาญธุรกิจ
ในการพัฒนาซอฟต์แวร์สำหรับ domain ที่ซับซ้อน เราต้องสร้างภาษากลางที่ฝังคำศัพท์ของธุรกิจลงไปในระบบที่เราสร้าง
— ใจความจาก Eric Evans / Martin Fowler
นิยามสามข้อของ Eric Evans
หัวข้อที่มีชื่อว่า “นิยามสามข้อของ Eric Evans”ใน DDD Reference (2015) Evans สรุป DDD เป็นการพัฒนาซอฟต์แวร์ที่ซับซ้อนโดย:
- โฟกัสที่ Core DomainCore Domainsubdomain ที่สำคัญและสร้างความได้เปรียบในการแข่งขันมากที่สุด เป็นเหตุผลที่เราต้องสร้างซอฟต์แวร์เองแทนการซื้อ ควรทุ่มทีมเก่งที่สุดลงตรงนี้Strategic Design — ทุ่มเทกับส่วนที่สร้างคุณค่าและความได้เปรียบมากที่สุด
- สำรวจ ModelModelระบบของแนวคิดที่อธิบายแง่มุมสำคัญของ Domain เพื่อใช้แก้ปัญหา ไม่ใช่ภาพสะท้อนความจริงทั้งหมด แต่เป็น “การตีความที่มีประโยชน์” ของความจริงStrategic Design ร่วมกัน — ระหว่างผู้เชี่ยวชาญธุรกิจกับนักพัฒนา อย่างสร้างสรรค์
- พูด Ubiquitous LanguageUbiquitous Languageภาษากลางที่ทุกคนในทีม (ทั้งนักพัฒนาและผู้เชี่ยวชาญธุรกิจ) ใช้ร่วมกัน อิงกับ domain model โดยตรง คำเดียวกันต้องหมายถึงสิ่งเดียวกัน และสะท้อนลงใน codeStrategic Design ภายใน Bounded ContextBounded Contextขอบเขตที่ชัดเจน (มักเป็นระบบย่อยหรือทีมหนึ่ง) ที่ model หนึ่งใช้ได้และมีความหมายแน่นอน ภายในขอบเขตนี้ Ubiquitous Language สอดคล้องกัน 100%Strategic Design ที่ชัดเจน — ใช้ภาษาเดียวกันในขอบเขตที่กำหนด
Strategic Design (เชิงกลยุทธ์): มองภาพใหญ่ — Ubiquitous LanguageUbiquitous Languageภาษากลางที่ทุกคนในทีม (ทั้งนักพัฒนาและผู้เชี่ยวชาญธุรกิจ) ใช้ร่วมกัน อิงกับ domain model โดยตรง คำเดียวกันต้องหมายถึงสิ่งเดียวกัน และสะท้อนลงใน codeStrategic Design, Bounded ContextBounded Contextขอบเขตที่ชัดเจน (มักเป็นระบบย่อยหรือทีมหนึ่ง) ที่ model หนึ่งใช้ได้และมีความหมายแน่นอน ภายในขอบเขตนี้ Ubiquitous Language สอดคล้องกัน 100%Strategic Design, SubdomainSubdomainส่วนย่อยของ Domain ใหญ่ เช่น Domain e-commerce แตกเป็น subdomain การสั่งซื้อ การชำระเงิน คลังสินค้า ฯลฯ อยู่ใน “พื้นที่ปัญหา” (problem space)Strategic Design, Context MappingContext Mappingกิจกรรมการระบุ Bounded Context และนิยามความสัมพันธ์ระหว่างกัน (เช่น Partnership, Shared Kernel, ACL) เพื่อจัดการการเชื่อมต่อระหว่างทีม/ระบบStrategic Design เป็นส่วนที่ Fowler ยกย่องว่าเป็น “คุณูปการที่สำคัญที่สุด” ของ Evans และใช้ได้กับทุกภาษา/ทุกกระบวนทัศน์
Tactical Design (เชิงปฏิบัติ): building blocks ระดับ code — EntityEntityอ็อบเจ็กต์ที่มี “ตัวตน” (identity) ต่อเนื่องตามเวลา แม้ค่าภายในเปลี่ยน ก็ยังเป็นสิ่งเดิม เช่น ลูกค้า, คำสั่งซื้อ — แยกแยะด้วย id ไม่ใช่ด้วยค่าTactical Design, Value ObjectValue Objectอ็อบเจ็กต์ที่สำคัญที่ “ค่า” ของมัน ไม่มีตัวตนเฉพาะ สองตัวที่ค่าเท่ากันถือว่าเท่ากัน ควรเป็น immutable (เปลี่ยนค่าไม่ได้) เช่น เงิน, วันที่, พิกัดTactical Design, AggregateAggregateกลุ่มของ Entity และ Value Object ที่ถูกมองเป็นหนึ่งหน่วยเดียวเพื่อรักษาความถูกต้องของข้อมูล มีขอบเขตชัดเจน และเป็นหน่วยของ transactionTactical Design, RepositoryRepositoryตัวที่ทำให้เราเข้าถึง Aggregate ราวกับเป็น collection ในหน่วยความจำ ซ่อนรายละเอียดฐานข้อมูล มี1 repository ต่อ1 Aggregate RootTactical Design, Domain EventDomain Eventสิ่งที่ “เกิดขึ้นแล้ว” ใน domain ซึ่งส่วนอื่นสนใจ แทนด้วยอ็อบเจ็กต์ที่เปลี่ยนแปลงไม่ได้ ตั้งชื่อเป็นอดีต เช่น CargoWasRouted ใช้สื่อสารข้าม AggregateTactical Design ฯลฯ เป็นเครื่องมือสร้าง domain model ที่ “รวยพฤติกรรม”
ตัวอย่างที่จะเดินไปด้วยกันทั้งคอร์ส: การขนส่งสินค้า
หัวข้อที่มีชื่อว่า “ตัวอย่างที่จะเดินไปด้วยกันทั้งคอร์ส: การขนส่งสินค้า”ตลอดคอร์สนี้เราจะใช้ตัวอย่างเดียวกับในหนังสือของ Evans คือ ระบบขนส่งตู้ container (Cargo Shipping) ค่อยๆ สร้างขึ้นทีละชั้นในแต่ละบท ควบคู่กับตัวอย่างเสริมที่คุ้นเคยกว่าอย่าง e-commerce เพื่อให้เห็นภาพชัด
บริษัทขนส่งต้องการระบบที่: รับ “จอง” การขนส่งสินค้าจากต้นทางไปปลายทางภายในกำหนด, วาง “แผนเดินทาง” ที่ผ่านท่าเรือและเรือหลายลำ, และ “ติดตามสถานะ” ของสินค้าระหว่างทาง ฟังดูเหมือน CRUD แต่กฎทางธุรกิจซับซ้อนกว่าที่คิดมาก — นี่คือสนามที่ DDD เปล่งประกาย
ในโลก e-commerce “คำสั่งซื้อ (Order)” ก็มีกฎทำนองเดียวกัน เช่น ยอดรวมต้องตรงกับรายการสินค้า, เปลี่ยนสถานะได้ตามลำดับที่ถูกต้องเท่านั้น เราจะเทียบเคียงสองโลกนี้ไปต่อเนื่อง
เจาะลึกแนวคิดในบทนี้ต่อได้ที่คลังอ้างอิง DevIQ:
- Domain Model — แบบจำลองธุรกิจที่ DDD ยึดเป็นแกนกลาง ตรงกับที่บทนี้อธิบายว่า DDD คือการฝังความเข้าใจ domain ลงใน code
- Domain (Core Domain) — ขยายความ “โฟกัสที่ Core Domain” ข้อแรกในนิยามสามข้อของ Evans ว่าทำไมต้องทุ่มเทกับส่วนที่สร้างคุณค่าที่สุด
- Ubiquitous Language — ภาษากลางระหว่างผู้เชี่ยวชาญธุรกิจกับนักพัฒนา ที่บทนี้ยกเป็นหนึ่งในสามหัวใจของ DDD
- Strategic Design — รายละเอียดของ “ครึ่งเชิงกลยุทธ์” ที่บทนี้แนะนำไว้แบบภาพรวม
- Tactical Design — รายละเอียดของ “ครึ่งเชิงปฏิบัติ” (Entity, Value Object, Aggregate ฯลฯ) ที่บทนี้แนะนำไว้แบบภาพรวม
เช็กความเข้าใจ — Stage 0
ข้อ 1 / 3ข้อใดอธิบาย “หัวใจ” ของ DDD ได้ดีที่สุด?