Strategic Domain-Driven Design
Business Domain Analysis
In Domain-Driven Design, a business domain is the specific area of expertise, activity, or knowledge that a business specializes in. It includes the key concepts, rules, processes, and logic that shape how the business operates and what it offers. Essentially, the business domain represents the real-world context and challenges that the software is meant to address.
A company's market presence is defined by its business domain, which encompasses its core activities and the services it provides to clients. Depending on factors such as company size and whether they operate nationally or internationally, firms may have one or multiple business domains.
The company's business domain is too complex to be managed within a single unit or domain. Additionally, to support domain modeling, establish proper ubiquitous language, and align with the business strategy, we need to divide the company's business domain into smaller segments.
Domain-Driven Design distinguishes between three types of subdomains:
Core Subdomain
The term The term Core Subdomain refers to the most critical aspect of a software system, which embodies the primary value the software provides. It is the defining element that distinguishes a company, representing the essence of its business operations. For example, in a company specializing in firewall manufacturing, the core domain would include key components like the packet processing module and the policy engine, depicted in the orange block in the figure above. These core domains are what differentiate the company from its competitors.
The Core Subdomain, an intricate part of Domain-Driven Design, is developed and maintained internally by the company's team. It should not be outsourced or bought from third-party vendors. While core subdomains are essential, they are not capable of independently solving problems or delivering services to clients. They require integration with other domains and subdomains to create a comprehensive and effective solution.
In Domain-Driven Design, identifying and clearly understanding the core subdomain is crucial, as it helps allocate resources effectively, ensuring that the most critical aspects of the software receive the necessary attention and expertise. A well-defined core subdomain also facilitates better communication among development teams, stakeholders, and business experts, fostering a shared understanding of the system's primary value.
Generic Subdomain
Generic subdomains refer to business activities that are generally performed in a similar manner across various companies. From a technical standpoint, these subdomains are highly complex to implement, making it advisable for companies to avoid developing them in-house. Instead, they should consider using third-party solutions.
Examples of generic subdomains include user authentication and authorization, as well as firewalls that require a Deep Packet Inspection (DPI) engine to analyze data packets. Due to the complexity involved, many companies choose to adopt existing market solutions for such needs. In the diagram above, generic subdomains are represented in blue.
It is important to note that these subdomains do not provide any competitive advantage. This lack of differentiation, combined with the complexity of their implementation, makes it practical to outsource these functions to specialized third-party providers. By leveraging third-party solutions for these subdomains, companies can focus their internal resources and development efforts on core subdomains that drive competitive differentiation and innovation.
Supporting Subdomain
Unlike the other two subdomains, Supporting Subdomains are relatively simple and can be outsourced for development and maintenance. For instance, in the context of a firewall, there are various supporting subdomains that can also be considered software features, such as Intrusion Prevention Systems (IPS) and Data Loss Prevention (DLP). It is often more efficient to outsource these features to third-party providers. These supporting subdomains are represented by the yellow components in the figure above.
Supporting Subdomains are essential, but they do not contribute directly to the core business's unique value proposition. Their primary role is to facilitate the operation of core subdomains by handling ancillary tasks. By outsourcing these subdomains, organizations can focus their internal resources on developing and refining Core Subdomain that directly impacts their competitive advantage.
Outsourcing Supporting Subdomains to specialized third-party providers also ensures that these features are built and maintained by experts in the field, leveraging the latest technology and industry best practices. This approach not only reduces the burden on internal teams but also improves the overall quality and security of the product, allowing organizations to deliver a more robust solution to their customers.
Team Topologies for Subdomains
In the framework of Team Topologies, Stream-Aligned Teams are focused on Core Subdomains. These teams are structured to support specific business processes or capabilities, ensuring that their work aligns with the core functions of the organization.
Platform Teams, on the other hand, manage Generic Subdomains. Their role is to develop and maintain the underlying infrastructure and services that support various aspects of the software ecosystem, ensuring smooth integration and operation.
Supporting Subdomains are generally managed by Enabling Teams. These teams, composed of specialists, assist Stream-Aligned Teams by providing expertise and support to enhance their effectiveness and efficiency.
Additionally, Team Topologies emphasizes the importance of clearly defining team responsibilities and interactions. Stream-Aligned Teams benefit from well-structured collaboration with Enabling Teams, which helps to address obstacles and optimize processes. Meanwhile, Platform Teams play a crucial role in providing the necessary tools and infrastructure to support the core functions of the organization, ensuring that Stream-Aligned Teams can focus on delivering value without being bogged down by underlying technical complexities.
For more information about Team Topologies, take a look at the article, Leveraging Team Topologies in Domain-Driven Design for Effective Software Transformation.
Ubiquitous Language
During software development, from managing customer requirements to launching the product in the market, each team and domain often uses its own specialized language to communicate internally. For example, the term "pattern" might have different meanings for the development team compared to the domain experts.
When each group has its own understanding and definition of the same word or expression, it becomes necessary to establish a common language among all parties to facilitate communication. Without this common language, teams must translate the messages they receive from others to make them understandable, usable, and applicable within their own context, whether it be a specific group, domain, or team. This translation process can hinder the efficiency and performance of workflows.
This shared language is known as Ubiquitous Language. By using a ubiquitous language, assumptions about business requirements are minimized, and ambiguities can be eliminated. This ensures that all parties involved share a common understanding, which enhances collaboration and alignment.
It bridges the gap between technical and non-technical stakeholders, enabling them to communicate effectively. By maintaining a consistent vocabulary, the development process becomes more transparent and focused, leading to more accurate implementation of the business requirements.
Last but not least, It allows all stakeholders, from developers to business experts, to speak the same language, thereby reducing miscommunication and fostering a more collaborative environment.
Bounded Context
The concept of ubiquitous language refers to a shared understanding of terminology and concepts within a business domain that all parties in a company can agree upon. However, different departments or teams may have varying levels of complexity associated with these terms.
For instance, in the context of our firewall project, the development team’s understanding of AI/ML is far more complex than that of the marketing team. To adhere to the principles of ubiquitous language, we could either simplify the development team's language or introduce the development team's complexity to the marketing team. The former could lead to the business goals not being met effectively, while the latter could overwhelm the marketing team with unnecessary complexity.
To address this challenge, the ubiquitous language must be defined within specific boundaries and with a more granular context. In other words, the ubiquitous language should be divided into smaller, context-specific languages that are only relevant within certain boundaries. This boundary is known as a Bounded Context, which outlines the scope within which the ubiquitous language is applicable.
Bounded Contexts ensure that the language remains functional and efficient by avoiding the pitfalls of trying to establish a universal language across the entire organization. Instead, each Bounded Context allows for a tailored language that aligns with the needs and complexities of specific teams or domains, facilitating clearer communication and more effective collaboration.
Context Map
A bounded context represents a specific business domain, with its own language and rules. Each bounded context must effectively communicate with other contexts to ensure mutual understanding. The connections and interactions between these different business domains are referred to as a Context Map. In this section, we will explore the most commonly used patterns in creating and managing a Context Map.
In Domain-Driven Design, a Context Map provides a clear view of the relationships, dependencies, and communication paths between domains, ensuring that the overall architecture remains coherent and aligned with business objectives.
Partnership Pattern
In this approach, the two bounded contexts maintain a close, interdependent relationship. They engage in bidirectional cooperation, meaning they rely on and support each other mutually. It means this pattern creates a more cohesive and effective architecture that can adapt to change and evolve over time.
Shared Kernel Pattern
The Shared Kernel Pattern in strategic Domain-Driven Design is applied when a specific portion of a subdomain is implemented across multiple bounded contexts. This typically happens when certain code or functionality needs to be shared between subdomains, whether to prevent code duplication or to uphold the DRY (Don't Repeat Yourself) principle. By creating a shared kernel, different teams or areas of a system can collaborate and share this core logic without duplicating efforts, ensuring consistency across the system.
Conformist Pattern
The Conformist pattern is the first of the three Customer-Supplier patterns in our discussion. It emerges when an upstream subdomain, serving as a supplier, is either unable or unwilling to accommodate the communication needs of a downstream subdomain, which functions as a customer.
In such cases, the downstream subdomain must adapt to the upstream’s conditions in order to interact effectively. This results in a communication style where the downstream subdomain conforms to the constraints set by the upstream.
Anti-corruption Layer Pattern
The ACL pattern is the second of three Customer-Supplier patterns in our strategic Domain-Driven Design approach. Rather than conforming to the upstream bounded context, the downstream subdomain establishes a translation layer to mediate communication with its own domain model. This intermediary layer, known as the Anti-corruption Layer, serves to protect the downstream subdomain from being influenced or compromised by the upstream domain, ensuring that its internal model remains clear and autonomous.
The use of an ACL is especially beneficial when the downstream subdomain is a core domain, or when the upstream bounded context represents a legacy system that is impractical to conform to.
Open-Host Service Pattern
The OHS pattern is the third of the three Customer-Supplier patterns in strategic Domain-Driven Design. In this pattern, the upstream subdomain (supplier) provides a well-defined public interface that is separate from its internal implementation. By doing so, it shields downstream systems (customers) from the impact of any changes made within its internal workings.
This separation ensures that customers can interact with the upstream service without being affected by modifications in the supplier's implementation model, maintaining stability and reducing dependency on the supplier’s internal structure.
The key advantage of the Open-Host Service pattern is that it promotes flexibility and longevity in software architecture.
Real World Scenario
In the strategic domain-driven design, the Open-Host Service (OHS) pattern and the Anti-Corruption Layer pattern often work in tandem to facilitate communication between two systems, such as a customer and a supplier. In our real-world scenario, the supplier utilizes the OHS pattern to expose its internal domain language through a RESTful API. This allows the supplier to share its services and capabilities in a standardized, open format. On the other side, the customer employs the ACL pattern to interpret the incoming messages and commands, translating the supplier's language into a form that the customer’s system understands. This solution shields the customer from any complexities or inconsistencies in the supplier's domain language.
The same process works in reverse when the customer needs to communicate with the supplier. The customer sends messages in its own domain language, which the ACL then translates into the language understood by the supplier. This bidirectional flow of communication, enabled by OHS and ACL, ensures that both parties can operate independently while interacting seamlessly, without being burdened by each other's internal models or terminology.
Wrapping Up
Strategic Domain-Driven Design provides a powerful framework for aligning software systems with complex business goals. By focusing on the business domain first, organizations can better understand and model the core problems they are solving, leading to more effective software solutions. The detailed analysis of the domain helps to identify key areas of complexity, strategic priorities, and where the most value can be delivered. This understanding lays the foundation for the application of DDD, ensuring that software development is deeply rooted in real business needs and objectives.
The use of Ubiquitous Language and Bounded Contexts further strengthens this alignment. Ubiquitous Language bridges the gap between technical and non-technical stakeholders, creating a shared vocabulary that reflects the nuances of the domain, reducing misunderstandings and fostering collaboration. Bounded Contexts, on the other hand, bring clarity by establishing clear boundaries around different subdomains, ensuring that different parts of the system are appropriately isolated or integrated based on their strategic relevance.
Context Mapping then provides the overarching structure to manage the relationships between these different contexts, giving organizations a clear view of how they interact. It helps in identifying dependencies, integration points, and potential areas of conflict, ensuring that these are managed strategically.
Share This Article