โฟกัสที่ Core Domain
ไม่ใช่ทุกส่วนของปัญหาจะ “สำคัญเท่ากัน” บางส่วนของ application มีค่ามากกว่าส่วนอื่น และต้องการความใส่ใจรวมถึงการลงทุนมากกว่าเพื่อทำให้ระบบประสบความสำเร็จ ระหว่างที่เราทำ Knowledge CrunchingKnowledge Crunchingการบดเคี้ยวความรู้ — ศิลปะการกลั่นข้อมูลที่เกี่ยวข้องออกจาก problem domain ร่วมกับ domain expert เพื่อสร้าง model ที่มีประโยชน์ต่อ business use caseProcess ร่วมกับ domain expert หน้าที่สำคัญคือ ลดเสียงรบกวนของสิ่งที่ไม่สำคัญ เพื่อให้เราโฟกัสกับสิ่งที่สำคัญจริงๆ ได้
Model-Driven DesignDomain ModelModel ของ Domain ที่ฝังกฎและกระบวนการทางธุรกิจไว้ใน code จริง หัวใจของ DDD คือการพัฒนา domain model ที่ “เข้าใจธุรกิจอย่างลึกซึ้ง”Strategic Design เป็นงานที่ยากและแพง จึงควรสงวนไว้สำหรับพื้นที่ที่ “เป็นหรือตาย” ต่อความสำเร็จของระบบเท่านั้น บทนี้จะสอนวิธี เปิดเผยพื้นที่ที่สำคัญที่สุด ของระบบผ่านการ กลั่น (distillation)Distillationการกลั่น — กระบวนการแยกย่อย problem domain ก้อนใหญ่ออกเป็น subdomain เพื่อเผยว่าส่วนไหนคือ core, supporting, generic ช่วยลดความซับซ้อนใน problem space และบอกว่าควรลงแรงตรงไหนStrategic Design เพื่อให้รู้ว่าควรลงแรงตรงไหน — แล้วทุ่ม model ที่ลึกซึ้งที่สุดลงไปกับสิ่งที่เป็น Core DomainCore Domainsubdomain ที่สำคัญและสร้างความได้เปรียบในการแข่งขันมากที่สุด เป็นเหตุผลที่เราต้องสร้างซอฟต์แวร์เองแทนการซื้อ ควรทุ่มทีมเก่งที่สุดลงตรงนี้Strategic Design
ทำไมต้องแยกย่อย problem domain
หัวข้อที่มีชื่อว่า “ทำไมต้องแยกย่อย problem domain”ระบบขนาดใหญ่ที่สร้างเพื่อ problem domain ที่ซับซ้อน ย่อมประกอบด้วย component และระบบย่อยหลายชิ้น ทุกชิ้นจำเป็นต่อการทำงานของระบบโดยรวม — แต่ไม่ใช่ทุกชิ้นจะมีค่าเท่ากัน
เราไม่สามารถ (และไม่จำเป็นต้อง) กระจายแรงและคุณภาพให้เท่าๆ กันทั่วทั้งระบบ การพยายามทำให้ทุกอย่างเท่าเทียมกลับทำให้ เสียโฟกัส จากพื้นที่ที่ต้องทำให้ถูกจริงๆ ทางออกคือกลั่น problem domain ออกมาเพื่อเผยให้เห็นว่าอะไรคือแก่น เมื่อแยกปัญหาก้อนใหญ่ออกเป็นชิ้นเล็กลง เราก็จัดสรรทรัพยากรได้ดีขึ้น — ส่ง developer เก่งที่สุดไปอยู่ในพื้นที่ที่สำคัญที่สุดต่อธุรกิจ ไม่ใช่พื้นที่ที่แค่ “ท้าทายทางเทคนิค” หรือได้เล่น framework ใหม่
ฟังดูสมเหตุสมผลที่จะใช้ model เดียวอธิบายทั้ง problem domain แต่ model นั้นจะต้องตอบทุกความต้องการ จนสุดท้ายมันจะ ซับซ้อนเกินไป หรือไม่ก็ กว้างเสียจนไม่สะท้อนกระบวนการธุรกิจ (business process) อะไรชัดเจน จำไว้ว่า DDD คือการ “ลด” ความซับซ้อน — model ก้อนเดียวขนาดมหึมา มีแต่จะเพิ่มความซับซ้อน ทางที่ดีกว่าคือแตก problem space ออกเป็น model เล็กๆ ที่โฟกัสและผูกกับ context ที่ชัดเจน
จับ “แก่น” ของปัญหาให้ได้
หัวข้อที่มีชื่อว่า “จับ “แก่น” ของปัญหาให้ได้”จะรู้ว่าควรลงแรงตรงไหน เราต้องเข้าใจก่อนว่า อะไรทำให้ app นี้ควรค่าแก่การออกแบบตั้งแต่แรก เราต้องเข้าใจกลยุทธ์ธุรกิจ และเข้าใจว่าทำไมการมีอยู่ของซอฟต์แวร์นี้จึงทำให้กลยุทธ์นั้นเป็นจริงได้ คำถามที่ควรถามคือ:
- ทำไมเราถึงเขียนซอฟต์แวร์เองแทนการซื้อของสำเร็จรูป (off-the-shelf)?
- ระบบนี้จะสร้างความแตกต่างให้ธุรกิจอย่างไร และเข้ากับกลยุทธ์บริษัทตรงไหน?
- ทำไมต้องทำในบ้าน (in-house) แทนการ outsource?
- ส่วนไหนของซอฟต์แวร์ที่ให้ ความได้เปรียบในการแข่งขัน กับธุรกิจ?
มองให้ไกลกว่า requirement
หัวข้อที่มีชื่อว่า “มองให้ไกลกว่า requirement”ระวังเมื่อ business user ขอ “เพิ่ม feature” ให้ระบบเดิม เพราะบ่อยครั้งสิ่งที่เขาขอตั้งอยู่บน ข้อจำกัดของระบบปัจจุบัน ไม่ใช่สิ่งที่เขาต้องการจริงๆ ลองถามตัวเองว่าเราเข้าใจ “ทำไม” ที่อยู่เบื้องหลัง “อะไร” บ่อยแค่ไหน เมื่อเราเข้าใจความต้องการที่แท้จริง เรามักเสนอทางแก้ที่ดีกว่าได้ — และลูกค้ามักประหลาดใจ ตามด้วยประโยคคลาสสิก: “ระบบทำแบบนั้นได้ด้วยหรือ?”
คุณคือ “ผู้ทำให้เป็นไปได้” (the enabler) ไม่ใช่คนที่เดินตาม requirement ของ user อย่างไร้การไตร่ตรอง
ลูกค้าธุรกิจอาจขอว่า “เพิ่มช่องค้นหาสินค้าให้ตรงกับฐานข้อมูลเดิม” แต่สิ่งที่เขาต้องการจริงๆ คือ “อยากให้ลูกค้าค้นเจอสินค้าที่อยากซื้อได้เร็วขึ้นเพื่อเพิ่มยอดขาย” เมื่อเข้าใจ “ทำไม” เราอาจเสนอ recommendation engine หรือการจัด ranking — ซึ่งอาจเป็น Core Domain ที่แท้จริง แทนที่จะเป็นแค่ search box ธรรมดา
บันทึก Domain Vision Statement
หัวข้อที่มีชื่อว่า “บันทึก Domain Vision Statement”ก่อนเริ่มงานใดๆ ให้ขอ “ภาพรวม project” เสมอ ในองค์กรใหญ่ กระบวนการริเริ่ม project มักเกิดก่อนทีม dev จะเข้ามาเกี่ยวข้องเสียอีก มักจะมี เอกสารสั้นๆ ที่อธิบายว่าทำไมบริษัทถึงเลือกสร้างซอฟต์แวร์ตัวนี้แทนตัวอื่น — เอกสารนี้มักซ่อน “กุญแจสู่ core domain” เอาไว้
Domain Vision StatementDomain Vision Statementคำแถลงวิสัยทัศน์ของ domain — ข้อความสั้น ๆ ที่จับใจความว่าอะไรคือหัวใจของความสำเร็จของซอฟต์แวร์ เป้าหมายธุรกิจคืออะไร และคุณค่าอยู่ตรงไหน ใช้สร้างความเข้าใจร่วมกันในทีมว่าอะไรคือ coreStrategic Design คือคำแถลงสั้นๆ ที่จับใจความว่า อะไรคือหัวใจของความสำเร็จ เป้าหมายธุรกิจคืออะไร และคุณค่าอยู่ตรงไหน เขียนมันออกมาให้ชัด share กับทีม กระทั่งแปะไว้บนผนังออฟฟิศ เพื่อเตือนทุกคนว่าเรากำลังเขียนซอฟต์แวร์นี้ไปเพื่ออะไร
Amazon มีวิธีสร้าง domain vision ที่เรียกว่า working backwards — สำหรับ feature ใหม่ product manager จะเขียน “ข่าวประชาสัมพันธ์ภายใน” (internal press release) ประกาศผลิตภัณฑ์ที่เสร็จแล้ว พร้อมระบุประโยชน์ที่ลูกค้าจะได้ ถ้าลูกค้าเป้าหมายไม่รู้สึกว่ามันน่าตื่นเต้นหรือคุ้มค่า PM ก็จะ refactor press release นั้นจนกว่า feature จะให้คุณค่าจริง — โฟกัสที่ลูกค้าตั้งแต่ก่อนเริ่มเขียน code
วิธีโฟกัสที่ปัญหาแก่น
หัวข้อที่มีชื่อว่า “วิธีโฟกัสที่ปัญหาแก่น”problem domain ก้อนใหญ่ถูกแบ่งออกเป็น SubdomainSubdomainส่วนย่อยของ Domain ใหญ่ เช่น Domain e-commerce แตกเป็น subdomain การสั่งซื้อ การชำระเงิน คลังสินค้า ฯลฯ อยู่ใน “พื้นที่ปัญหา” (problem space)Strategic Design เพื่อจัดการความซับซ้อนและแยกส่วนสำคัญออกจากส่วนที่เหลือ Millett เปรียบเทียบไว้สวยงาม: เหมือนการชำแหละหมูในร้านขายเนื้อ — หมูทั้งตัวถูกแบ่งออกเป็น “ชิ้นส่วน” ต่างๆ (สันใน สันนอก สะโพก ขาหมู) เช่นเดียวกับการแบ่ง problem space

