รักษาความบริสุทธิ์ของ Model ด้วย Bounded Context
ใน app ขนาดใหญ่และซับซ้อน คุณจะพบว่ามี modelModelระบบของแนวคิดที่อธิบายแง่มุมสำคัญของ Domain เพื่อใช้แก้ปัญหา ไม่ใช่ภาพสะท้อนความจริงทั้งหมด แต่เป็น “การตีความที่มีประโยชน์” ของความจริงStrategic Design หลายตัวทำงานอยู่พร้อมกัน แต่ละตัวถูกสร้างเพื่อแทนพื้นที่หนึ่งของ problem domain โดยเฉพาะ ในอุดมคติเราอยากให้มี1 model ต่อหนึ่ง SubdomainSubdomainส่วนย่อยของ Domain ใหญ่ เช่น Domain e-commerce แตกเป็น subdomain การสั่งซื้อ การชำระเงิน คลังสินค้า ฯลฯ อยู่ใน “พื้นที่ปัญหา” (problem space)Strategic Design แต่ในความเป็นจริงไม่เป็นเช่นนั้นเสมอไป — บาง subdomain ที่ซับซ้อนอาจมีหลาย model และบาง model ก็คร่อมหลาย subdomain
ไม่ว่าจะมีกี่ model สุดท้ายแล้วทั้งหมดต้องสื่อสารกันเพื่อทำให้ระบบทำงานสำเร็จ และจุดที่อันตรายที่สุดคือเมื่อทีม นำ model มารวมกันโดยไม่เข้าใจว่าแต่ละตัวใช้ได้ในบริบทไหน แนวคิดและตรรกะจึงปนเปื้อนกัน ทำให้ model เริ่มพร่าเลือนและสูญเสียความชัดเจน บทนี้จะพาไปรู้จักเครื่องมือที่ DDD ใช้ปกป้องความบริสุทธิ์ของแต่ละ model นั่นคือ Bounded ContextBounded Contextขอบเขตที่ชัดเจน (มักเป็นระบบย่อยหรือทีมหนึ่ง) ที่ model หนึ่งใช้ได้และมีความหมายแน่นอน ภายในขอบเขตนี้ Ubiquitous Language สอดคล้องกัน 100%Strategic Design
ปัญหาของการมี model เดียวทั้งระบบ
หัวข้อที่มีชื่อว่า “ปัญหาของการมี model เดียวทั้งระบบ”แก่นของ DDD คือการสร้าง model ใน code ที่ ชัดเจนและวิวัฒน์ได้ สอดคล้องกับ model ความคิดที่ทีมเข้าใจร่วมกัน เมื่อได้ insight ใหม่จาก domain ก็ผนวกเข้าไปได้อย่างมีประสิทธิภาพ แต่ถ้าเราฝืนใช้ model เดียวสำหรับทั้งระบบ แนวคิดจากพื้นที่หนึ่งจะถูกสับสนกับแนวคิดชื่อคล้ายๆ กันจากอีกพื้นที่ และยังผูกติดกันจนแกะไม่ออก DDD จึงสนับสนุนให้ แตกระบบใหญ่ที่ซับซ้อนออกเป็นหลาย code model
model โตขึ้นจนซับซ้อน
หัวข้อที่มีชื่อว่า “model โตขึ้นจนซับซ้อน”ทุกครั้งที่เพิ่ม use case หรือ insight ใหม่เข้าไป จำนวนแนวคิดและการพึ่งพา (dependency) ภายใน model ก็เพิ่มขึ้น ความซับซ้อนพุ่งสูงขึ้น จัดวางแนวคิดผิดที่ได้ง่าย และค้นหาสิ่งที่ต้องการก็ยากขึ้น ยิ่งระบบโต ปัญหายิ่งรุนแรง ความเร็วในการเพิ่ม feature ใหม่ก็ช้าลงเรื่อยๆ — นี่คือเส้นทางตรงสู่ Big Ball of MudBig Ball of Mudระบบที่ปนเปกันยุ่งเหยิงไม่มีขอบเขตชัด ให้ลากเส้นล้อมไว้แล้วยอมรับสภาพ ไม่พยายามทำ model ละเอียดในนั้น และระวังไม่ให้ลามไป context อื่นStrategic Design
หลายทีมแย่งกันแก้ model ก้อนเดียว
หัวข้อที่มีชื่อว่า “หลายทีมแย่งกันแก้ model ก้อนเดียว”code ที่ซับซ้อนเป็นเพียงปัญหาเดียว อีกปัญหาใหญ่คือ ต้นทุนการประสานงาน (collaboration overhead) เมื่อทีมหนึ่งจะปล่อย feature ต้องไปเช็กกับทีมอื่นว่า deploy ได้ไหม ทีมแรกต้องรอ หรือไม่ก็ต้องใช้กลยุทธ์ branching ที่ซับซ้อน ยิ่งมีหลายทีมทำงานบน model เดียว ความชัดเจนยิ่งเจือจาง
หลายคนกังวลว่าการมีหลาย model จะทำให้เกิด code ซ้ำซ้อน แต่ให้โฟกัสที่ประโยชน์ของการ ตัด dependency ระหว่างทีม ออกไป — การมี code ที่ดูคล้ายกันใน2 model นั้นยอมรับได้ เพราะแท้จริงแล้วมันคือคนละแนวคิดกัน
ภาษาใน model คลุมเครือ
หัวข้อที่มีชื่อว่า “ภาษาใน model คลุมเครือ”หนึ่งใน “บทเรียนแห่งการตื่นรู้” ของคนที่ทำ DDD คือการตระหนักว่า บางแนวคิดในระบบฟังดูคล้ายกันมาก — บางครั้งใช้ชื่อเดียวกันทุกตัวอักษร — แต่กลับ หมายถึงคนละสิ่งสำหรับคนละแผนก เช่นคำว่า “Ticket” ในแผนกขาย (จำนวนที่นั่ง วันที่ ราคา สถานที่) กับ “Ticket” ในแผนกบริการลูกค้า (ความรุนแรง เวลาที่แจ้ง หมวดหมู่)

