View Model

View Model thực chất là một kiểu đặc biệt của Read Model, được dùng để đóng gói dữ liệu sẵn sàng cho View/UI hoặc API. Có thể coi như một DTO (Data Transfer Object) chứa đúng định dạng và kiểu dữ liệu mà giao diện cần.

🖼️ Mục đích

  • Giảm logic định dạng trong view.
  • Tách bạch việc chuyển đổi dữ liệu ra khỏi controller.
  • Chỉ chứa những gì giao diện cần, ở dạng nguyên thủy (string, number) để dễ render / serialize.

📄 Ví dụ: View Model cho HTML

EbookViewModel với title, formattedPrice, authorName… (tất cả kiểu string) để đưa thẳng vào template. Controller gọi EbookViewRepository->listAll() nhận danh sách EbookViewModel đã có sẵn dữ liệu định dạng (giá đã format tiền tệ).

🌐 Ví dụ: View Model cho JSON API

Thay vì trả Order entity (chứa nhiều dữ liệu thừa và phương thức business), thiết kế OrderListViewModel chỉ gồm orderId, orderDate, customerName, totalAmount… - chỉ thông tin cần hiển thị:

// OrderListViewRepository
public function findRecentOrders(int $limit): array; // trả OrderListViewModel[]
  • Implement có thể chạy JOIN phức tạp nhiều bảng (orders, customers, payments) nhưng gói kết quả vào view model đơn giản.
  • Mỗi OrderListViewModel tự cung cấp toArray() hoặc implement JsonSerializable để dễ chuyển thành JSON.
  • Kết quả JSON trả về đúng các trường API yêu cầu, không thừa không thiếu, và hoàn toàn tách khỏi cấu trúc nội tại của domain (domain có thể có field nhạy cảm như internal notes → view model bỏ qua).

💡 Chốt lại

Tách Read Model/View Model khỏi Write Model giúp giảm coupling giữa phần hiển thị và nghiệp vụ, tăng hiệu năng truy vấn, và giữ domain model gọn gàng. Đây là con đường dẫn tới CQRS - Command Query Responsibility Segregation.

Liên quan