subdomain เป็น แนวคิดเชิงนามธรรม อย่าสับสนกับผังโครงสร้างองค์กร (แผนก/ทีม) ของบริษัท subdomain แทน พื้นที่ของความสามารถ (areas of capability) ที่นิยามกระบวนการธุรกิจ (business process) และความสามารถเชิง function ของระบบ
อย่าเอาเรื่องเทคนิคเข้ามาปนตอนวิเคราะห์ problem space — Security, audit trail, logging ล้วนเป็น เรื่อง infrastructure (เว้นแต่ problem space ของคุณคือ security เอง) ให้โฟกัสที่ domain เป็นอันดับแรก
เมื่อกลั่น problem domain เราจะ “แบ่งแล้วพิชิต” (divide and conquer) ความซับซ้อนได้ subdomain หลายตัวจะ generic กับธุรกิจองค์กรทั่วไป (เช่น ระบบรายงาน การแจ้งเตือน) เราเรียกว่า generic domainGeneric Subdomainปัญหาที่แก้กันมาแล้วทั่วไป เช่น ระบบ login บัญชี การแจ้งเตือน — ควรใช้ของสำเร็จรูปหรือ library แทนการเขียนเองStrategic Design ส่วนพื้นที่ที่ทำให้สินค้าของบริษัทคุณ แตกต่างจากคู่แข่ง และสร้างความได้เปรียบ คือ Core DomainCore Domainsubdomain ที่สำคัญและสร้างความได้เปรียบในการแข่งขันมากที่สุด เป็นเหตุผลที่เราต้องสร้างซอฟต์แวร์เองแทนการซื้อ ควรทุ่มทีมเก่งที่สุดลงตรงนี้Strategic Design — เหตุผลที่คุณต้องเขียนซอฟต์แวร์นี้เอง ที่เหลือคือ supporting domainSupporting Subdomainส่วนที่จำเป็นและเฉพาะกับธุรกิจเรา แต่ไม่ใช่จุดที่สร้างความได้เปรียบ ไม่มีของสำเร็จรูปที่พอดี จึงต้องทำเอง แต่ลงทุนน้อยกว่า coreStrategic Design ซึ่งเป็นตัวสนับสนุน core
ตัวอย่าง: กลั่น problem domain ของเว็บประมูล
หัวข้อที่มีชื่อว่า “ตัวอย่าง: กลั่น problem domain ของเว็บประมูล”ลองดู domain ของเว็บประมูลออนไลน์ มันคือ problem domain ก้อนใหญ่ก้อนหนึ่งที่ยังไม่ถูกแยกย่อย

