บทที่ 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
ModelCoordinationจุดเริ่มที่มักพอดี
ต่ำต่ำ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:

  1. ทำ Big Picture/Domain Story รอบ value stream ที่มี coordination pain สูง
  2. จำแนก Subdomain เพื่อไม่ลงทุนทุก capability เท่ากัน
  3. ตั้ง candidate Bounded Context จาก language, invariant, lifecycle และ change pattern
  4. กำหนด module owner, public contract และ data ownership ใน modular monolith ก่อน
  5. แยก 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”:

ConcernArtifact ที่ช่วยตัดสินสิ่งที่ DDD ไม่ได้ทำแทน
Financial decisioninvariant + authoritative decision pathกำหนดเพดานหรืออนุมัติ policy
Regulatory policyowner, source, effective date, versionตีความกฎหมายแทน Legal/Compliance
Auditabilitycommand/event identity + decision evidenceรับรองว่าผ่าน regulation
Segregation of dutiesrole/action/resource policy modelเลือก maker-checker threshold
Third-party riskport + ACL + failure/reconciliation contractรับประกัน behavior ของ provider
Customer displayread 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
Languagerequirement กำกวมscenario, examples, glossaryคำชนกันข้าม capability
Modelกฎและ state ซับซ้อนValue Object, invariant tests, Aggregate ที่จำเป็นchange กระจายหลาย model
Boundaryหลาย model/ownerSubdomain, Bounded Context, contractscoordination หรือ runtime need สูง
Organisationหลายทีมพึ่งกันContext Map, team alignment, platform/enabling supportportfolio/contract drift
Ecosystemvendor/partner/legacy มากPublished Language, ACL, compatibility and reconciliationlandscape เปลี่ยนหรือ 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 มากกว่าปัญหา

อ่านเพิ่มเติม