DDD สำหรับเรา
อยากเก่งขึ้นในงานที่ทำ อยากให้ project ประสบความสำเร็จมากขึ้น อยากช่วยให้ธุรกิจของตัวเองแข่งขันในระดับที่สูงขึ้นด้วยซอฟต์แวร์ที่สร้างขึ้นมาเอง อยากเขียนซอฟต์แวร์ที่ไม่เพียง “เข้าใจสิ่งที่ธุรกิจต้องการอย่างถูกต้อง” แต่ยังทำงานได้ที่ระดับ scale บนสถาปัตยกรรมสมัยใหม่ที่สุด — การเรียนรู้ Domain-Driven Design (DDD)Domain-Driven Design (DDD)แนวทางพัฒนาซอฟต์แวร์ที่เน้นสร้าง domain model ซึ่งเข้าใจกฎและกระบวนการของธุรกิจอย่างลึกซึ้ง แล้วเขียนลงใน code จริง บัญญัติโดย Eric Evans (2003) แบ่งเป็น Strategic และ Tactical DesignStrategic Design และเรียนรู้ได้อย่างรวดเร็ว คือเส้นทางที่พาไปถึงทั้งหมดนั้นและมากกว่านั้น
DDD คือกล่องเครื่องมือที่ช่วยออกแบบและสร้างซอฟต์แวร์ซึ่งให้คุณค่าสูง ทั้งในเชิงกลยุทธ์ (strategic) และเชิงยุทธวิธี (tactical) องค์กรเก่งทุกเรื่องไม่ได้ จึงต้อง เลือกอย่างรอบคอบว่าจะโดดเด่นเรื่องอะไร เครื่องมือเชิงกลยุทธ์ของ DDD ช่วยให้ทีมเลือกแนวทางออกแบบและตัดสินใจเรื่องการเชื่อมต่อระบบที่ได้เปรียบในการแข่งขันที่สุดสำหรับธุรกิจ องค์กรจะได้ประโยชน์มากที่สุดจากซอฟต์แวร์ model ที่สะท้อน ความสามารถหลัก (core competencies) ของตัวเองออกมาอย่างชัดเจน ส่วนเครื่องมือเชิงยุทธวิธีก็ช่วยให้ทีมออกแบบซอฟต์แวร์ที่จำลองกระบวนการเฉพาะตัวของธุรกิจได้อย่างแม่นยำ และนำไป deploy ได้หลากหลายรูปแบบ ทั้งบนเครื่องในองค์กรเองหรือบนคลาวด์
หนังสือเล่มนี้ (เขียนโดย Vaughn Vernon) คือ DDD ฉบับ “กลั่นเข้มข้น” — ครอบคลุมทั้งเครื่องมือเชิงกลยุทธ์และเชิงยุทธวิธี แต่บีบให้กระชับ เพราะผู้เขียนเข้าใจดีว่างานพัฒนาในอุตสาหกรรมที่เร่งรีบนั้นไม่เปิดโอกาสให้ใครหยุดไปนั่งอ่านตำราเรื่อง DDD เป็นเดือนๆ ทั้งที่ก็ยังอยากลงมือใช้ DDD ให้เร็วที่สุดเท่าที่จะทำได้
Vaughn Vernon คือผู้เขียน Implementing Domain-Driven Design [IDDD] ที่ขายดี และเป็นผู้สอนเวิร์กช็อป IDDD สามวันให้นักพัฒนาทั่วโลก หนังสือเล่มนี้คือ DDD ในรูปแบบที่ “บีบอัดอย่างถึงที่สุด” ส่วนหนึ่งของความตั้งใจที่จะพา DDD ไปสู่ทุกทีมพัฒนาซอฟต์แวร์ — รวมถึงพามาถึงเราทุกคนด้วย
DDD จะเจ็บไหม? (Will DDD Hurt?)
หัวข้อที่มีชื่อว่า “DDD จะเจ็บไหม? (Will DDD Hurt?)”หลายคนอาจเคยได้ยินว่า DDD เป็นแนวทางพัฒนาซอฟต์แวร์ที่ “ซับซ้อน” ซับซ้อนจริงหรือ? ความจริงคือ DDD ไม่ได้ซับซ้อนโดยจำเป็น มันเป็นชุดเทคนิคขั้นสูงที่ออกแบบมาเพื่อใช้กับ project ซอฟต์แวร์ที่ซับซ้อนต่างหาก ด้วยพลังของมันและปริมาณที่ต้องเรียนรู้ การหยิบ DDD มาใช้เองโดยไม่มีคนนำทางจึงอาจดูน่าหวั่นใจอยู่บ้าง และตำรา DDD เล่มอื่นๆ ก็มักหนาหลายร้อยหน้าจนย่อยและนำไปใช้ได้ยาก

