บทที่ 29 · Part 6 — Adoption and Evolution
DDD by Company Context
เลือก practice ให้พอดีกับ small business, scale-up, corporate และ regulated Fintech โดยไม่ลอก enterprise ceremony
DDD by Company Context
คำแนะนำ DDD ที่เกิดในองค์กรซึ่งมี engineer หลายพันคนอาจทำร้ายบริษัทที่มีทีม product เพียง 6 คนได้พอ ๆ กับการนำวิธีของ startup ไปใช้กับธนาคารที่มี legacy systems, regulatory obligations และทีมกระจายหลายประเทศ คำศัพท์เดียวกันยังใช้ได้ แต่ระดับของ artifact, governance, ownership และ deployment ต้องต่างกัน
จบบทนี้คุณจะ
เลือก minimum viable DDD สำหรับ small business, growth company, corporate และ regulated Fintech วาง ownership ให้ตรงกับจำนวนทีม และอธิบายได้ว่า practice ใดควรทำตอนนี้ practice ใดรอได้ และสัญญาณใดบอกว่าควรยกระดับ
[!IMPORTANT] Company size เป็นเพียง Proxy จำนวนพนักงานหรือรายได้ไม่บอก domain complexity โดยตรง บริษัทเล็กที่ทำ credit decision อาจต้อง model policy ลึกกว่าบริษัทใหญ่ที่ทำ CRUD ภายใน บทนี้จึงใช้ขนาดองค์กรร่วมกับ complexity, risk, dependency และ team topology ไม่ใช้เป็นสูตรเลือก architecture
แผนที่ 2 แกนก่อนดูขนาดบริษัท
ประเมิน 2 แกนแยกกัน:
- Model complexity — กฎ, state, exception, language conflict และความเสียหายเมื่อผิด
- Coordination complexity — จำนวนทีม, handoff, vendor, legacy, geography และ release boundary
| Model | Coordination | จุดเริ่มที่มักพอดี |
|---|---|---|
| ต่ำ | ต่ำ | simple module, clear names, example-based tests |
| สูง | ต่ำ | collaborative discovery + Rich Domain Model ใน process เดียว |
| ต่ำ | สูง | ownership map, contract, platform/API governance; อย่าฝืนสร้าง Aggregate |
| สูง | สูง | Strategic DDD + Context Map + team alignment + selective Tactical DDD |
ตารางนี้อธิบายว่าทำไม “องค์กรใหญ่ต้องทำ DDD เต็มชุด” และ “ startup ไม่ต้องใช้ DDD” จึงไม่จริงเสมอ องค์กรใหญ่ที่มี model เรียบง่ายอาจต้องการ contract governance มากกว่า domain objects ขณะที่ startup ด้าน lending อาจต้องเริ่ม Ubiquitous Language และ invariant ตั้งแต่วันแรก
Small Business หรือทีมเดียว
บริบททั่วไปคือ Product owner กับ Engineer คุยกันได้ตรง ทีม deploy application เดียว และยังไม่มี เหตุให้จัด workshop ขนาดใหญ่ เป้าหมายคือเก็บความรู้โดยไม่เพิ่ม ceremony:
ทำตอนนี้
- เลือก 1– 3 critical scenarios พร้อม exception ไม่เริ่มจาก entity list
- ใช้ glossary ขนาดเล็กอยู่ข้าง code หรือ acceptance examples
- จัด package ตาม business capability และมี owner คนเดียวที่ตอบ policy
- ใช้ Transaction Script ถ้ากฎตรงไปตรงมา ใช้ Value Object/Aggregate เฉพาะกฎที่เริ่มหนาแน่น
- บันทึก exit criteria เช่น change เริ่มกระจายหรือคำเดียวมีหลายความหมาย
ยังไม่ต้องทำโดยอัตโนมัติ
- Context Map ทั้งบริษัท, architecture guild และ repository แยกทุก context
- microservices, event bus, CQRS หรือ Event Sourcing เพื่อให้ดู “เป็น DDD”
- interface สำหรับทุก struct หรือ layer ที่มีเพียงการส่งข้อมูลต่อ
ค่าใช้จ่ายสำคัญของบริษัทเล็กคือ opportunity cost หาก workshop 1 วันไม่เปลี่ยน decision, scenario หรือ code ที่จะส่งมอบ สัปดาห์ถัดไปควรลด scope ไม่ใช่เพิ่ม notation
Growth Company ที่เริ่มมีหลายทีม
สัญญาณเปลี่ยนระยะคือ ownership ทับกัน, release ต้องรออีกทีม, shared table ถูกเขียนหลายทาง
และคำอย่าง Customer, Order หรือ Balance เริ่มมีความหมายต่างกัน ขั้นนี้ DDD ให้ผลมากจาก
การทำ boundary และ contract ให้เห็นก่อนแยก runtime:
- ทำ Big Picture/Domain Story รอบ value stream ที่มี coordination pain สูง
- จำแนก Subdomain เพื่อไม่ลงทุนทุก capability เท่ากัน
- ตั้ง candidate Bounded Context จาก language, invariant, lifecycle และ change pattern
- กำหนด module owner, public contract และ data ownership ใน modular monolith ก่อน
- แยก deployable เมื่อมี scale, failure isolation หรือ release ownership เป็นหลักฐาน
Domain Analysis ของ Microsoft เน้น business capability, loose coupling, cohesion และการจัด team ownership ให้สนับสนุน boundary อย่างตั้งใจ เอกสารเดียวกันระบุว่า boundary ต้องประเมินต่อเนื่อง ไม่ใช่วาดครั้งเดียวแล้วหยุด
Large Corporate หลาย Business Units
องค์กรใหญ่มีทั้ง semantic complexity และอำนาจต่อรองระหว่างทีม Context Map จึงต้องเก็บ relationship ไม่ใช่เพียงกล่อง:
- upstream/downstream และ business owner ของ contract
- Published Language, version, deprecation และ support expectation
- ข้อมูลใด authoritative ใครอ่าน snapshot และใครมีสิทธิ์สั่งเปลี่ยน
- translation/Anti-Corruption Layer เมื่อ model หรือ vendor ต่างกัน
- team interaction: collaboration ชั่วคราว, X-as-a-Service หรือ facilitation
- portfolio: Core/Supporting/Generic classification และ build/buy/partner decision
Team Topologies เสนอ stream-aligned, platform, enabling และ complicated-subsystem teams พร้อม interaction modes เพื่อจัด cognitive load แนวคิดนี้เสริม DDD แต่ไม่ใช่คำเดียวกัน Bounded Context ไม่เท่ากับทีมเสมอ และ org chart ไม่ควรกลายเป็น model boundary อัตโนมัติ
กรณี DOMA ของ Uber แสดงการจัด related microservices เป็น domain, ใช้ gateway, layer และ extension point เพื่อลด complexity ของ service landscape ใหญ่ บทเรียนที่ถ่ายโอนได้คือจัด dependency และ ownership อย่างตั้งใจ ไม่ใช่คัดลอก จำนวน layer หรือใช้คำว่า domain ตามความหมายเดียวกับ Bounded Context โดยไม่ตรวจบริบท
Regulated Fintech และองค์กรที่กระทบเงิน
เพิ่มแกน risk/control โดยไม่สรุปว่า “ compliance จึงต้อง microservices”:
| Concern | Artifact ที่ช่วยตัดสิน | สิ่งที่ DDD ไม่ได้ทำแทน |
|---|---|---|
| Financial decision | invariant + authoritative decision path | กำหนดเพดานหรืออนุมัติ policy |
| Regulatory policy | owner, source, effective date, version | ตีความกฎหมายแทน Legal/Compliance |
| Auditability | command/event identity + decision evidence | รับรองว่าผ่าน regulation |
| Segregation of duties | role/action/resource policy model | เลือก maker-checker threshold |
| Third-party risk | port + ACL + failure/reconciliation contract | รับประกัน behavior ของ provider |
| Customer display | read model + freshness contract | ใช้ cache ตัดสินยอดเงินจริง |
แยก Display Path ออกจาก Decision Path
หน้าจออาจอ่านยอดรวมจาก Redis หรือ composed read model ที่ยอมรับความเก่าได้ แต่การอนุมัติ Transfer, Refund หรือ Credit ต้องกลับไปให้ owning context อ่าน authoritative state และตรวจ invariant ภายใต้ concurrency boundary ที่เหมาะสม ค่า policy ทุกตัวต้องมีเจ้าของ เอกสาร และวันที่
องค์กร regulated มักต้องมี traceability มากขึ้น แต่ไม่ควรเปลี่ยนทุกเหตุการณ์เป็น Event Sourcing โดยอัตโนมัติ Domain Event, integration message, audit record และ event-sourced state เป็นคนละเรื่อง เลือกแต่ละกลไกจาก requirement ที่มี owner
อ่าน Company Case อย่างไม่ลอก Architecture
first-party cases ช่วยให้เห็นแรงจริง แต่ต้องรักษาขอบเขตของหลักฐาน:
- Monzo: How We Calculate Balances แสดงว่าคำว่า balance มีหลาย definition และ time axis จน backend, warehouse และ reconciliation อาจให้คำตอบไม่ตรงกัน บทเรียนคือทำ semantic definition กับ owner ให้ชัด ไม่ใช่คัดลอกวิธีคำนวณของ Monzo
- Adyen: Architecture Decisions อธิบาย monorepo/platform ที่แบ่ง relatively independent business domains และให้ edge, accounting กับ reporting มี quality attributes ต่างกัน เป็น counterexample ที่มีประโยชน์ต่อ ความเชื่อว่า DDD ต้องเท่ากับ microservices
- Uber DOMA แสดงการจัด dependency เมื่อ landscape มี service จำนวนมาก พร้อมชี้ต้นทุนของ microservices ต่อ startup
ทั้ง 3 แหล่งเป็นรายงานจากบริษัทเจ้าของระบบ ณ เวลาหนึ่ง ไม่ใช่ standard หรือ causal proof ของ DDD ให้ถามเสมอว่าแรงด้าน scale, regulation, team และ product ของเราตรงกับ case ใดจริง
Adoption Ladder ที่ไม่ผูกกับ Headcount
| ระดับ | ใช้เมื่อ | Practices ขั้นต่ำ | Exit signal |
|---|---|---|---|
| Language | requirement กำกวม | scenario, examples, glossary | คำชนกันข้าม capability |
| Model | กฎและ state ซับซ้อน | Value Object, invariant tests, Aggregate ที่จำเป็น | change กระจายหลาย model |
| Boundary | หลาย model/owner | Subdomain, Bounded Context, contracts | coordination หรือ runtime need สูง |
| Organisation | หลายทีมพึ่งกัน | Context Map, team alignment, platform/enabling support | portfolio/contract drift |
| Ecosystem | vendor/partner/legacy มาก | Published Language, ACL, compatibility and reconciliation | landscape เปลี่ยนหรือ acquisition |
ทีมเดินขึ้นหรือลง ladder ได้ Supporting capability อาจลดจาก custom model ไปใช้ SaaS ขณะที่ Core capability ถูกลงทุนเพิ่ม ไม่มีเป้าหมายว่าทุกส่วนต้องไปถึงระดับสูงสุด
รูปแบบความล้มเหลวตามบริบท
- Small business: ทำ ceremony เหมือน corporate จน discovery แพงกว่าการส่งมอบ
- Growth company: แยก microservice ตาม candidate context ก่อนมี contract และ operational owner
- Corporate: central architecture team สร้าง canonical enterprise model แล้วทีมจริงไม่ใช้
- Regulated Fintech: ซ่อน policy ที่ไม่มี owner ไว้ใน config แล้วอ้างว่า model ยืดหยุ่น
- ทุกขนาด: ใช้ org chart หรือ database schema เป็น boundary โดยไม่ตรวจ language/invariant
แบบฝึกปฏิบัติ: Contextual Adoption Canvas
เลือกบริษัทหรือหน่วยงาน 1 บริบทแล้วกรอก:
Business stage and strategy:
Model complexity evidence:
Coordination complexity evidence:
Risk / regulation owners:
Current team and deployment boundaries:
Painful value stream:
Minimum practices for the next 6 weeks:
Artifacts deliberately omitted:
Expected evidence:
Exit / escalation signal:
Named owner and review date:
ท้าทาย canvas ด้วย 2 เหตุการณ์: บริษัทโตจาก 1 ทีมเป็น 4 ทีม และ strategy เปลี่ยนจาก สร้าง Payment Routing เองเป็นซื้อ provider หาก classification, ownership และ practice ยังเหมือนเดิมทุกอย่าง แสดงว่า canvas ยังผูกกับ template มากกว่าบริบท
รายการตรวจสอบ
- ประเมิน model complexity แยกจาก coordination complexity
- Small business เริ่มจาก language/scenario/module ไม่ใช่ enterprise ceremony
- Growth company ทดลอง boundary ใน code ก่อนรีบสร้าง network boundary
- Corporate Context Map เก็บ power, contract และ owner ไม่ใช่แค่กล่อง
- Team topology สนับสนุน flow แต่ไม่ถูกประกาศว่าเท่ากับ Bounded Context
- Financial policy มี accountable source และ effective date
- ทุกระดับมี exit signal และลด practice ได้เมื่อไม่คุ้ม
สรุปบทนี้
DDD ที่ดีมีความลึกไม่เท่ากันทั่วบริษัท ทีมเล็กต้องรักษาความเร็วพร้อมเก็บ language และ invariant ที่สำคัญ ทีมเติบโตต้องทำ ownership กับ module boundary ให้เห็น องค์กรใหญ่ต้องจัด relationship และ cognitive load ส่วน regulated Fintech ต้องเพิ่ม policy provenance กับ evidence โดยไม่มีบริบทใดได้ประโยชน์จากการสร้าง pattern มากกว่าปัญหา
อ่านเพิ่มเติม
- Use Domain Analysis to Model Microservices — iterative domain analysis และ team alignment
- Microservices Assessment and Readiness — first-party readiness guidance ที่รวมทีมและ operation
- Team Topologies Key Concepts — team types, interaction modes และ cognitive load จากผู้สร้างแนวคิด
- Introducing DOMA — first-party large-scale case study ของ Uber
- How We Calculate Balances — first-party Fintech case เรื่อง language ของ balance
- Design to Duty: Architecture Decisions at Adyen — first-party case ที่แยก domain จาก deployment style