หลังการ knowledge crunching เราแบ่งมันออกเป็น subdomain ได้ดังนี้: Membership (สมัครสมาชิก ความชอบ ข้อมูลสมาชิก), Seller (กิจกรรมของผู้ขาย), Auction (จัดการเวลาประมูลและการประมูลแข่งราคา), Listing (catalog สินค้าที่เปิดประมูล) และ Dispute Resolution (จัดการข้อพิพาทระหว่างสมาชิกกับผู้ขาย)

ขั้นต่อไปคือจัดประเภท subdomain เป็น core / supporting / generic ตามคุณค่าที่มีต่อธุรกิจ

- Seller และ Auction = Core Domain — Seller มีตรรกะการคิดเรตติ้งและค่าธรรมเนียมผู้ขาย ส่วน Auction คือกลไกการประมูลและจัดการการแข่งราคา ทั้งคู่คือหัวใจของความสำเร็จ
- Membership และ Listing = Supporting — ช่วยให้ผู้ประมูลสร้างบัญชีและหาสินค้าเจอ แต่ไม่ได้นิยามว่าธุรกิจนี้คืออะไร
- Dispute Resolution = Generic — เป็นแค่ระบบ ticket จัดการเคสข้อพิพาท หาซื้อ off-the-shelf มาใช้ได้
Core Domain — หัวใจที่ต้องลงทุน
หัวข้อที่มีชื่อว่า “Core Domain — หัวใจที่ต้องลงทุน”จะรู้ว่าอะไรคือ core ลองถามตัวเองว่า: ส่วนไหนของผลิตภัณฑ์ที่จะทำให้มันสำเร็จ? ทำไมส่วนเหล่านั้นถึงสำคัญ? และทำไมถึง ซื้อสำเร็จรูปมาใช้ไม่ได้? พูดอีกอย่างคือ — อะไรทำให้ระบบนี้ “ควรค่าแก่การสร้าง”
Core Domain แทน ความได้เปรียบในการแข่งขันพื้นฐาน ที่บริษัทจะได้จากการส่งมอบซอฟต์แวร์นี้ และมันไม่ได้ชัดเจนเสมอไป ถ้า generic domain ควร “ซื้อเข้ามาและพัฒนาให้น้อยที่สุด” core domain ก็คือขั้วตรงข้าม — มันต้องการ developer ที่เก่งที่สุดของคุณ (Millett เรียกพวกเขาว่า “คอมมานโด”) Core Domain อาจไม่ใช่ส่วนที่ใหญ่ที่สุดในแง่ปริมาณเทคโนโลยี แต่ต้องการการลงทุนมากที่สุด
Pottermore.com เป็นที่เดียวบนเว็บที่ขายหนังสือ Harry Potter แบบดิจิทัล หน้าตาก็เหมือนเว็บ e-commerce ทั่วไป — เลือกสินค้า ใส่ตะกร้า จ่ายเงิน แต่ core domain คือสิ่งที่ลูกค้ามองไม่เห็น: หนังสือไม่ได้ล็อกด้วย DRM แต่ฝัง ลายน้ำที่มองไม่เห็น (invisible watermark) ไว้ เพื่อให้ติดตามได้หากมีคนนำไปเผยแพร่อย่างผิดกฎหมายบนเว็บ เทคโนโลยีลายน้ำนี่แหละคือสิ่งที่ทำให้ธุรกิจต่างจากคนขาย e-book รายอื่น และเป็นเหตุผลที่ต้องสร้างเองแทนการไปขายผ่าน iTunes
Core Domain เปลี่ยนไปตามกาลเวลา ถ้าคุณสำเร็จ คู่แข่งก็จะเลียนแบบ Core Domain จึงต้อง วิวัฒน์ (evolve) ต่อไปเพื่อให้ธุรกิจนำหน้าอยู่เสมอ ทีม dev ต้องเข้าใจข้อนี้ และทำให้ code สอดคล้องกับคุณค่าที่เปลี่ยนไปของธุรกิจ
มองมันเป็น “ผลิตภัณฑ์” ไม่ใช่ “project”
หัวข้อที่มีชื่อว่า “มองมันเป็น “ผลิตภัณฑ์” ไม่ใช่ “project””หนึ่งในการเปลี่ยน mindset ที่สำคัญที่สุดคือ มอง core domain เป็น product ไม่ใช่ project ที่จบแล้วจบเลย ซอฟต์แวร์สำหรับ business product แทบไม่เคย “เสร็จ” — มันจะมีชีวิตผ่านช่วงเวลาของการเพิ่ม feature เรื่อยๆ จนกว่ามันจะไม่ให้คุณค่าอีกต่อไป คุยกับ business sponsor เรื่องอนาคตของผลิตภัณฑ์ เพื่อโฟกัสความพยายามในการเขียน code ให้ถูกจุด
บ่อยครั้งซอฟต์แวร์ core domain ไม่ถูกมองเป็น product ที่ต้องดูแล แต่ถูกบีบให้ แลกคุณภาพกับความเร็วในการออกสู่ตลาด (time to market) โดยเน้นที่เดดไลน์มากกว่าการลงทุนระยะยาว ผลคือ codebase ที่ดูแลยากและกลายเป็น Big Ball of MudBig Ball of Mudระบบที่ปนเปกันยุ่งเหยิงไม่มีขอบเขตชัด ให้ลากเส้นล้อมไว้แล้วยอมรับสภาพ ไม่พยายามทำ model ละเอียดในนั้น และระวังไม่ให้ลามไป context อื่นStrategic Design (BBoM) ในที่สุด
ทางออกเมื่อเดดไลน์ขยับไม่ได้คือ ตัดขอบเขต feature (descope) เพื่อรักษาคุณภาพไว้ ไม่ใช่ลดคุณภาพ — แต่จะทำเช่นนี้ได้ คุณต้องมี vision ร่วมกันทั้งทีม เพื่อรู้ว่า feature ไหน “สำคัญที่สุด” จริงๆ
Generic และ Supporting Domain
หัวข้อที่มีชื่อว่า “Generic และ Supporting Domain”Generic domainGeneric Subdomainปัญหาที่แก้กันมาแล้วทั่วไป เช่น ระบบ login บัญชี การแจ้งเตือน — ควรใช้ของสำเร็จรูปหรือ library แทนการเขียนเองStrategic Design คือ subdomain ที่ระบบธุรกิจขนาดใหญ่ส่วนมากมีเหมือนๆ กัน เช่น บริการส่งอีเมล package บัญชี ชุดรายงาน — ไม่ใช่ core แต่ธุรกิจก็ขาดมันไม่ได้ เพราะไม่ได้ให้ความได้เปรียบ จึงไม่สมเหตุสมผลที่จะทุ่มแรงสร้างเอง ควร ซื้อเข้ามา หรือมอบหมายให้ junior developer ทำ เพื่อปลดปล่อยคนเก่งที่สุดไปทุ่มกับงาน core
อีเมลคือ generic domain สำหรับเว็บประมูลทั่วไป — แต่สำหรับ Groupon หรือ Wowcher ที่ธุรกิจถูกนิยามด้วยการส่งอีเมลโปรโมชันแบบจำกัดเวลา ระบบ email/CRM ที่ซับซ้อนกลับเป็น core domain ของพวกเขา จงตัดสินจากคุณค่าต่อธุรกิจ “ของคุณ” เสมอ
Supporting domainSupporting Subdomainส่วนที่จำเป็นและเฉพาะกับธุรกิจเรา แต่ไม่ใช่จุดที่สร้างความได้เปรียบ ไม่มีของสำเร็จรูปที่พอดี จึงต้องทำเอง แต่ลงทุนน้อยกว่า coreStrategic Design คือ subdomain ที่เหลือ ไม่ได้นิยามว่าระบบทำอะไร แต่ช่วย “ค้ำ” core เช่น function เลือกดู catalog สินค้าของ Amazon — ไม่ได้นิยามว่า Amazon เป็นบริษัทอะไร และก็ไม่ต่างจากเว็บ e-commerce รายอื่น แต่มันช่วยติดตาม user journey ไปป้อน recommendation engine เช่นเดียวกับ generic domain ถ้าทำได้ก็ควรซื้อสำเร็จรูป หรือไม่เช่นนั้นก็ไม่ควรลงทุนหนัก — บางครั้ง กระบวนการแบบ manual ก็ตอบโจทย์ได้ โดยไม่ต้องเขียน code ด้วยซ้ำ
subdomain กำหนดรูปร่างของ solution อย่างไร
หัวข้อที่มีชื่อว่า “subdomain กำหนดรูปร่างของ solution อย่างไร”ภายในแต่ละ subdomain เราสร้าง model ขึ้นมาหนึ่งตัว และ solution ก็ map ตาม subdomain เหล่านั้น ในเว็บประมูล ระบบถูกแบ่งเป็น2 app จริง: core กับ supporting domain สร้างเป็นเว็บ app ที่เขียนเอง (bespoke) ส่วน dispute domain ใช้ package สำเร็จรูป