เมื่อยอมรับว่าชื่อเดียวกันมีความหมายต่างกันในต่างบริบท ก็จะเข้าใจได้ง่ายขึ้นว่า หลาย model เล็กๆ ดีกว่า model ใหญ่ก้อนเดียว และคุยกับ domain expert ได้ตรงประเด็นกว่า — คุยกับผู้จัดการฝ่ายขายเรื่อง Ticket คุณรู้ว่าเขาสนใจราคากับสถานที่ ส่วนผู้จัดการฝ่ายบริการสนใจความรุนแรงและหมวดหมู่ของปัญหา
entity จริงหนึ่งตัว อาจเป็นหลายแนวคิด
หัวข้อที่มีชื่อว่า “entity จริงหนึ่งตัว อาจเป็นหลายแนวคิด”กับดักคลาสสิกคือ Product entity ทางกายภาพหนึ่งตัวมักถูกจับเป็น “1 class” ใน code ทั้งที่จริงๆ มันแทนหลายแนวคิดที่หมายถึงคนละเรื่องในคนละบริบท สำหรับทีมจัดซื้อ (Procurement) “product” คือสิ่งที่ต้องซื้อเข้ามาโดยคำนึงถึงกำไรและ lead time ที่ยอมรับได้ ส่วนสำหรับทีมขาย (Sales) “product” คือสิ่งที่มีรูปภาพ ตารางขนาด และหมวดหมู่การขาย — ซึ่งทีมจัดซื้อไม่ได้ให้ความสนใจเลย แม้จะเป็น entity ตัวเดียวกันในโลกจริง
เมื่อ developer ยัดทุกความต้องการลงใน class Product เดียว ผลคือ god object — class ยักษ์ที่ทุกบริบทอยากแก้ด้วยเหตุผลต่างกันโดยสิ้นเชิง ละเมิด Single Responsibility Principle (SRP) อย่างจัง

