Command Object và DTO
⚠️ Đừng nhầm với Command Pattern của GoF. Ở đây “Command” được hiểu là Command Object / DTO (Data Transfer Object) - một class đơn giản gom toàn bộ input của một use case thành một đối tượng duy nhất, để truyền vào Application Service. (Nó gần với “command” trong CQRS - Command Query Responsibility Segregation hơn là pattern đóng gói-hành-động của GoF.)
📦 Ý tưởng
Thay vì truyền hàng loạt tham số rời rạc vào phương thức service, ta tạo một class biểu thị yêu cầu người dùng muốn thực hiện:
$command = new PlaceOrderCommand(
$request->get('customer_id'),
$request->get('items'),
$request->get('email'),
);
$orderId = $placeOrderService->handle($command);- Tên class diễn đạt ý định nghiệp vụ:
PlaceOrderCommand,CreateOrderCommand- “người dùng muốn tạo một đơn hàng mới”. - Constructor yêu cầu đủ thông tin → command luôn hợp lệ khi được tạo.
- Chứa các thuộc tính + getter (
customerId,items,email…).
✨ Lợi ích
- Code gọn gàng, truyền tải ý định rõ ràng - một đối tượng thay vì mớ tham số.
- Tách tầng web khỏi tầng ứng dụng. Controller chịu trách nhiệm chuyển đổi từ chi tiết giao thức (HTTP) sang command. Muốn thêm kênh mới (CLI, API mobile) → chỉ cần dựng
PlaceOrderCommandtương ứng, không nhân đôi logic. - Dễ validate và kiểm thử. Có thể kiểm tra tính hợp lệ của command trước khi đưa vào service (lớp Validator riêng). Trong unit test, tạo một
PlaceOrderCommandmẫu + inject mock repository → gọihandle(), không cần dựng request giả hay môi trường web.
🔗 Bức tranh tổng
Data vào được gói trong command, logic xử lý nằm trong Application Service, data ra trả về dạng đơn giản (value object hoặc View Model). Controller/handler chỉ còn nhiệm vụ chuyển đổi dữ liệu và gọi dịch vụ.
Liên quan
- Application Service - nơi nhận và xử lý command
- Command Pattern - pattern GoF cùng tên nhưng KHÁC mục đích
- CQRS - Command Query Responsibility Segregation - “command” phía ghi
- View Model - DTO ở chiều ra (đọc)