ผู้ที่ใช้ DDD จริงมักกลับไปเปิดอ่านตำราซ้ำหลายครั้ง บางคนถึงขั้นสรุปว่า “เรียนเท่าไรก็ไม่มีวันพอ” หนังสือเล่มนี้จึงเหมาะจะใช้เป็น คู่มืออ้างอิงเร็ว ระหว่างที่ฝีมือเราค่อยๆ คมขึ้น ขณะเดียวกันก็ช่วยให้คนที่เคย “ขาย DDD ให้เพื่อนร่วมงานและทีมบริหารไม่สำเร็จ” ทำได้ง่ายขึ้น ทั้งจากการอธิบาย DDD ในรูปแบบกระชับ และจากการชี้ให้เห็นว่ามีเครื่องมือช่วยเร่งและบริหารการนำ DDD ไปใช้
ข่าวดีคือ DDD ไม่จำเป็นต้องเจ็บปวด ในเมื่อเราต้องรับมือกับความซับซ้อนใน project อยู่แล้วทุกวัน DDD นี่แหละที่จะช่วย ลดความเจ็บปวด จากการเอาชนะความซับซ้อนนั้นลงได้
DDD ไม่ใช่ “ความหรูหราทางวิชาการ” แต่คือ กล่องเครื่องมือเชิงปฏิบัติ ที่ช่วยให้ทีมเลือกแนวทางออกแบบและการเชื่อมต่อระบบที่ได้เปรียบในการแข่งขันที่สุดสำหรับธุรกิจ องค์กรเก่งทุกเรื่องไม่ได้ — DDD ช่วยให้เรา ลงแรงตรงจุดที่สำคัญที่สุด
design ที่ดี ที่แย่ และที่ “ได้ผล” (Good, Bad, and Effective Design)
หัวข้อที่มีชื่อว่า “design ที่ดี ที่แย่ และที่ “ได้ผล” (Good, Bad, and Effective Design)”คนเรามักพูดกันถึง design ที่ดีและ design ที่แย่ แต่ทีมพัฒนาจำนวนมากกลับแทบไม่ได้คิดเรื่อง design เลย สิ่งที่ทำกันจริงคือสิ่งที่ Vernon เรียกว่า “การสับ Post-it บนบอร์ด” (task-board shuffle) — ทีมมีรายการ task อยู่ใน backlog แบบ Scrum แล้วก็แค่ลาก Post-it จากช่อง “To Do” ไปช่อง “In Progress” การคิด backlog item ขึ้นมาแล้วทำ “task-board shuffle” นี้กลายเป็น “ความคิดเชิงลึกทั้งหมด” ที่ทีมมี ที่เหลือก็ปล่อยให้เป็นวีรกรรมการเขียน code ของโปรแกรมเมอร์ที่ “ลุยพ่น code กันออกมา” ผลลัพธ์จึงแทบไม่เคยดีอย่างที่ควรจะเป็น และธุรกิจที่ต้องจ่ายราคาแพงที่สุดให้กับ design ที่ไม่เคยมีอยู่จริง
เรื่องนี้มักเกิดจากแรงกดดันให้ส่งมอบซอฟต์แวร์ตามตารางที่ไม่ยอมผ่อนปรน ฝ่ายบริหารใช้ Scrum เพื่อ คุมไทม์ไลน์ เป็นหลัก แทนที่จะเปิดทางให้เกิดสิ่งที่เป็นหนึ่งในหัวใจสำคัญที่สุดของ Scrum นั่นคือ “การได้มาซึ่งความรู้” (knowledge acquisition)
เวลาไปให้คำปรึกษาหรือสอนตามองค์กรต่างๆ Vernon มักเจอสถานการณ์เดิมๆ คือ project อยู่ในภาวะเสี่ยง และทั้งทีมถูกจ้างมาเพียงเพื่อประคองให้ระบบยังเดินต่อได้ คอยปะ code และข้อมูลกันทุกวัน นี่คือปัญหาร้ายกาจที่พบบ่อย (ไล่จากระดับธุรกิจลงมาถึงระดับเทคนิค) — และน่าสนใจว่าล้วนเป็นสิ่งที่ DDD ช่วยให้หลีกเลี่ยงได้:
- มองงานพัฒนาซอฟต์แวร์เป็น ศูนย์ต้นทุน (cost center) ไม่ใช่ศูนย์สร้างกำไร เพราะธุรกิจมองคอมพิวเตอร์และซอฟต์แวร์เป็น “ภาระจำเป็น” มากกว่าจะเป็นแหล่งความได้เปรียบเชิงกลยุทธ์ (ถ้าเป็นวัฒนธรรมองค์กรที่ฝังลึกแล้ว อาจไม่มีทางแก้)
- นักพัฒนาหมกมุ่นกับเทคโนโลยีมากเกินไป พยายามแก้ปัญหาด้วยเทคโนโลยีแทนการคิดและออกแบบอย่างรอบคอบ จนไล่ตาม “ของเล่นใหม่ๆ” (shiny objects) คือเทรนด์เทคโนโลยีล่าสุดไปต่อเนื่อง
- ให้ความสำคัญกับ ฐานข้อมูล มากเกินไป จนการคุยเรื่องทางออกหมุนรอบ database และ data model แทนที่จะเป็นกระบวนการทางธุรกิจ
- ไม่ใส่ใจตั้งชื่อ object และ operation ให้ตรงกับเจตนาทางธุรกิจที่มันรองรับ เกิดเป็น ช่องว่างกว้าง ระหว่าง mental model ที่ธุรกิจเป็นเจ้าของ กับซอฟต์แวร์ที่นักพัฒนาส่งมอบ
- ปัญหาข้างต้นมักเป็นผลจากการ ร่วมมือกับฝั่งธุรกิจน้อยเกินไป ผู้มีส่วนได้ส่วนเสียทางธุรกิจหมกตัวทำงานแยกเดี่ยว ผลิต specification ที่ไม่มีใครได้ใช้ หรือนักพัฒนาเอาไปใช้ได้เพียงบางส่วน
- การประมาณการ (estimate) เป็นที่ต้องการสูง และการทำมันบ่อยๆ ก็กินเวลาและแรงไปมาก จนทำให้การส่งมอบซอฟต์แวร์ล่าช้า นักพัฒนาเลยหันไปใช้ “task-board shuffle” แทนการออกแบบอย่างมีความคิด ผลคือได้ Big Ball of MudBig Ball of Mudระบบที่ปนเปกันยุ่งเหยิงไม่มีขอบเขตชัด ให้ลากเส้นล้อมไว้แล้วยอมรับสภาพ ไม่พยายามทำ model ละเอียดในนั้น และระวังไม่ให้ลามไป context อื่นStrategic Design แทนที่จะแยก model ตามตัวขับเคลื่อนทางธุรกิจอย่างเหมาะสม
- ยัด ตรรกะทางธุรกิจ (Business Logic) ไว้ในคอมโพเนนต์ของ UI และชั้น persistence อีกทั้งยังมักทำงาน persistence แทรกกลางตรรกะทางธุรกิจ
- มี query ฐานข้อมูลที่พัง ช้า และล็อก จนผู้ใช้ทำงานทางธุรกิจที่ไวต่อเวลาไม่ได้
- เกิด abstraction ผิดๆ เพราะนักพัฒนาพยายามรองรับทั้งความต้องการปัจจุบันและที่จินตนาการว่าจะเกิดในอนาคต ด้วยการ generalize มากเกินไป แทนที่จะแก้ความต้องการทางธุรกิจที่เป็นรูปธรรมจริงๆ
- มี service ที่ผูกกันแน่นเกินไป operation หนึ่งทำใน service หนึ่ง แล้ว service นั้นเรียกตรงไปยังอีก service เพื่อทำงานชดเชย การผูกกันแบบนี้มักนำไปสู่กระบวนการธุรกิจที่พัง ข้อมูลที่ไม่ตรงกัน และระบบที่ดูแลรักษายากมาก
ทั้งหมดนี้มักเกิดขึ้นภายใต้ความเชื่อว่า “ไม่ออกแบบแล้วซอฟต์แวร์จะถูกลง” และบ่อยครั้งมันเป็นเพียงเพราะธุรกิจและนักพัฒนาไม่รู้ว่ามีทางเลือกที่ดีกว่านี้มาก “ซอฟต์แวร์กำลังกลืนกินโลก” (Software is eating the world) และเราควรตระหนักว่าซอฟต์แวร์ก็กลืนกินกำไรของเราได้เช่นกัน — หรือจะป้อนกำไรให้เราอย่างเต็มอิ่มก็ได้
ที่สำคัญคือต้องเข้าใจว่า “เศรษฐศาสตร์ของการไม่ออกแบบ” (No Design) ที่คิดกันไปเองนั้นเป็นเรื่องลวง ที่หลอกคนซึ่งกดดันให้ผลิตซอฟต์แวร์โดยไม่คิดออกแบบได้อย่างแนบเนียน เพราะ design ยังคงไหลออกจากสมองของนักพัฒนาแต่ละคนผ่านปลายนิ้วขณะที่เขาปล้ำกับ code โดยไม่มี input จากใครเลย รวมถึงจากฝั่งธุรกิจด้วย คำกล่าวนี้สรุปสถานการณ์ได้ดี:
คำถามที่ว่า design จำเป็นหรือคุ้มค่าหรือไม่ ล้วนไม่ตรงประเด็น เพราะ design เป็นสิ่งที่หลีกเลี่ยงไม่ได้ ทางเลือกของ design ที่ดีคือ design ที่แย่ ไม่ใช่การไม่มี design เลย
— Douglas Martin, Book Design: A Practical Introduction
แม้คำพูดของ Martin จะไม่ได้พูดถึงการออกแบบซอฟต์แวร์โดยตรง แต่ก็ใช้ได้กับงานของเรา ที่ซึ่งไม่มีอะไรมาทดแทนการออกแบบอย่างมีความคิดได้ ในสถานการณ์ที่เพิ่งเล่าไป ถ้ามีนักพัฒนาห้าคนใน project “การไม่ออกแบบ” จะให้ผลเป็นการผสม design ห้าแบบเข้าด้วยกัน — คือได้ภาษาทางธุรกิจที่ต่างคนต่างกุขึ้นมาเอง5 version ปนกัน โดยไม่ได้รับประโยชน์จาก ผู้เชี่ยวชาญธุรกิจ (Domain Expert)Domain Expertผู้เชี่ยวชาญธุรกิจที่รู้กฎ กระบวนการ และความต้องการของ domain อย่างลึกซึ้ง เป็นแหล่งความรู้สำคัญที่ทีมพัฒนาต้องร่วมงานด้วยอย่างใกล้ชิดใน DDDStrategic Design ตัวจริงเลย
สรุปก็คือ เราล้วน “สร้าง model” ไม่ว่าจะยอมรับหรือไม่ เปรียบได้กับการกำเนิดของถนน ถนนโบราณบางสายเริ่มจากทางเกวียนที่ค่อยๆ ถูกเหยียบจนเป็นทางเดิน มันเลี้ยวไปอย่างไร้เหตุผลและแยกแขนงตามความต้องการพื้นๆ ของคนไม่กี่คน ต่อมาทางเหล่านี้จึงถูกปรับให้เรียบและลาดยางเพื่อความสะดวกของผู้สัญจรที่มากขึ้น ทางลัดเฉพาะกิจเหล่านี้ยังถูกใช้อยู่ทุกวันนี้ไม่ใช่เพราะมันถูกออกแบบมาดี แต่เพราะ “มันมีอยู่” ส่วนถนนสมัยใหม่ถูกวางแผนและออกแบบจากการศึกษาประชากร สภาพแวดล้อม และการคาดการณ์การจราจรอย่างรอบคอบ ถนนทั้งสองแบบล้วนเป็น “model” — แบบหนึ่งใช้สติปัญญาขั้นต่ำที่สุด อีกแบบใช้ความคิดอย่างเต็มที่ ซอฟต์แวร์ก็สร้าง model ได้จากทั้งสองมุมมองนี้เช่นกัน
ถ้ากลัวว่าการผลิตซอฟต์แวร์ด้วยการออกแบบอย่างมีความคิดจะแพง ลองนึกดูว่ามันจะแพงกว่าแค่ไหนที่ต้องทนอยู่กับ — หรือต้องไปแก้ — design ที่แย่ ยิ่งเป็นซอฟต์แวร์ที่ต้องสร้างความแตกต่างจากคู่แข่งและสร้างความได้เปรียบในการแข่งขันอย่างมีนัยสำคัญ ยิ่งจริงเข้าไปใหญ่
คำที่ใกล้เคียงกับ “ดี (good)” คือ “ได้ผล (effective)” และมันอาจอธิบายสิ่งที่เราควรไขว่คว้าในการออกแบบซอฟต์แวร์ได้แม่นยำกว่า — นั่นคือ effective design (design ที่ได้ผล) คือ design ที่ตอบสนองความต้องการขององค์กรได้ถึงขั้นทำให้องค์กร สร้างความแตกต่างเหนือคู่แข่งด้วยซอฟต์แวร์ มันบังคับให้องค์กรเข้าใจว่าตัวเองต้องโดดเด่นเรื่องอะไร แล้วใช้ความเข้าใจนั้นนำทางการสร้าง model ซอฟต์แวร์ที่ถูกต้อง
ใน Scrum การได้มาซึ่งความรู้ (knowledge acquisition) เกิดจากการทดลองและการเรียนรู้ร่วมกัน เรียกอีกอย่างว่า “การซื้อข้อมูล” (buying information) ความรู้ไม่เคยได้มาฟรีๆ แต่หนังสือเล่มนี้ช่วยให้เราเร่งวิธีได้มาซึ่งความรู้นั้นได้ และเผื่อใครยังสงสัยว่า effective design สำคัญจริงไหม อย่าลืมข้อคิดจากคนที่ดูจะเข้าใจความสำคัญนี้เป็นอย่างดี:
คนส่วนใหญ่เข้าใจผิดว่า design คือสิ่งที่มัน “หน้าตาเป็นอย่างไร” คิดว่ามันเป็นแค่เปลือกนอก — ราวกับว่ายื่นกล่องให้ดีไซเนอร์แล้วบอกว่า “ทำให้มันสวย” นั่นไม่ใช่ความหมายของ design สำหรับเรา design ไม่ได้เป็นแค่หน้าตาหรือสัมผัส แต่ design คือ “วิธีที่มันทำงาน”
— Steve Jobs
ในงานซอฟต์แวร์ effective design สำคัญที่สุด และเมื่อทางเลือกมีเพียงทางเดียว Vernon แนะนำให้เลือก effective design
Strategic Design — มองภาพใหญ่ก่อน
หัวข้อที่มีชื่อว่า “Strategic Design — มองภาพใหญ่ก่อน”DDD เริ่มที่ระดับ กลยุทธ์ (strategic design) ซึ่งสำคัญอย่างยิ่ง เพราะแทบเป็นไปไม่ได้ที่จะนำ tactical design ไปใช้อย่างได้ผลถ้าไม่ได้เริ่มจาก strategic design ก่อน Strategic design เปรียบเหมือนการลงพู่กันด้วยฝีแปรงกว้างๆ ก่อนจะลงรายละเอียดของการ implement มันชี้ให้เห็นว่าอะไรสำคัญเชิงกลยุทธ์ต่อธุรกิจ จะแบ่งงานตามความสำคัญอย่างไร และจะเชื่อมต่อกันให้ดีที่สุดได้อย่างไร