class Product ที่ share ร่วมกันในรูปที่ 6-6 คือตัวอย่างชั้นดีของ Big Ball of Mud การแก้ตรรกะใน subdomain หนึ่งจะมี ripple effect ที่ไม่พึงประสงค์ไปยัง subdomain อื่นที่ไม่เกี่ยวข้องกันเลย เพราะ code ถักทอพันกันและไม่มีขอบเขตความรับผิดชอบที่ชัดเจน
ทางออกที่ดีกว่าคือให้แต่ละบริบท — Promotion, Allocation, Loyalty, Shipping — มี model ของตัวเอง แต่ละ model มีตัวแทนของ product ที่ไม่ซ้ำกัน และตอบเฉพาะความต้องการของบริบทตัวเองเท่านั้น
ในระบบช้อปปิ้งออนไลน์ “สินค้า” ตัวเดียวมีได้หลายแง่มุม: ฝั่ง Catalog/Sales สนใจรูปภาพ รายละเอียด รีวิว และราคาขาย; ฝั่ง Inventory สนใจจำนวนคงเหลือและตำแหน่งจัดเก็บในคลัง; ฝั่ง Pricing สนใจส่วนลดและกฎโปรโมชัน; ฝั่ง Shipping สนใจน้ำหนักและขนาดเพื่อคำนวณค่าจัดส่ง เมื่อใดที่พยายามยัดทุกอย่างลงใน class Product เดียว ทุกทีมจะแย่งกันแก้ file เดียวกันทันที
เหตุผลอื่นที่ควรชอบ model เล็ก
หัวข้อที่มีชื่อว่า “เหตุผลอื่นที่ควรชอบ model เล็ก”- การต่อกับ legacy หรือ third-party — เมื่อ model มีขนาดเล็ก ไม่ใช่ทุก model ที่ต้องไปแตะ code เก่า model ใหม่ที่สะอาดจึงไม่ถูกข้อจำกัดของ legacy มาบีบรัดความชัดเจนของ design
- domain model ไม่ใช่ enterprise model — การมี model เดียวของทั้งองค์กรมีประโยชน์กับงาน BI และ reporting แต่ไม่เหมาะกับการสร้าง domain model ที่วิวัฒน์ได้และส่งมอบคุณค่าได้บ่อยๆ เราใช้ทั้งสองอย่างคู่กันได้ — model เฉพาะของแต่ละบริบท บวกกับ enterprise model สำหรับ reporting
Bounded Context: แบ่งแล้วพิชิต model ใหญ่
หัวข้อที่มีชื่อว่า “Bounded Context: แบ่งแล้วพิชิต model ใหญ่”Bounded ContextBounded Contextขอบเขตที่ชัดเจน (มักเป็นระบบย่อยหรือทีมหนึ่ง) ที่ model หนึ่งใช้ได้และมีความหมายแน่นอน ภายในขอบเขตนี้ Ubiquitous Language สอดคล้องกัน 100%Strategic Design คือสิ่งที่ นิยามขอบเขตการใช้งานของ model มันบอกชัดว่า model นี้ใช้ทำอะไร ควรสอดคล้องที่ไหน และควร เพิกเฉย ต่ออะไร แนวคิดของ domain ที่อยู่นอกบริบทจะไม่มากวนปัญหาที่ model นี้ถูกออกแบบมาแก้ มันทำให้ชัดเจนต่อทุกทีมว่า model รับผิดชอบอะไรและไม่รับผิดชอบอะไร
คำว่า “context” สำคัญมากใน DDD เมื่อพูดถึง product ในบริบทของ subdomain คลังสินค้า เราไม่จำเป็นต้องเรียกมันว่า “product ที่ส่งมอบได้” — มันก็คือ “product” ในบริบทที่นิยามไว้ชัดเจนแล้ว สิ่งสำคัญคือเวลาคุยกับ domain expert หรือเพื่อนร่วมทีม ทุกคนต้องรู้ว่ากำลังพูดอยู่ในบริบทไหน
ใน Model-Driven Design เราได้รู้จัก Ubiquitous LanguageUbiquitous Languageภาษากลางที่ทุกคนในทีม (ทั้งนักพัฒนาและผู้เชี่ยวชาญธุรกิจ) ใช้ร่วมกัน อิงกับ domain model โดยตรง คำเดียวกันต้องหมายถึงสิ่งเดียวกัน และสะท้อนลงใน codeStrategic Design (UL) และความสำคัญของ model ที่นิยามในบริบทซึ่งปลอดจากความกำกวมทางภาษา Bounded Context ต่อยอดแนวคิด “model in context” ด้วยการ ห่อมันไว้ในขอบเขตความรับผิดชอบที่เป็น implementation จริงในเชิงเทคนิค ต่างจาก context ที่เป็นนามธรรม Bounded Context บังคับให้การสื่อสารเกิดขึ้นในแบบที่ไม่ลดทอนความบริสุทธิ์ของ model
Bounded Context ก่อนสิ่งอื่นใดคือ ขอบเขตทางภาษา (linguistic boundary) — เวลาคุยกับ domain expert หากคุณรู้สึกว่าประโยคหนึ่งจำเป็นต้องมี “บริบท” มากำกับเสมอ นั่นคือสัญญาณชัดเจนว่าคุณต้องแยก model นั้นออกมาไว้ใน bounded context ของมันเอง
มอง Bounded Context ให้เหมือนพรมแดนของประเทศ — ไม่มีสิ่งใดผ่านเข้ามาได้หากไม่ผ่านด่านตรวจและถูกต้องตามกฎ เช่นเดียวกับที่คนละประเทศพูดคนละภาษา code ในแต่ละ bounded context ก็พูด UL ของตัวเอง หนึ่งในหัวใจสำคัญที่สุดของ DDD คือ การปกป้องขอบเขต (protecting the boundary) — เพราะหากไม่บังคับใช้ขอบเขตรอบ model สุดท้ายแล้วคุณจะได้กอง code ที่ลุกลามไปทุกทิศจนกลายเป็น BBoM

