Tài liệu dành cho Backend Engineer, Senior Backend Engineer, Tech Lead, Solution Architect và Software Architect. Viết bằng tiếng Việt, giữ nguyên thuật ngữ chuyên ngành (Domain, Bounded Context, Aggregate, Entity, Value Object, Domain Event, Repository, Ubiquitous Language…). Code mẫu dùng TypeScript (NestJS) và Go, mỗi khái niệm đều được đối chiếu với cách làm phổ biến trong framework để chỉ ra những điểm dễ hiểu sai.

Tài liệu này viết theo triết lý nào

Không chương nào mở đầu bằng định nghĩa. Mọi khái niệm đi theo mạch: vấn đề business có thật → vì sao cách làm truyền thống thất bại → bản chất của lời giải → cách hoạt động → điểm mạnh, điểm yếu, trade-off → cân nhắc production → anti-pattern → khi nào KHÔNG nên dùng. Mỗi kết luận kỹ thuật đều phải trả lời: tại sao? đánh đổi gì? không áp dụng thì sao? áp dụng sai thì hậu quả gì? Và xuyên suốt: DDD không phải một bộ class — nó là phương pháp tư duy để quản lý sự phức tạp của business; tài liệu không thần thánh hóa nó, mà chỉ rõ chỗ nào nó đáng tiền và chỗ nào nó là gánh nặng.

Mục lục

Phần I — Foundations (Level 1)

ChươngNội dung chính
01 — Tại sao DDD ra đờiBusiness complexity là kẻ thù chính; vì sao thiết kế database-first, transaction script và CRUD thinking sụp đổ khi rule chồng chéo; accidental vs essential complexity; knowledge gap giữa dev và domain expert
02 — Domain và SubdomainCore / Supporting / Generic Domain; nhận diện lợi thế cạnh tranh; quyết định build–buy–outsource; “liều lượng DDD” theo từng vùng; hai case study phân rã domain (logistics, fintech)
03 — Ubiquitous LanguageChi phí dịch thuật vô hình; ngôn ngữ chung đi vào code thế nào; Event Storming; một từ nhiều nghĩa dẫn tới Bounded Context; quy ước song ngữ Việt–Anh cho team Việt

Phần II — Strategic Design (Level 3)

ChươngNội dung chính
04 — Bounded ContextVì sao Enterprise Model thống nhất luôn thất bại; ranh giới ngữ nghĩa; Bounded Context vs Subdomain (problem space vs solution space); Bounded Context ≠ microservice; Shared Database phá ranh giới thế nào
05 — Context MappingContext Map là công cụ quyền lực/tổ chức; đủ 9 pattern: Partnership, Shared Kernel, Customer/Supplier, Conformist, ACL, Open Host Service, Published Language, Separate Ways, Big Ball of Mud; code ACL đầy đủ TS + Go

Phần III — Tactical Design (Level 2)

ChươngNội dung chính
06 — Entity và Value ObjectIdentity vs equality by value; immutability; primitive obsession; Entity DDD ≠ entity ORM (TypeORM/GORM); refactor từ anemic sang rich model; chiến lược persistence mapping
07 — AggregateChương trọng tâm: consistency boundary = transaction boundary; xác định ranh giới từ invariant thật (không từ ERD); optimistic concurrency; giải phẫu God Aggregate từng bước; aggregate ≠ nhóm bảng, ≠ relations của ORM
08 — Repository và FactoryRepository là collection ảo của aggregate; interface ở domain, implementation ở infrastructure; Repository DDD ≠ repository của ORM; vì sao generic repository nguy hiểm; Factory và reconstitution; in-memory fake cho test
09 — Domain Service và Application ServiceLogic không thuộc entity nào thì ở đâu; orchestration vs business rule; giải phẫu một OrderService 500 dòng kiểu NestJS/Go và tách từng bước
10 — Domain EventSự kiện là quá khứ bất biến; Domain Event vs Integration Event; collect trong aggregate — publish sau persist; thiết kế payload; event versioning; eventual consistency có kỷ luật
11 — SpecificationBusiness rule dạng điều kiện có nhà; kết hợp and/or/not; ba công dụng và bài toán “dịch sang SQL”; khi nào specification là overkill

Phần IV — DDD và Kiến trúc (Level 3–4)

ChươngNội dung chính
12 — DDD và Kiến trúcLayered vs Hexagonal vs Onion vs Clean — bản chất chung là dependency inversion; cấu trúc thư mục cụ thể cho NestJS và Go; Modular Monolith là điểm khởi đầu đúng; Bounded Context là đơn vị chia microservice; distributed monolith
13 — DDD và Distributed SystemsEvent-driven Architecture; CQRS (hai mức, không bắt buộc kèm Event Sourcing); Saga — choreography vs orchestration, compensation; Outbox và bài toán dual-write; Event Sourcing — chi phí thật; Idempotency; vì sao 2PC chết

Phần V — Production (Level 4)

ChươngNội dung chính
14 — DDD trong ProductionRefactor legacy: strangler fig, bubble context, ACL bọc legacy; incremental adoption; Team Organization và Conway’s Law, team topologies, inverse Conway; Monolith First; lộ trình tách microservices; testing, versioning, migration dài hạn

Phần VI — Case Study 8 ngành

ChươngNội dung chính
15a — E-commerce, FinTech, Banking, LogisticsMỗi ngành: phân rã domain và lý do, context map, aggregate chủ chốt với invariant cụ thể (Order, Ledger double-entry, Shipment…), luồng event chính, trade-off và các lỗi thiết kế đặc thù
15b — SaaS, Blockchain, Booking, Social NetworkTenant isolation ba tầng chốt; ledger off-chain và ranh giới với on-chain; chống double-booking bằng reservation pattern; fan-out và ModerationCase; bảng so sánh bốn thái cực nhất quán

Phần VII — Tổng kết

ChươngNội dung chính
16 — Anti-patterns & Khi nào KHÔNG nên dùng DDD11 anti-pattern với cách nhận biết trong code thật và cách sửa; bảng “khi nào không dùng DDD” với phương pháp thay thế; ma trận quyết định liều lượng; checklist 10 câu; tổng kết toàn bộ và lộ trình đọc tiếp

Ba lộ trình đọc gợi ý

Đọc tuần tự (khuyên dùng cho lần đầu) — 01 → 16: mạch lập luận được thiết kế nối tiếp, khái niệm sau đứng trên khái niệm trước.

Lộ trình cho người cần tactical ngay (đang phải thiết kế module tuần này): 01 (đọc nhanh) → 06 → 07 → 08 → 09 → 10 → 16. Cảnh báo: tactical không có strategic dễ thành cargo cult — quay lại phần II sớm nhất có thể.

Lộ trình cho Tech Lead / Architect (quyết định ranh giới hệ thống và tổ chức team): 01 → 02 → 03 → 04 → 05 → 12 → 13 → 14 → 16, case study (15a/15b) chọn ngành gần với hệ thống của bạn.

Quy ước chung của toàn bộ tài liệu

Thuật ngữ DDD giữ tiếng Anh, phần giải thích bằng tiếng Việt. Diagram dùng Mermaid (đọc tốt trên GitHub/GitLab/Obsidian). Code TypeScript mặc định trong bối cảnh NestJS, code Go theo bố cục internal/<context>/domain|app|infra. Các ví dụ ngành (tiền tệ VND, COD, đối soát…) lấy từ bối cảnh sản phẩm Việt Nam có chủ đích — để bạn mang thẳng vào cuộc họp với domain expert của mình.