สิ่งแรกที่จะได้เรียนคือการแยก domain model ออกจากกันด้วย pattern เชิงกลยุทธ์ที่ชื่อ Bounded ContextBounded Contextขอบเขตที่ชัดเจน (มักเป็นระบบย่อยหรือทีมหนึ่ง) ที่ model หนึ่งใช้ได้และมีความหมายแน่นอน ภายในขอบเขตนี้ Ubiquitous Language สอดคล้องกัน 100%Strategic Design (ขอบเขตที่ model หนึ่งใช้ได้และมีความหมายแน่นอน) และคู่กันอย่างแนบแน่นคือการพัฒนา Ubiquitous LanguageUbiquitous Languageภาษากลางที่ทุกคนในทีม (ทั้งนักพัฒนาและผู้เชี่ยวชาญธุรกิจ) ใช้ร่วมกัน อิงกับ domain model โดยตรง คำเดียวกันต้องหมายถึงสิ่งเดียวกัน และสะท้อนลงใน codeStrategic Design (ภาษากลาง) ให้เป็น domain model ภายในขอบเขตนั้น
นอกจากนั้นยังจะได้เห็นความสำคัญของการดึงทั้งนักพัฒนาและ ผู้เชี่ยวชาญธุรกิจ (Domain Expert)Domain Expertผู้เชี่ยวชาญธุรกิจที่รู้กฎ กระบวนการ และความต้องการของ domain อย่างลึกซึ้ง เป็นแหล่งความรู้สำคัญที่ทีมพัฒนาต้องร่วมงานด้วยอย่างใกล้ชิดใน DDDStrategic Design เข้ามาร่วมกันพัฒนา Ubiquitous Language ของ model การรวมพลังของคนเก่งและมีไฟจากทั้งสองฝั่งนี้คือส่วนผสมสำคัญที่ทำให้ DDD ให้ผลลัพธ์ที่ดีที่สุด ภาษาที่พัฒนาร่วมกันจะกลายเป็นภาษากลางที่แทรกซึมอยู่ทั่วทั้งการสื่อสารด้วยวาจาในทีมและในซอฟต์แวร์ model
เมื่อก้าวลึกขึ้นในเชิงกลยุทธ์ เราจะได้เรียนรู้เรื่อง SubdomainSubdomainส่วนย่อยของ Domain ใหญ่ เช่น Domain e-commerce แตกเป็น subdomain การสั่งซื้อ การชำระเงิน คลังสินค้า ฯลฯ อยู่ใน “พื้นที่ปัญหา” (problem space)Strategic Design และวิธีที่มันช่วยรับมือกับความซับซ้อนไร้ขอบเขตของระบบ legacy รวมถึงปรับปรุงผลลัพธ์ใน project ใหม่ (greenfield) โดยเฉพาะการระบุ Core DomainCore Domainsubdomain ที่สำคัญและสร้างความได้เปรียบในการแข่งขันมากที่สุด เป็นเหตุผลที่เราต้องสร้างซอฟต์แวร์เองแทนการซื้อ ควรทุ่มทีมเก่งที่สุดลงตรงนี้Strategic Design — ส่วนที่สำคัญที่สุดที่ควรทุ่มแรงลงไป และจะได้เห็นวิธีเชื่อมต่อหลาย Bounded Context เข้าด้วยกันด้วยเทคนิคที่เรียกว่า Context MappingContext Mappingกิจกรรมการระบุ Bounded Context และนิยามความสัมพันธ์ระหว่างกัน (เช่น Partnership, Shared Kernel, ACL) เพื่อจัดการการเชื่อมต่อระหว่างทีม/ระบบStrategic Design ซึ่ง Context Map จะนิยามทั้งความสัมพันธ์ระหว่างทีมและกลไกทางเทคนิคที่อยู่ระหว่าง2 Bounded Context ที่เชื่อมต่อกัน
ในระบบขนส่งตู้ container คำว่า “Customer” ในบริบท การจอง (ผู้ว่าจ้างขนส่ง) กับในบริบท การออกใบแจ้งหนี้ (ผู้ที่ต้องชำระเงิน) อาจไม่ใช่สิ่งเดียวกันเป๊ะ การขีด Bounded ContextBounded Contextขอบเขตที่ชัดเจน (มักเป็นระบบย่อยหรือทีมหนึ่ง) ที่ model หนึ่งใช้ได้และมีความหมายแน่นอน ภายในขอบเขตนี้ Ubiquitous Language สอดคล้องกัน 100%Strategic Design ให้ชัดช่วยให้แต่ละทีมมีภาษาของตัวเองโดยไม่ตีกัน
Tactical Design — ลงรายละเอียดใน code
หัวข้อที่มีชื่อว่า “Tactical Design — ลงรายละเอียดใน code”หลังจากวางรากฐานที่มั่นคงด้วย strategic design แล้ว เราจึงจะได้ค้นพบเครื่องมือเชิงยุทธวิธี (tactical design) ที่โดดเด่นที่สุดของ DDD ถ้า strategic design คือฝีแปรงกว้าง tactical design ก็เปรียบเหมือนการใช้พู่กันเส้นเล็กระบายรายละเอียดอันประณีตของ domain model หนึ่งในเครื่องมือที่สำคัญที่สุดใช้สำหรับรวม Entity และ Value Object เข้าด้วยกันเป็นกลุ่มที่ “ขนาดพอเหมาะ” นั่นคือ pattern ชื่อ AggregateAggregate RootEntity หนึ่งตัวที่เป็น “ประตูเดียว” เข้าสู่ Aggregate การอ้างอิงจากภายนอกทำได้กับ root เท่านั้น root จึงควบคุมกฎความถูกต้องของทั้งกลุ่มTactical Design