จะลากเส้นขอบเขตตรงไหน?
หัวข้อที่มีชื่อว่า “จะลากเส้นขอบเขตตรงไหน?”ความจำเป็นของ bounded context ชัดเจนในระบบใหญ่ แต่การ หา ว่าขอบเขตควรอยู่ตรงไหนนั้นท้าทาย ข่าวดีคือมันไม่ใช่การตัดสินใจล่วงหน้าที่ต้องถูกต้องแม่นยำตั้งแต่แรก เมื่อเรียนรู้ domain มากขึ้น เราปรับขอบเขตได้เสมอ ปัจจัยที่ใช้เป็นแนวทางมีดังนี้
1. ลากขอบเขตรอบ “ภาษา”
หัวข้อที่มีชื่อว่า “1. ลากขอบเขตรอบ “ภาษา””นี่คือไกด์ที่สำคัญที่สุด ถ้าคำหรือวลีหนึ่งเปลี่ยนความหมายเมื่อข้ามไปอีกพื้นที่ ตรงรอยต่อนั้นมักคือขอบเขตของ bounded context — ถ้าคำว่า product มีหลายความหมายภายใน model เดียว ก็ควรแยกเป็นอย่างน้อย2 bounded context ที่แต่ละอันมีนิยามของ product เพียงหนึ่งเดียว (ดูรูปที่ 6-9) ในทำนองกลับกัน คำเดียวที่หมายถึงหลายแนวคิด (เช่น Ticket ในรูปที่ 6-3) ก็เป็นขอบเขตทางภาษาเช่นกัน linguistic boundary คือ bounded context boundary
2. จัดให้ตรงกับ business capability
หัวข้อที่มีชื่อว่า “2. จัดให้ตรงกับ business capability”องค์กรคือระบบนิเวศของบริการที่พึ่งพากัน แต่ละบริการมีคำศัพท์ของตัวเอง business capability จึงมักเป็นตัวบ่งชี้ขอบเขตทางภาษาที่ดี เช่นถ้ามีแผนกขายและแผนกบริการลูกค้า ก็มีแนวโน้มสูงว่าจะมี sales context และ customer service context
อย่า model ตามโครงสร้างองค์กรอย่างไม่ไตร่ตรอง — บางครั้ง business capability ก็ไม่ได้สอดคล้องกับ problem domain อย่างพอดิบพอดี Melvin Conway เตือนไว้ว่า
ระบบใดๆ ที่องค์กรออกแบบ จะมีโครงสร้างที่เป็นสำเนาของโครงสร้างการสื่อสารขององค์กรนั้นอย่างหลีกเลี่ยงไม่ได้
— Conway’s Law
ใช้กฎนี้เป็นแนวทางได้สองทาง: รู้เท่าทันมันเพื่อไม่ให้เผลอ model ตามโครงสร้างองค์กรล้วนๆ หรือ ปรับโครงสร้างองค์กรใหม่ ให้สอดคล้องกับสถาปัตยกรรมที่ต้องการ ทั้งสองทางต้องใช้ความพยายามสูง จึงต้องวางแผนอย่างรอบคอบ
3. โครงสร้างทีมและที่ตั้ง
หัวข้อที่มีชื่อว่า “3. โครงสร้างทีมและที่ตั้ง”โครงสร้างทีมและที่ตั้งทางกายภาพมีอิทธิพลต่อขอบเขตมาก หลักการคือ หนึ่งทีมเป็นเจ้าของ1 bounded context จัดทีมเป็นกลุ่ม product/service รอบๆ bounded context (ไม่ใช่ลอกโครงสร้างแผนก) และให้ทีมรับผิดชอบครบตั้งแต่ presentation → domain logic → persistence
Amazon มีนโยบายไม่ให้ทีมพัฒนาใหญ่จนพิซซ่าสองถาดเลี้ยงไม่อิ่ม เพราะทีมเล็กและโฟกัสจะ ตัดสินใจได้ดีขึ้นและเร็วขึ้น เมื่อทีมดูแลทั้ง product และการตัดสินใจเชิงเทคนิคด้วยตัวเอง ก็ iterate ได้รวดเร็วโดยไม่ต้องกังวลว่าจะกระทบทีมอื่น — แต่อย่าตัดการสื่อสารระหว่างทีมทิ้งทั้งหมด ควรคงไว้บ้างเพื่อแลกเปลี่ยนความรู้ เช่น cross-team pair programming และ session แบ่งปันสิ่งที่แต่ละทีมกำลังทำอยู่
4. legacy และ third-party — แต่ “ขนาด” ไม่ใช่เกณฑ์
หัวข้อที่มีชื่อว่า “4. legacy และ third-party — แต่ “ขนาด” ไม่ใช่เกณฑ์”การต่อกับ legacy หรือระบบภายนอกก็เป็นเหตุผลที่ลากเส้นได้ แต่ขอนำเสนอสิ่งที่ ไม่ใช่ เกณฑ์: ขนาด ไม่มีตัวเลขสัมบูรณ์หรือสัมพัทธ์ใดบอกได้ว่า bounded context ควรมีกี่ class หรือกี่บรรทัด ขนาดขึ้นอยู่กับ problem domain ล้วนๆ บาง context จึงใหญ่ บาง context ก็เล็ก
Context Game
หัวข้อที่มีชื่อว่า “Context Game”เพื่อเผยให้เห็นว่ามีหลาย model ซ่อนอยู่ Greg Young เสนอเกมชื่อ Context Game: เมื่อสงสัยว่าคำหนึ่งกำกวมหรือแบกความหมายเกินตัว ให้แบ่งคนเป็นกลุ่มเล็ก (developer + business expert) แยกตามแผนก ให้เวลา 20 นาทีนิยามว่าคำนั้นหมายถึงอะไรในพื้นที่ของเขา แล้วกลับมานำเสนอ จุดที่แต่ละฝ่ายเห็นต่างกัน คือจุดที่ต้องลากเส้นบริบทและสร้าง model ใหม่
Subdomain ต่างจาก Bounded Context อย่างไร
หัวข้อที่มีชื่อว่า “Subdomain ต่างจาก Bounded Context อย่างไร”สองคำนี้สับสนกันบ่อยที่สุด สรุปสั้นๆ คือ subdomain อยู่ใน problem space ส่วน bounded context อยู่ใน solution space
| SubdomainSubdomainส่วนย่อยของ Domain ใหญ่ เช่น Domain e-commerce แตกเป็น subdomain การสั่งซื้อ การชำระเงิน คลังสินค้า ฯลฯ อยู่ใน “พื้นที่ปัญหา” (problem space)Strategic Design | Bounded ContextBounded Contextขอบเขตที่ชัดเจน (มักเป็นระบบย่อยหรือทีมหนึ่ง) ที่ model หนึ่งใช้ได้และมีความหมายแน่นอน ภายในขอบเขตนี้ Ubiquitous Language สอดคล้องกัน 100%Strategic Design | |
|---|---|---|
| อยู่ใน | Problem space (ปัญหา) | Solution space (คำตอบ) |
| ธรรมชาติ | พื้นที่เชิงตรรกะของ domain | implementation จริงในเชิงเทคนิค |
| หน้าที่ | แบ่ง problem domain เผยให้เห็น core/supporting/generic | บังคับขอบเขตระหว่าง model จริงๆ ใน code |
| ความสัมพันธ์ | อุดมคติคือ 1 ต่อ 1 กับ model | แต่จริง: subdomain หนึ่งอาจมีหลาย model หรือ model หนึ่งคร่อมหลาย subdomain |
ในอุดมคติจะมี mapping แบบ 1-ต่อ-1 ระหว่าง model กับ subdomain แต่ในความเป็นจริง model ถูกนิยามจากปัจจัยอย่างโครงสร้างทีม ความกำกวมของภาษา การจัดกระบวนการธุรกิจ (business process) หรือการ deploy — โดยเฉพาะในสภาพแวดล้อม legacy
flowchart LR
subgraph PS["Problem Space"]
SD1["Subdomain: Sales (core)"]
SD2["Subdomain: Shipping (supporting)"]
end
subgraph SS["Solution Space"]
BC1["Sales Bounded Context"]
BC2["Pricing Bounded Context"]
BC3["Shipping Bounded Context"]
end
SD1 --> BC1
SD1 --> BC2
SD2 --> BC3
ลงมือสร้าง Bounded Context
หัวข้อที่มีชื่อว่า “ลงมือสร้าง Bounded Context”Bounded Context เป็นเจ้าของ vertical slice ของ function ทั้งชิ้น — ตั้งแต่ presentation layer ผ่าน domain logic ลงไปถึง persistence และแม้แต่ data storage เมื่อนำแนวคิดนี้ไปใช้กับระบบ god object เดิม ผลที่ได้คือแต่ละ bounded context ดูแล presentation, domain logic และ persistence ของตัวเอง การเปลี่ยนใน context หนึ่งจึงไม่กระเพื่อมไปกระทบ context อื่นอีกต่อไป

