บทที่ 11 · Part 3 — Bound Models and Relationships
Bounded Contexts in Practice
กำหนดขอบเขตที่ model และภาษาหนึ่งสอดคล้องกันโดยไม่เท่ากับ service, team หรือ database อัตโนมัติ
Bounded Contexts in Practice
คำว่า Customer ใน Risk หมายถึง subject ที่ต้องประเมิน ใน Billing หมายถึงผู้รับเอกสาร
และใน Portal หมายถึงคนที่กำลังเปิด session การสร้าง Customer model กลางเพื่อ “ลด duplication”
ทำให้ทุก change ต้องต่อรองกัน และ field จาก context หนึ่งถูกนำไปตัดสินอีก context โดยไม่รู้ semantics
Bounded Context ปกป้องความสอดคล้องของ model และ language ไม่ใช่เส้น network
จบบทนี้คุณจะ
หา Bounded Context จาก language, decisions, invariants, lifecycle และ authority แยก context จาก team, module, service, repository และ database ทดสอบ boundary ด้วย scenarios และบันทึก assumptions/alternatives โดยไม่รีบทำ microservices
นิยาม Boundary ของ Model
DDD Reference และ Bounded Context ของ Martin Fowler อธิบาย boundary ที่ model หนึ่งใช้ได้อย่างสอดคล้อง ภายใน boundary คำ, rules และ relationships ต้องไม่ขัดกัน ส่วนข้าม boundary อนุญาตให้ model ต่างและต้องแปลอย่างตั้งใจ
Boundary มี evidence 5 กลุ่ม:
- Language fracture — คำเดียวความหมายต่างหรือ grammar ต่าง
- Decision authority — ใครมีสิทธิ์ตัดสิน policy/invariant
- Lifecycle/consistency — state ใดเปลี่ยนร่วมกันและต้อง consistent
- Change pattern — requirements ไหนเปลี่ยนพร้อม/แยกกัน
- Ownership — business/technical knowledge และ incident responsibility อยู่ที่ใคร
อย่าใช้เพียงจำนวน tables, current services หรือ org chart
Context ไม่เท่ากับสิ่งเหล่านี้
| แกน | ตัวอย่าง | ความสัมพันธ์กับ Context |
|---|---|---|
| Model boundary | Risk language/model | ตัวนิยามหลัก |
| Code module | Go package/module | implementation หนึ่งแบบ |
| Runtime | process/service | deploy choice |
| Data | schema/database | authority/control choice |
| Team | Risk Product Team | ownership arrangement |
| Product | Wallet | อาจมีหลาย contexts |
Context หนึ่งอยู่ใน modular monolith ได้ หรือมีหลาย physical services ได้ Microsoft ย้ำว่า domain analysis และ service boundary เป็น iterative decisions ใน Azure Domain Analysis
ตัวอย่าง Customer หลาย Contexts
| Context | Customer model | ไม่เป็นเจ้าของ |
|---|---|---|
| Onboarding | identity evidence, verification journey | transfer eligibility ปัจจุบัน |
| Risk | subject reference, risk signals, decision history | billing address presentation |
| Billing | legal/billing snapshot, tax identity | login credential |
| Portal | principal/session, display preference | authoritative customer status |
Context อาจเก็บ reference หรือ snapshot จากอีกฝ่าย แต่ต้องระบุ source, time, correction และ decision ที่อนุญาต การ copy data ไม่เท่ากับ copy authority
บุคคลจริงคนเดียวจึงมีหลาย model ได้ ลูกศรระบุ Published Language ที่ตั้งใจส่ง ไม่ใช่การแชร์
Customer object เดียวกัน และแต่ละ downstream ต้องรู้ว่าข้อมูลเป็น reference, snapshot หรือ decision
Boundary Hypothesis Card
Candidate context:
Purpose:
Ubiquitous Language statements:
Owned decisions and invariants:
Entities/lifecycles:
Authoritative data:
Inputs accepted and trust level:
Outputs promised:
Business and technical owners:
Deployment today:
Alternative merge/split:
Counterexample / review trigger:
คำว่า candidate ทำให้ทีมยอมเปลี่ยนเมื่อ scenario ใหม่ไม่พอดี
Stress-test ด้วย Financial Scenarios
ใช้ 4 เรื่อง:
- Risk approved แต่ funds ไม่พอ
- provider accepted แต่ Ledger ยังไม่ post
- Customer legal name เปลี่ยนหลัง transfer receipt ถูกออก
- Portal แสดง balance เก่าขณะมี reservation ใหม่
ถามว่า context ใดมี authority ตัดสินและ context อื่นเห็น fact ผ่านอะไร ถ้า Portal ต้อง join tables ของทุกฝ่ายเพื่ออนุมัติ transfer แสดงว่า authority boundary ถูกละเมิด หาก Context ใหญ่ต้องโหลด ทุก lifecycle เพื่อ decision เล็ก อาจต้อง split
Snapshot ใช้ Decision ได้เฉพาะ Contract อนุญาต
displayed balance, cached profile หรือ old policy decision ห้ามถูกนำไปตัดสินเงิน/สิทธิ์โดยเงียบ Owning context ต้องระบุ freshness, validity, authority และ concurrency semantics
Boundary Smells
shared-domainmodel ที่ทุกทีมแก้- คำเดียวต้องมี flags เพื่อบอก product/context
- team A เขียน table ของ team B เพื่อให้ flow จบ
- integration ส่ง ORM entity ทั้งก้อน
- context ทุกกล่องเท่ากับ current microservice
- boundary ถูก split ตาม CRUD entity แต่ business decision ยังข้ามหลายกล่อง
Smell เป็นคำถาม ไม่ใช่ verdict Shared Kernel อาจถูกเลือกอย่างตั้งใจ แต่ต้องมี co-ownership และ coordination cost ที่ยอมรับ
แบบฝึกปฏิบัติ: Customer Boundary Trial
สร้าง candidate contexts สำหรับ Onboarding, Risk, Billing และ Portal พร้อม glossary ของ
Customer, Verified, Active, Address ทดสอบด้วย legal-name-change scenario และ policy expiry
แล้วส่ง:
- boundary cards 4 ใบ
- shared facts vs owned decisions table
- alternative ที่ merge 2 contexts
- alternative ที่ split 1 context
- evidence ที่ใช้เลือกตอนนี้และ review trigger
รายการตรวจสอบ
- Boundary มาจาก model/language consistency
- Decision/invariant authority มี owner
- Context แยกจาก team/service/database/product
- Reference/snapshot ไม่แอบโอน authority
- Scenario ที่มี time/failure ท้าทาย boundary แล้ว
- Alternative และ counterevidence ถูกบันทึก
- Deployment ถูกเลือกภายหลัง
สรุปบทนี้
Bounded Context ทำให้ model หนึ่งมีความหมายสอดคล้องและกำหนด authority ของ decisions มันเป็น hypothesis ที่พิสูจน์ด้วย language, rules, lifecycle, change และ ownership ไม่ใช่ชื่อกล่อง ใน deployment diagram
อ่านเพิ่มเติม
- Bounded Context — Martin Fowler
- DDD Reference — Bounded Context และ Context Map
- Azure Domain Analysis — iterative boundary guidance