16.6 — 5. DDD chiến thuật (vừa đủ cho backend)
Mục tiêu bài học
- Nắm được ý chính của bài và mối liên hệ với module.
- Áp dụng được kiến thức vào bối cảnh CRM/.NET backend.
- Sẵn sàng chuyển sang bài kế tiếp với nền tảng chắc chắn.
Nội dung bài học
Không cần “full DDD ceremony” ngay ngày đầu. Tập trung:
16.6.1 — 5.1 Entity so với Value Object
- Entity: có định danh (
LeadId), đời sống thay đổi theo thời gian. - Value Object: không có identity, bất biến (
Money,EmailAddress) — so sánh theo giá trị.
public readonly record struct Money(decimal Amount, string Currency)
{
public Money Add(Money other)
{
if (Currency != other.Currency)
throw new InvalidOperationException("Không cộng khác currency.");
return new Money(Amount + other.Amount, Currency);
}
}
16.6.2 — 5.2 Aggregate & invariant
Aggregate là cụm entity có một root — mọi thay đổi invariant đi qua root.
Ví dụ: Order (root) chứa OrderLine; không cho phép service ngoài add line trực tiếp bypass rule tồn kho.
16.6.3 — 5.3 Repository (domain-facing)
Repository là collection ảo trong domain language: ILeadRepository.GetByIdAsync, không lộ IQueryable ra application nếu muốn giữ domain độc lập ORM.
16.6.4 — 5.4 Bounded context
Trong CRM: Sales (Lead, Opportunity) khác ngôn ngữ với Billing (Invoice, Payment). Cùng từ “Account” có thể khác nghĩa — tách model, đừng ép một bảng “quá tổng quát”.
Bài tập áp dụng
- Tóm tắt bài học bằng ngôn ngữ của bạn.
- Liên hệ nội dung với một tình huống thực tế trong dự án.
- Đề xuất một cải tiến cụ thể sau khi học bài này.
Tự kiểm tra
- Bạn có thể giải thích lại nội dung chính trong 2 phút không?
- Bạn có ví dụ áp dụng thực tế chưa?
- Bạn biết bước tiếp theo cần học/triển khai là gì không?
Kết luận
Hoàn thành bài này giúp bạn có góc nhìn đầy đủ hơn trước khi đi tiếp trong module.
Điều hướng
- Bài trước: 16.5 — 4. Vertical Slice Architecture (VSA)
- Bài tiếp theo: 16.7 — 6. MediatR — pipeline cho use case
- Về module: Trang mục lục