class Product ตัวเดียวกันจึงปรากฏในหลาย model แต่ถูกนิยามด้วยบริบทที่มันอยู่ — ใน Loyalty มันรู้แค่วิธีคิดแต้ม ส่วนใน Promotion มันรู้แค่วิธีรวมเข้าโปรโมชัน:
namespace Loyalty{ public class Product { // คิดแต้มสะสมที่ลูกค้าจะได้จากสินค้านี้ public Points Earns() { /* ... */ } }}
namespace Promotion{ public class Product { // รวมสินค้านี้เข้ากับข้อเสนอ/โปรโมชัน public void IncludeIn(Offer offer) { /* ... */ } }}ไม่จำเป็นต้องใช้สถาปัตยกรรมเดียวกันทุก context
หัวข้อที่มีชื่อว่า “ไม่จำเป็นต้องใช้สถาปัตยกรรมเดียวกันทุก context”นี่คือพลังที่แท้จริงของการแยกขอบเขต: architectural pattern ถูกเลือกที่ระดับ bounded context ไม่ใช่ระดับ app ถ้า context หนึ่งเป็น supporting/generic ที่มีตรรกะน้อย ก็ใช้สไตล์ CRUD เรียบง่ายได้ (อย่ากลัวคำว่า CRUD — ยึดหลัก KISS ไว้ก่อน) แต่ถ้าตรรกะซับซ้อนพอ ก็สร้าง rich object-oriented model หรือแม้แต่ CQRSCQRSCommand Query Responsibility Segregation — แยก model สำหรับ “เขียน/แก้ไข” (command) ออกจาก model สำหรับ “อ่าน” (query) เหมาะกับ domain ซับซ้อน แต่เพิ่มความซับซ้อน ใช้อย่างระมัดระวังArchitecture เฉพาะ context นั้น แล้วประกอบทุก context เข้าด้วยกันผ่าน composite UI ที่ดึงข้อมูลจากหลาย bounded context มาแสดงในหน้าเดียว
ในระบบขนส่งตู้ container บริบท Routing (วางแผนเส้นทางเรือและท่าเรือ) มีตรรกะธุรกิจเข้มข้นมาก จึงคุ้มค่าที่จะลงทุนทำ rich domain model เต็มรูปแบบ ส่วนบริบท Customer Management (ข้อมูลผู้ส่ง/ผู้รับ) แทบไม่มีกฎ ใช้ CRUD ก็เพียงพอ และบริบท Tracking ที่มีการอ่านสถานะหนักหน่วง อาจเลือก CQRS เพื่อแยก read model ออกมา — สามบริบทในระบบเดียว สามสถาปัตยกรรม นี่คือสิ่งที่ bounded context เปิดทางให้ทำได้
กายวิภาคของ bounded context
หัวข้อที่มีชื่อว่า “กายวิภาคของ bounded context”วิธีปกป้องความบริสุทธิ์ของ model คือเปิดเฉพาะ Application Service เป็น API แบบหยาบ (coarse-grained) ที่ห่อหุ้มรายละเอียดของ domain model ไว้ข้างใน endpoint นี้รับ input จาก model อื่นแล้วแปลให้เป็นภาษาที่ model ภายในเข้าใจ ป้องกันไม่ให้เส้นแบ่งความรับผิดชอบพร่าเลือน — autonomy (ความเป็นอิสระในการปกครองตนเอง) จึงเป็นคุณสมบัติหลักที่แยกทีมออกจากสิ่งรบกวนภายนอก และแยก model ออกจากแนวคิดที่ไม่เกี่ยวข้อง

การฝืนใช้ model เดียวกับ problem domain ที่ซับซ้อนมักลาก code ให้กลายเป็น Big Ball of Mud ทางแก้คือ นิยามบริบทของแต่ละ model ให้ชัดเจน แล้วล้อมด้วย Bounded Context ซึ่งเป็น ขอบเขตทางภาษา (linguistic boundary) ที่ปกป้องความบริสุทธิ์ของ domain model จำให้ขึ้นใจว่า subdomain อยู่ใน problem space ส่วน bounded context อยู่ใน solution space; หนึ่งทีมควรเป็นเจ้าของ1 bounded context อย่าง autonomous ครบทั้ง stack; และเลือก architectural pattern ที่ระดับ bounded context ไม่ใช่ระดับ app
เจาะลึกแนวคิดในบทนี้ต่อได้ที่คลังอ้างอิง DevIQ:
- Bounded Context — นิยามและตัวอย่างเพิ่มเติมของขอบเขตที่ล้อม model ให้บริสุทธิ์ ตรงกับแก่นของบทนี้
- Ubiquitous Language — ขยายความว่าทำไม linguistic boundary ถึงเป็นสัญญาณสำคัญที่สุดในการลากเส้น bounded context
- Subdomain — เปรียบเทียบ problem space กับ solution space ให้ชัดขึ้น ต่อยอดจากตารางเทียบในบทนี้
- Context Mapping — ก้าวถัดไปหลังแบ่ง bounded context แล้ว คือการนิยามความสัมพันธ์ระหว่างบริบทเหล่านั้น
- CQRS — ตัวอย่างสถาปัตยกรรมที่เลือกใช้เฉพาะบาง bounded context ที่มีตรรกะซับซ้อนหรืออ่านหนัก ที่กล่าวถึงถึงในบทนี้
เช็กความเข้าใจ — บทที่ 6
ข้อ 1 / 4ทำไม DDD จึงสนับสนุนให้แตกระบบใหญ่ออกเป็นหลาย code model แทนที่จะใช้ model เดียว?