หัวใจของ DDD คือการจำลอง domain ให้ชัดเจนที่สุดเท่าที่จะทำได้ การใช้ Domain EventDomain Eventสิ่งที่ “เกิดขึ้นแล้ว” ใน domain ซึ่งส่วนอื่นสนใจ แทนด้วยอ็อบเจ็กต์ที่เปลี่ยนแปลงไม่ได้ ตั้งชื่อเป็นอดีต เช่น CargoWasRouted ใช้สื่อสารข้าม AggregateTactical Design ช่วยทั้งการสร้าง model อย่างชัดเจน และการแบ่งปัน “สิ่งที่เกิดขึ้นแล้ว” ภายใน model ไปยังระบบอื่นที่จำเป็นต้องรู้ ผู้ที่สนใจ event นั้นอาจเป็น Bounded Context ของเราเอง หรือ Bounded Context อื่นที่อยู่ระยะไกลออกไปก็ได้
เมื่อลูกค้ากดสั่งซื้อ Aggregate ชื่อ Order จะบังคับใช้กฎ (เช่น ยอดรวมต้องตรงกับรายการสินค้า) แล้วปล่อย Domain EventDomain Eventสิ่งที่ “เกิดขึ้นแล้ว” ใน domain ซึ่งส่วนอื่นสนใจ แทนด้วยอ็อบเจ็กต์ที่เปลี่ยนแปลงไม่ได้ ตั้งชื่อเป็นอดีต เช่น CargoWasRouted ใช้สื่อสารข้าม AggregateTactical Design ชื่อ OrderPlaced ออกมา — context อื่นอย่าง “คลังสินค้า” หรือ “การจัดส่ง” ก็รับ event นี้ไปทำงานต่อได้ โดยไม่ต้องผูกมัดกันแน่นจนเกินไป
การเรียนรู้และการกลั่นความรู้ (The Learning Process and Refining Knowledge)
หัวข้อที่มีชื่อว่า “การเรียนรู้และการกลั่นความรู้ (The Learning Process and Refining Knowledge)”DDD สอน “วิธีคิด” ที่ช่วยให้ทีมกลั่นความรู้ให้คมขึ้นต่อเนื่อง ขณะที่ค่อยๆ เรียนรู้เกี่ยวกับความสามารถหลัก (core competencies) ของธุรกิจ กระบวนการเรียนรู้นี้คือเรื่องของการ ค้นพบผ่านการพูดคุยกันเป็นกลุ่มและการทดลอง ด้วยการตั้งคำถามต่อสภาพเดิมๆ และท้าทายสมมติฐานเกี่ยวกับซอฟต์แวร์ model เราจะได้เรียนรู้มากมาย และการได้มาซึ่งความรู้อันสำคัญยิ่งนี้จะแพร่กระจายไปทั่วทั้งทีม

