Should the Domain ever access Application Services of another system?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
When building a software system, particularly one based on the principles of Domain-Driven Design (DDD), one key design decision revolves around the interaction and dependency between various components and layers, specifically the domain and application layers and how they connect with external systems. Understanding whether, and when, a domain should directly access application services of another system is crucial for maintaining a clean, scalable, and maintainable codebase.
Understanding Domain and Application Layers
- Domain Layer: This layer is at the heart of business software, focusing on encapsulating and representing business concepts, information about the business situation, and business rules. The domain model layers strictly the logic and rules associated with these business elements.
- Application Layer: This acts as a set of services that orchestrates how domain objects interact with each other or external requests to fulfill the purposes of the application. It doesn't contain business rules or knowledge, but controls the workflow in which the domain objects are used.
Principles to Consider
- Separation of Concerns: Each layer of an application should be responsible for a specific role. Mingling domain logic with application services dilutes the responsibilities, making the system harder to maintain and evolve.
- Single Responsibility Principle: A module, class, or function should have one, and only one, reason to change. This principle helps in building a more robust and predictable system.
- Interface Segregation: Clients should not be forced to depend upon interfaces they do not use. This principle helps in designing fine-grained interfaces that are client specific.
Accessing Application Services of Another System
Directly accessing application services of another system from the domain layer can lead to various issues:
- Coupling: Your domain logic becomes tightly coupled with another system's application logic, leading to scenarios where changes in one system require changes in another.
- Layer Violation: Direct interaction between a domain and external application services bypasses the natural layers of abstraction, violating the separation of concerns.
- Scalability and Maintenance Issues: With direct dependency, scaling and maintaining applications can become cumbersome due to the increased complexity and tight coupling.
When Interaction is Necessary
There are situations where one system's domain layer might need the data or capability provided by another system’s application layer. In such cases, adhere to the following guidelines:
- Use Anti-Corruption Layer (ACL): Implement an ACL to act as a translator between systems. This layer will buffer your domain from any direct dependencies on external models or designs.
- Design Pattern Utilization: Use design patterns like Dependency Injection (DI) to maintain cleanliness in architecture. This can allow injecting services in a controlled way.
- Domain Events: These can help in facilitating interactions between different systems in a loosely coupled manner. Systems can listen to events they are interested in and respond accordingly, instead of being called directly.
Technical Example
Consider a scenario in a financial application where user information is required from an identity management system to process transactions:
In this example, TransactionProcessor needs user data to process the transaction but does not need to know where and how it is stored and manipulated.
Summary Table
| Aspect | Direct Access | Indirect Access |
| Coupling | High | Low |
| Separation of Concerns | Violated | Maintained |
| Scalability & Maintenance | Difficult | Easier |
| Dependency Management | Complex | Simplified |
Conclusion
While in some cases accessing application services directly from the domain may seem like the simplest way to get something done, it is usually not advisable due to the potential pitfalls in terms of maintainability, scalability, and software design principles. Utilizing techniques such as ACLs, domain events, and proper dependency management can facilitate necessary interactions without compromising the system architecture.

