DDD: Phần 10 – Design Heuristics – Chiến lược & chiến thuật

🧭 Design Heuristics là gì?

Heuristic là quy tắc kinh nghiệm – không đảm bảo đúng trong 100% trường hợp, nhưng đủ hiệu quả để đưa ra quyết định trong tình huống cụ thể.

Nếu bạn dịch từ “Heuristics” trong tiếng Anh – nó còn có ý nghĩa: Phương pháp thử – sai, rút kinh nghiệm dần, hoặc chiến lược giải quyết vấn đề dựa trên kinh nghiệm hoặc trực giác thay vì phân tích toàn bộ dữ liệu.

💡 Thay vì bị choáng ngợp bởi nhiều yếu tố mâu thuẫn, heuristics giúp ta tập trung vào những tín hiệu quan trọng nhất để giải quyết vấn đề thiết kế phần mềm.

Xem lại phần 9 tại: https://minhphien.com/ddd-phan-9-series-communication-patterns-trong-domain-driven-design/


📦 1. Bounded Context: Nên rộng hay hẹp?

“Nên chia bounded context càng nhỏ càng tốt?” → Không hẳn!

🎯 Heuristic:

  • Không tối ưu kích thước mà tối ưu mô hình nghiệp vụ.
  • Thay đổi chéo context = thiết kế kém hiệu quả → Cần nhiều phối hợp, tạo techdebt.
  • Bắt đầu rộng → thu hẹp dần khi hiểu rõ hơn về domain.

📌 Gợi ý:

  • Nếu là core subdomain → nên gộp cả các subdomain liên quan để dễ thay đổi và phản ứng với yêu cầu mới.
  • Supporting hoặc Generic subdomain thường ổn định hơn, không cần rào chắn rộng.

🧠 2. Mô hình hoá logic nghiệp vụ – Pattern nào phù hợp?

🧮 Các mẫu có thể chọn:

  • Transaction Script: đơn giản, ít tầng, tốt cho logic sơ khai.
  • Active Record: khi có cấu trúc dữ liệu phức tạp nhưng logic vẫn đơn giản.
  • Domain Model: dành cho logic nghiệp vụ phức tạp, nhiều quy tắc.
  • Event-Sourced Domain Model: phù hợp với hệ thống cần audit, tracking, deep analysis.

📍Heuristic thêm:

  • Nếu thấy subdomain là core mà pattern phù hợp lại là Transaction Script → Xem lại nhận định.
  • Hoặc subdomain là supporting nhưng lại dùng Domain Model → Có thể đã phân loại sai.

🏗️ 3. Chọn Architectural Pattern nào?

✨ Kết nối mô hình logic với kiến trúc phù hợp:

Business Logic PatternArchitecture Pattern
Event-Sourced Domain ModelCQRS
Domain ModelPorts & Adapters
Active RecordLayered Architecture
Transaction ScriptMinimal Layered Architecture

Cây quyết định Business Logic Pattern:

Cây quyết định Architecture Pattern:

👉 CQRS cũng có thể dùng cho các mô hình khác nếu cần nhiều mô hình lưu trữ dữ liệu khác nhau.


🧪 4. Testing Strategy phù hợp

PatternTesting Strategy
Domain Model, Event-SourcedTesting Pyramid → chủ yếu Unit Test
Active RecordTesting Diamond → Integration Test quan trọng
Transaction ScriptReversed Pyramid → End-to-End test nhiều nhất

Khi đã chọn được pattern để triển khai business logicpattern kiến trúc, chúng ta có thể sử dụng những lựa chọn này như heuristics (quy tắc kinh nghiệm) để lựa chọn chiến lược kiểm thử phù hợp.

📊 Ba chiến lược kiểm thử chính:

1. 🧱 Testing Pyramid – Kim tự tháp kiểm thử

  • Đặc điểm:
    • Nhiều unit test
    • Ít integration test
    • Rất ít end-to-end test
  • Áp dụng tốt nhất cho:
    • Mô hình Domain Model (cả dạng chuẩn và dạng event-sourced).
  • Lý do:
    • Các AggregatesValue Objects rất phù hợp để kiểm thử đơn vị.
    • Logic nghiệp vụ được đóng gói tốt nên dễ kiểm soát.

2. 💎 Testing Diamond – Hình kim cương

  • Đặc điểm:
    • Tập trung nhiều nhất vào integration test
    • Cân bằng giữa unit và end-to-end test
  • Áp dụng tốt nhất cho:
    • Mô hình Active Record
  • Lý do:
    • Logic nghiệp vụ nằm rải rác giữa service layer và business object → cần kiểm thử khả năng tích hợp nhiều hơn.

3. 🔺 Reversed Testing Pyramid – Kim tự tháp ngược

  • Đặc điểm:
    • Tập trung mạnh vào end-to-end test
    • Rất ít unit test
  • Áp dụng tốt nhất cho:
    • Mô hình Transaction Script
  • Lý do:
    • Hệ thống có logic đơn giản, ít lớp → kiểm thử end-to-end toàn bộ dòng xử lý sẽ hiệu quả hơn.

🧠 5. Tactical Design Decision Tree – tổng hợp

Kết hợp tất cả các yếu tố:

  • Phân loại subdomain.
  • Độ phức tạp của business logic & dữ liệu.
  • Yêu cầu audit, analytics, tracking.
  • Pattern tương ứng.
  • Testing tương ứng.

→ Đưa vào một decision tree tổng thể giúp chọn đúng mô hình.

Ghi chú quan trọng:
Những sơ đồ và quy tắc này là heuristics, không phải luật cứng nhắc. Chúng giúp khởi đầu tốt, nhưng không nên thay thế cho tư duy phản biện. Có trường hợp ngoại lệ, thậm chí có team dùng event-sourced model cho tất cả subdomain vì họ quen tay — điều đó cũng không sai, nếu phù hợp với năng lực và bối cảnh.


📌 Bài tập áp dụng:

🐺 WolfDesk Ticket Lifecycle (Core Subdomain, cần audit và analytics)

→ ✅ Event-Sourced Domain Model + CQRS + Unit Tests

👩‍💻 Shift Management Module (Supporting Subdomain)

→ ✅ Active Record + Layered Architecture + Integration Tests

🌍 Tích hợp API ngày nghỉ công (Generic Subdomain)

→ ✅ Transaction Script + Layered + End-to-End tests


🧠 “Heuristics giúp ta có điểm bắt đầu tốt, nhưng không thay thế cho tư duy phản biện.”

Để lại một bình luận