Read Model
Read Model là mô hình dữ liệu chuyên phục vụ thao tác đọc / tra cứu. Thay vì trả về Domain Entity “đủ thứ” rồi chỉ dùng một ít, read model cung cấp đúng và chỉ dữ liệu cần cho màn hình hoặc báo cáo cụ thể.
⚠️ Vấn đề khi dùng Entity cho mục đích đọc
Tái sử dụng entity của write model để đọc/hiển thị là sai lầm phổ biến:
- Trao quyền không cần thiết cho tầng hiển thị. Entity mang theo hàng loạt phương thức thay đổi trạng thái (
Ebook->changePrice(),Ebook->hide()). Tầng view chỉ cần đọc nhưng lại có thể vô tình gọi nhầm → vi phạm nguyên tắc “chỉ cung cấp cho client những gì nó thực sự cần”. - Model phình to, khó bảo trì. Một class vừa dùng để ghi (write) vừa đọc (read) phải gánh hai vai trò → thêm nhiều thuộc tính/phương thức phục vụ cả hai → dần trở thành code legacy với phụ thuộc chằng chịt.
Nguyên tắc: tách biệt mô hình ghi (write model) và mô hình đọc (read model). Phần thay đổi trạng thái dùng entity/aggregate thiết kế cho nghiệp vụ; phần chỉ hiển thị dùng mô hình nhẹ hơn, tối ưu cho truy vấn.
🛠️ Cách triển khai
- Class + repository riêng cho read model: vd
EbookReadModel(chỉid,title,price) vàEbookReadRepositoryvớifindById()trảEbookReadModel. - Đơn giản nhất: nếu chỉ cần một giá trị, khỏi cần class riêng - repository trả kiểu nguyên thủy (vd interface
GetPricevớiofEbook(EbookId): int). - Nâng cao (CQRS): duy trì cơ sở dữ liệu/cấu trúc lưu trữ riêng cho việc đọc, cập nhật mỗi khi write model đổi (qua Domain Event) - tối ưu hiệu năng đọc nhưng phức tạp hơn vì phải đồng bộ. Xem CQRS - Command Query Responsibility Segregation.
Trong phạm vi sách: cách đơn giản là dùng chung database nhưng lớp repository riêng cho read model (vd SqlEbookReadRepository chạy SELECT price FROM ebooks WHERE id = ?).
Liên quan
- View Model - một kiểu đặc biệt của read model, cho UI/API
- CQRS - Command Query Responsibility Segregation - kiến trúc tách đọc/ghi
- Repository Pattern
- Domain Entity - write model, đối lập với read model