Application Service

Application Service (dịch vụ ứng dụng) là lớp thuộc Tầng Application, chịu trách nhiệm điều phối một use case cụ thể - không chứa logic hạ tầng và có thể gọi từ nhiều “entry point” khác nhau (web, CLI, test, job queue).

🎯 Tách logic use case khỏi Controller

Trong web truyền thống, controller vừa nhận request, vừa xử lý nghiệp vụ, vừa lưu DB, vừa trả response → Controller phình to, trộn logic use case với mã HTTP.

Giải pháp (áp dụng Separation of Concerns): đưa logic use case ra khỏi controller, gói vào một Application Service riêng.

Ví dụ use case “Place Order”: xác thực input, kiểm tra tồn kho, tạo Order, lưu qua repository, gửi email xác nhận. Trích ra PlaceOrderService → gọi được từ bất kỳ đâu (job queue, lệnh artisan…) mà không phụ thuộc Request/Session của web.

Controller lúc này mỏng đi: nhận request → tạo Command Object và DTO → gọi service → xử lý phản hồi.

🧩 Vai trò trong luồng

final class PlaceOrderService
{
    public function __construct(
        private OrderRepository $orderRepo,      // inject qua constructor (DI)
        private ProductRepository $productRepo,
    ) {}
 
    public function handle(PlaceOrderCommand $cmd): OrderId
    {
        $product = $this->productRepo->getById($cmd->productId());
        if (!$product->isInStock($cmd->quantity())) throw new OutOfStockException();
 
        $orderAmount = $product->price()->multiply($cmd->quantity());
        $order = Order::create($this->orderRepo->nextIdentity(), $cmd->customerId(), $product, $cmd->quantity(), $orderAmount);
        $this->orderRepo->save($order);
        // (gửi email / phát domain event)
        return $order->id();
    }
}

📌 Đặc điểm

  • Không truy cập Request/Session - chỉ làm việc với dữ liệu thuần từ command và các thành phần domain/infra đã được inject.
  • Không chứa logic nghiệp vụ chi tiết - phần lớn quy tắc đã ở domain. Nếu service bắt đầu nhiều tính toán → cân nhắc đẩy xuống Domain Service hoặc entity.
  • Xử lý transaction & điều phối: mở/commit transaction, gọi nhiều service con nếu cần (vai trò facade/orchestrator).
  • Dùng Dependency Injection thay vì Service Locator → dễ test (inject mock).

Liên quan