Definition: Domain services are specialized components in software design that encapsulate business logic not naturally belonging to a specific object or entity.
Role in DDD (Domain-Driven Design): In Domain-Driven Design, domain services represent business operations that involve multiple entities or value objects.
Not Bound to One Entity: They handle actions that span across multiple domain objects, instead of being tied to just one.
Stateless: Most domain services are stateless. They don’t hold any persistent data internally.
Business Logic Holder: If a business rule doesn’t clearly belong to a single entity, it goes into a domain service.
Naming Convention: Their names usually end with a verb or describe an action, e.g., InvoiceGenerator, PaymentProcessor.
Examples of Domain Services:
Transferring money between two bank accounts.
Calculating shipping fees for an order.
Sending confirmation emails after order placement.
Difference from Application Services: Domain services are part of the business layer, while application services coordinate application-level tasks like calling APIs or user interfaces.
Communication with Entities: Domain services often use and manipulate entities to complete business operations.
Interface Implementation: A domain service can be defined by an interface and implemented by a concrete class.
Injectable: Domain services are typically injected using dependency injection in modern frameworks.
Testable: Due to their stateless nature, they are easy to unit test.
Focus on Behavior: They focus on what the system does, not what it stores.
Part of Ubiquitous Language: Their naming and structure should reflect the business language used in the domain.
Do Not Handle Persistence: Domain services do not directly manage data access or databases; that is handled by repositories.
Example Use Case: In an e-commerce platform, calculating discounts based on multiple conditions is often done in a domain service.
Keeps Entities Clean: By putting complex operations into domain services, the design keeps entity classes simpler and focused.
Single Responsibility Principle: Domain services usually do one thing well, aligning with good software design principles.
Pure Functions: In some cases, domain services behave like pure functions, returning output based on input without side effects.
Usage in Layers: Domain services sit in the domain layer of a layered architecture and should not depend on infrastructure or UI code.
Bridge Between Entities and Rules: They act as a bridge to enforce rules across multiple business objects.
Can Be Internal or Public: Depending on the structure, domain services can be used within the domain or exposed to the application layer.
Improves Reusability: Common operations shared between entities can be reused through domain services.
Good for Complex Logic: When logic doesn’t clearly belong to a single entity, domain services are the right place.
Encapsulation of Logic: They encapsulate domain-specific knowledge without tying it to data models.
Flexible and Extendable: They can be extended or modified without affecting the entities themselves.