Domain Services vs Application Services in Domain-Driven Design

By Levon Zhang

Domain-Driven Design (DDD) introduces the concepts of Domain Services and Application Services to handle complex business logic and application operations. Understanding the distinction and roles of these services is key to applying DDD effectively.

What are Domain Services?

Domain Services encapsulate business logic that doesn’t naturally fit within a domain object. These services are part of the domain layer and are used to implement operations that span multiple entities or value objects.

Characteristics of Domain Services

  • Stateless: They do not hold state.
  • Business Logic: Contain business logic that is not a natural part of an entity or value object.
  • Side-effect Free: Ideally, methods in domain services should not have side effects.

What are Application Services?

Application Services act as a coordinator or a facade for the domain layer. They orchestrate the flow of data to and from the domain entities and may also involve infrastructure concerns like transactions, logging, security, etc.

Characteristics of Application Services

  • Coordination: They coordinate tasks and delegate work to domain services or domain entities.
  • Infrastructure Concerns: Handle transaction management, security, and other application-specific concerns.
  • Thin Layer: Typically do not contain business logic but instead coordinate the invocation of domain services.

Differences Between Domain and Application Services

  • Scope of Responsibility: Domain services handle business logic, while application services handle application-level operations.
  • State Handling: Domain services are stateless and focus on business rules, whereas application services can manage application state and orchestrate domain operations.
  • Layer: Domain services are in the domain layer, while application services are in the application layer.

Example in an E-commerce System

Scenario

In an e-commerce system, the process of placing an order involves several steps like validating order details, calculating the total price, and updating inventory.

Implementation

  • Domain Service (OrderService): Handles order validation and calculation logic.
  • Application Service (OrderApplicationService): Coordinates the order placement process, including calling the OrderService and interacting with repositories.
class OrderService:
    @staticmethod
    def validate_order(order):
        # Validate order details
        pass

    @staticmethod
    def calculate_total(order):
        # Calculate total price
        return total

class OrderApplicationService:
    def __init__(self, order_repository, inventory_repository):
        self.order_repository = order_repository
        self.inventory_repository = inventory_repository

    def place_order(self, order):
        if OrderService.validate_order(order):
            total = OrderService.calculate_total(order)
            order.set_total(total)
            self.order_repository.save(order)
            # Update inventory
            self.inventory_repository.update(order)

In this example, OrderService (a domain service) handles the business logic, while OrderApplicationService (an application service) orchestrates the order placement process, interfacing with the domain and infrastructure layers.


Understanding the distinction between domain and application services is crucial for structuring DDD-based applications effectively, ensuring that business logic and application operations are well-organized and maintainable.

Share: Twitter Facebook LinkedIn