ไม่ใช่ทุกส่วนของระบบที่ต้องออกแบบให้ดี
หัวข้อที่มีชื่อว่า “ไม่ใช่ทุกส่วนของระบบที่ต้องออกแบบให้ดี”ภายในแต่ละ subdomain จะมี model ที่แทนตรรกะและกฎธุรกิจของพื้นที่นั้น — แต่ model ทุกตัวไม่จำเป็นต้องมีคุณภาพเท่ากัน เมื่อเข้าใจ subdomain ต่างๆ แล้ว เราจัดสรรแรงให้เหมาะสมได้ และนำ model-driven design patterns ของ DDD ไปใช้เฉพาะพื้นที่ที่ได้ประโยชน์มากที่สุด
อย่าเสียเวลา refactor code ทั้งหมด — แรงโฟกัสหลักต้องอยู่ที่ core domain ถ้าได้ code ที่ “ทำงานได้แต่ไม่เนี้ยบ” ในส่วน supporting/generic ก็ปล่อยมันไว้ Good is good enough (ดีพอก็เพียงพอแล้ว) ความสมบูรณ์แบบเป็นภาพลวงตา และควรสงวนไว้สำหรับสิ่งที่เป็น core เท่านั้น
ปล่อยให้มี BBoM ก้อนเล็กๆ อยู่ได้ ตราบใดที่มันถูกล้อมด้วยขอบเขตที่ชัดเจน ธุรกิจไม่ได้สนใจคุณภาพ code ของพื้นที่ที่จำเป็นแต่ไม่ใช่กุญแจของระบบ
โฟกัสที่ขอบเขตสะอาด มากกว่า model ที่สมบูรณ์แบบ
หัวข้อที่มีชื่อว่า “โฟกัสที่ขอบเขตสะอาด มากกว่า model ที่สมบูรณ์แบบ”ในระบบใหญ่ที่วิวัฒน์มานาน ย่อมมีพื้นที่ที่ไม่สมบูรณ์แบบ ถ้ามีส่วนที่หน้าตาเหมือน BBoM สิ่งที่ดีที่สุดคือ ขีดเส้นล้อมมันไว้ เพื่อกัน “โคลน” (mud) ไม่ให้ลามไปยังพื้นที่ใหม่ ใช้ Anticorruption LayerAnticorruption Layer (ACL)ชั้นกั้นที่ทีมปลายน้ำสร้างขึ้นเพื่อแปลง model ของระบบอื่นให้เป็นภาษาของ model ตัวเอง ป้องกันไม่ให้ model ภายนอกมา “ปนเปื้อน” model เราStrategic Design (ACL) ห่อการสื่อสารกับ code legacy หรือ code ของบุคคลที่สาม เพื่อรักษาความถูกต้องของ Bounded ContextBounded Contextขอบเขตที่ชัดเจน (มักเป็นระบบย่อยหรือทีมหนึ่ง) ที่ model หนึ่งใช้ได้และมีความหมายแน่นอน ภายในขอบเขตนี้ Ubiquitous Language สอดคล้องกัน 100%Strategic Design ใหม่ไว้ ป้องกัน model หนึ่งไม่ให้ปนเปื้อนอีก model (เราจะลงลึกเรื่อง ACL ในบท Context Mapping)