นี่คือการลงทุนที่สำคัญทั้งต่อธุรกิจและต่อทีม เป้าหมายไม่ควรหยุดแค่ “เรียนรู้และกลั่น” แต่ต้อง “เรียนรู้และกลั่นให้เร็วที่สุด” ด้วย และมีเครื่องมือเพิ่มเติมที่ช่วยเรื่องนี้รออยู่ในบทท้ายๆ ว่าด้วย “เครื่องมือเร่งและบริหารการนำ DDD ไปใช้”
นี่คือ DDD ฉบับเข้มข้นที่กลั่นมาจาก Implementing Domain-Driven Design [IDDD] ของผู้เขียนเอง — แน่นอนว่าหนังสือเล่มเดียวสอนทุกอย่างเกี่ยวกับ DDD ไม่ได้ เพราะตั้งใจกลั่นเทคนิคให้กระชับ เหมาะเป็น “จุดเริ่ม” และ “คู่มืออ้างอิงเร็ว” ส่วนรายละเอียดเชิงลึกค่อยตามอ่านในเล่มใหญ่หรือเวิร์กช็อป IDDD สามวันได้
เริ่มกันเลย! (Let’s Get Started!)
หัวข้อที่มีชื่อว่า “เริ่มกันเลย! (Let’s Get Started!)”แม้จะเป็นการนำเสนอแบบกระชับ แต่ก็ยังมีเรื่องของ DDD ให้เรียนรู้อีกมาก เราจะเริ่มต้นในบทถัดไปด้วยเรื่อง Strategic Design ผ่าน Bounded ContextBounded Contextขอบเขตที่ชัดเจน (มักเป็นระบบย่อยหรือทีมหนึ่ง) ที่ model หนึ่งใช้ได้และมีความหมายแน่นอน ภายในขอบเขตนี้ Ubiquitous Language สอดคล้องกัน 100%Strategic Design และ Ubiquitous LanguageUbiquitous Languageภาษากลางที่ทุกคนในทีม (ทั้งนักพัฒนาและผู้เชี่ยวชาญธุรกิจ) ใช้ร่วมกัน อิงกับ domain model โดยตรง คำเดียวกันต้องหมายถึงสิ่งเดียวกัน และสะท้อนลงใน codeStrategic Design
- DDD คือกล่องเครื่องมือ เชิงกลยุทธ์ + เชิงยุทธวิธี เพื่อสร้างซอฟต์แวร์ที่ให้คุณค่าสูงและเข้าใจธุรกิจจริง
- การไม่ออกแบบ (“task-board shuffle”) ทำให้ธุรกิจจ่ายราคาแพง — design เป็นสิ่งที่หลีกเลี่ยงไม่ได้ เป้าหมายคือ effective design ที่ทำให้แตกต่างจากคู่แข่ง
- Strategic มาก่อน: Bounded ContextBounded Contextขอบเขตที่ชัดเจน (มักเป็นระบบย่อยหรือทีมหนึ่ง) ที่ model หนึ่งใช้ได้และมีความหมายแน่นอน ภายในขอบเขตนี้ Ubiquitous Language สอดคล้องกัน 100%Strategic Design + Ubiquitous LanguageUbiquitous Languageภาษากลางที่ทุกคนในทีม (ทั้งนักพัฒนาและผู้เชี่ยวชาญธุรกิจ) ใช้ร่วมกัน อิงกับ domain model โดยตรง คำเดียวกันต้องหมายถึงสิ่งเดียวกัน และสะท้อนลงใน codeStrategic Design → SubdomainSubdomainส่วนย่อยของ Domain ใหญ่ เช่น Domain e-commerce แตกเป็น subdomain การสั่งซื้อ การชำระเงิน คลังสินค้า ฯลฯ อยู่ใน “พื้นที่ปัญหา” (problem space)Strategic Design/Core DomainCore Domainsubdomain ที่สำคัญและสร้างความได้เปรียบในการแข่งขันมากที่สุด เป็นเหตุผลที่เราต้องสร้างซอฟต์แวร์เองแทนการซื้อ ควรทุ่มทีมเก่งที่สุดลงตรงนี้Strategic Design → Context MappingContext Mappingกิจกรรมการระบุ Bounded Context และนิยามความสัมพันธ์ระหว่างกัน (เช่น Partnership, Shared Kernel, ACL) เพื่อจัดการการเชื่อมต่อระหว่างทีม/ระบบStrategic Design
- Tactical ตามมา: AggregateAggregate RootEntity หนึ่งตัวที่เป็น “ประตูเดียว” เข้าสู่ Aggregate การอ้างอิงจากภายนอกทำได้กับ root เท่านั้น root จึงควบคุมกฎความถูกต้องของทั้งกลุ่มTactical Design + Domain EventDomain Eventสิ่งที่ “เกิดขึ้นแล้ว” ใน domain ซึ่งส่วนอื่นสนใจ แทนด้วยอ็อบเจ็กต์ที่เปลี่ยนแปลงไม่ได้ ตั้งชื่อเป็นอดีต เช่น CargoWasRouted ใช้สื่อสารข้าม AggregateTactical Design
- แก่นแท้คือ วิธีคิดและการกลั่นความรู้ ร่วมกับธุรกิจอย่างต่อเนื่องและให้เร็วที่สุด
เจาะลึกแนวคิดในบทนี้ต่อได้ที่คลังอ้างอิง DevIQ:
- Bounded Context — ขยายความ pattern เชิงกลยุทธ์ตัวแรกที่บทนี้แนะนำ คือขอบเขตที่ model หนึ่งใช้ได้และมีความหมายแน่นอน
- Ubiquitous Language — ภาษากลางที่ต้องพัฒนาร่วมกับ Domain Expert ภายใน Bounded Context แต่ละแห่ง
- Context Mapping — เทคนิคเชื่อมต่อหลาย Bounded Context เข้าด้วยกันที่บทนี้กล่าวถึงในช่วง strategic design
- Aggregate — pattern เชิงยุทธวิธีที่รวม Entity และ Value Object เข้าเป็นกลุ่มขนาดพอเหมาะ ตามที่บทนี้แนะนำไว้ในช่วง tactical design
- Domain Events — กลไกสื่อสาร “สิ่งที่เกิดขึ้นแล้ว” ข้าม Bounded Context ที่บทนี้ยกตัวอย่างไว้
เช็กความเข้าใจ — บทที่ 1
ข้อ 1 / 4ตามหนังสือ DDD “ซับซ้อนโดยจำเป็น” หรือไม่?