ในระบบ Cargo Shipping ของเรา core domain คือการวางแผนเส้นทางและการจองการขนส่ง (Route SpecificationRoute SpecificationValue Object ที่ระบุ “ความต้องการของลูกค้า”: ต้นทาง ปลายทาง และกำหนดเวลาถึง — มี method isSatisfiedBy() ตรวจว่าแผนเดินทางตรงตามนี้หรือไม่Tactical Design, ItineraryItineraryValue Object ที่เป็น “แผนการเดินทางจริง” ของ Cargo ประกอบด้วยลำดับของ Leg (ช่วงการขนส่งแต่ละช่วง)Tactical Design) — นี่คือจุดที่กฎธุรกิจซับซ้อนและสร้างความได้เปรียบ จึงควรทุ่ม model ที่ลึกที่สุดลงไป
ส่วนการออกใบแจ้งหนี้ (billing), การส่งอีเมลยืนยัน, หรือระบบ login ของพนักงาน เป็น generic / supporting domain — ซื้อสำเร็จรูปหรือมอบหมายให้ junior ทำ และล้อมระบบ tracking เก่าที่เป็น legacy ไว้ด้วย ACL เพื่อไม่ให้มันลามมาบั่นทอนคุณภาพของ core
core domain ไม่จำเป็นต้องสมบูรณ์ตั้งแต่ครั้งแรก
หัวข้อที่มีชื่อว่า “core domain ไม่จำเป็นต้องสมบูรณ์ตั้งแต่ครั้งแรก”ในโลกอุดมคติ คุณภาพควรมาเป็นอันดับหนึ่งเสมอ — แต่ต้อง practical ด้วย บางครั้ง core domain ของระบบใหม่ต้องชิงออกตลาดก่อนใคร หรือบางครั้งธุรกิจยังไม่แน่ใจว่าไอเดียจะสำเร็จและกลายเป็น core หรือไม่ ในกรณีนี้ธุรกิจอยาก เรียนรู้เร็วและล้มเร็ว (fail fast) โดยไม่ลงแรง up-front มาก version แรกอาจไม่ประณีต — ซึ่งก็ยอมรับได้ แต่ ถ้ามันสำเร็จและคุ้มที่จะลงทุนต่อ คุณต้อง refactor เพื่อรองรับการวิวัฒน์ มิฉะนั้น technical debt ที่สะสมจากการเร่งส่งจะกลายเป็นปัญหาในภายหลัง
สร้าง subdomain เพื่อ “แทนที่” ไม่ใช่เพื่อ “ใช้ซ้ำ”
หัวข้อที่มีชื่อว่า “สร้าง subdomain เพื่อ “แทนที่” ไม่ใช่เพื่อ “ใช้ซ้ำ””เมื่อพัฒนา model ใน supporting subdomain ให้สร้างมันแบบแยกเดี่ยวๆ โดยคิดเรื่อง การแทนที่ ไว้ในใจ กั้นมันจาก model อื่น code legacy และบริการภายนอกด้วยขอบเขตที่สะอาด การออกแบบเพื่อ “แทนที่ได้” (designed for replacement) แทน “ใช้ซ้ำ” (reuse) ทำให้ได้ supporting subdomain ที่ดีพอโดยไม่ต้องเสียแรงทำให้สมบูรณ์แบบ — วันข้างหน้าจะเปลี่ยนไปใช้ของสำเร็จรูปหรือเขียนขึ้นใหม่ก็ทำได้ง่าย
ถ้าไม่มี Core Domain เลยล่ะ?
หัวข้อที่มีชื่อว่า “ถ้าไม่มี Core Domain เลยล่ะ?”ธุรกิจสร้างซอฟต์แวร์เองด้วยหลายเหตุผล — ถ้าทำได้ถูกกว่า เร็วกว่า หรือฉลาดกว่า ก็เป็นตัวเลือกที่ดีในการสร้างเอง แต่ถ้าพบว่าสิ่งที่กำลังสร้างเป็น generic ทั้งหมด หรือเป็นแค่ตัว support app อื่นในองค์กร — แปลว่าคุณ ไม่มี core domain ในกรณีนี้ อย่าพยายามยัด practices และ principles ทั้งหมดของ DDD ลงไป
คุณยังได้ประโยชน์จาก strategic patterns ของ DDD อยู่ แต่ tactical patterns ของ model-driven design อาจเป็นการเสียแรงเปล่า (เราจะพูดถึงเมื่อไรควร/ไม่ควรใช้ tactical patterns ในบทหลัง)
ใช้ Distillation แตก problem domain ก้อนใหญ่ออกเป็น Core / Supporting / Generic เพื่อลดความซับซ้อนและรู้ชัดว่าควรลงแรงตรงไหน — ทุ่ม developer เก่งที่สุดไว้ที่ Core Domain เพราะมันคือเหตุผลที่คุณต้องเขียนซอฟต์แวร์นี้ขึ้นมาเอง ส่วน supporting/generic ให้ซื้อ outsource หรือมอบหมายให้ junior ทำ และจำไว้เสมอว่า ไม่ใช่ทุกส่วนต้องออกแบบให้ดีเท่ากัน — ความสมบูรณ์แบบมีไว้สงวนให้ core เท่านั้น ส่วน legacy ที่รกรุงรัง ให้ล้อมด้วยขอบเขตที่ชัดเจนและ ACL
เจาะลึกแนวคิดในบทนี้ต่อได้ที่คลังอ้างอิง DevIQ:
- Domain (Subdomain vs Core Domain) — นิยามพื้นฐานของ domain และการจัดประเภท core/supporting/generic ที่บทนี้ใช้ตลอด
- Subdomain — หลักการแบ่ง problem domain ก้อนใหญ่ออกเป็นพื้นที่ความสามารถย่อยๆ ตามที่บทนี้อธิบายด้วยตัวอย่างเว็บประมูล
- Strategic Design — ภาพรวมของการกลั่น (distillation) และวางกลยุทธ์ระดับ domain ก่อนลงมือทำ tactical patterns
- Anti-Corruption Layer — เทคนิคขีดขอบเขตกัน legacy Big Ball of Mud ไม่ให้ปนเปื้อน model ใหม่ ที่กล่าวถึงถึงในหัวข้อ “โฟกัสที่ขอบเขตสะอาด”
เช็กความเข้าใจ — บทที่ 3
ข้อ 1 / 4ทำไม DDD ถึงแนะนำให้กลั่น (distill) problem domain ก้อนใหญ่ออกเป็น subdomain?