Software Complexity and Domain‑Driven Design: Isolating Business and Technical Concerns
This article explains how software complexity arises from both business requirements and quality attributes, discusses the challenges of technical and business complexity, and demonstrates how Domain‑Driven Design—through layered and hexagonal architectures, bounded contexts, and micro‑service decomposition—helps isolate concerns and manage complexity in large systems.
Why still talk about software architecture? As an organizational capability, continuous delivery 2.0 requires not only tooling support and process management but also a solid software architecture; architecture directly influences delivery capability and is tightly linked to system design complexity. This site therefore publishes articles on software architecture to serve readers.
Whether the difficulty stems from scale‑induced comprehension barriers or from unpredictable changes, the ultimate deciding factor is demand. Eric Evans notes that most application complexity lies not in technology but in the domain itself, user activities, or business rules. Hence Domain‑Driven Design (DDD) focuses on the domain and its logic because software systems fundamentally deliver business‑value domain functions to customers.
Complexity Caused by Requirements
Requirements can be divided into business requirements and quality‑attribute requirements, leading to two kinds of complexity: technical complexity and business complexity.
Technical complexity originates from quality attributes such as security, high performance, high concurrency, and high availability. These attributes often conflict—for example, adding security layers (firewalls, encryption, authentication) can increase latency, while scaling for high concurrency may require horizontal partitioning and asynchronous processing, which in turn adds architectural layers and challenges data consistency.
Business complexity grows with the scale of customer needs. As functionality expands, inter‑dependencies increase, affecting maintainability and extensibility. Poor communication or unclear requirements can cause frequent changes, leading to tangled business logic and a "big ball of mud".
Consider an e‑commerce promotion‑rule scenario: different customers and products receive varied promotions (points, coupons, gifts) with customizable periods (e.g., Double‑11). Without careful design, the interaction between promotion rules, products, customers, payments, logistics, and warehousing becomes extremely difficult.
The problem domain becomes too large, making solution discovery harder; this relates to system scale.
Developers conflate business‑logic complexity with technical‑implementation complexity; this relates to system structure.
Growing and changing requirements make it hard to control both business and technical complexity; this relates to system evolution.
DDD provides specific countermeasures for these three issues.
DDD Countermeasures
Isolating Business Complexity from Technical Complexity
To avoid mixing concerns, the first step is to define clear boundaries between business logic and technical implementation. In an e‑commerce order domain, business rules include order validation, total calculation, and workflow, while technical concerns ensure data consistency and correct inter‑service communication.
Business logic should not care how technology is implemented; as long as requirements stay the same, the rules remain unchanged. Ideally, business rules and technical implementation are orthogonal.
DDD achieves this isolation through layered architecture and the Hexagonal Architecture.
Layered Architecture – Concern Separation
The layered approach places business concerns in the Domain Layer, technical concerns in the Infrastructure Layer, and introduces an Application Layer that acts as a façade for use‑cases and as the glue between domain and infrastructure.
The diagram below (original) shows a typical DDD layered architecture where blue areas represent business logic and gray areas represent technical implementation, converging in the Application Layer, which binds them via direct dependencies or Dependency Injection (DI).
Hexagonal Architecture – Inside‑Outside Separation
Proposed by Cockburn, the Hexagonal Architecture places the core business logic at the center and isolates it from technical details via ports and adapters, making the system easier to evolve and keeping technical changes from contaminating the domain.
Case: Isolating Database and Cache Access
DDD recommends defining a Repository abstraction in the domain layer; its implementations live in the infrastructure layer. Switching from MyBatis to Spring Data does not affect domain code.
<span style="color: rgb(86, 156, 214)">package</span> practiceddd.ecommerce.ordercontext.application;
<span style="color: rgb(155, 155, 155)">@Transaction</span>
<span style="color: rgb(86, 156, 214)">public class</span> OrderAppService {
<span style="color: rgb(155, 155, 155)">@Service</span>
private PlaceOrderService placeOrder;
// ...
}
<span style="color: rgb(86, 156, 214)">public interface</span> OrderRepository {
List<Order> forBuyerId(Identity buyerId);
void add(Order order);
}
<span style="color: rgb(86, 156, 214)">public class</span> OrderMybatisRepository implements OrderRepository {}
<span style="color: rgb(86, 156, 214)">public class</span> OrderSpringDataRepository implements OrderRepository {}Cache access follows a similar pattern but belongs to the application layer because it is not domain‑specific.
<span style="color: rgb(86, 156, 214)">public interface</span> CacheClient<T> {
Optional<T> get(String key);
void put(String key, T value);
}
<span style="color: rgb(86, 156, 214)">public class</span> RedisCacheClient<T> implements CacheClient<T> {}Bounded Context – Divide and Conquer
When a problem domain becomes large, DDD introduces Bounded Contexts to split it into smaller, loosely coupled sub‑systems, each with its own model and architecture. This reduces overall complexity and clarifies boundaries.
Example: an international tax‑reporting system originally split only by user roles (Front End for Assignees, Office End for Admins). This led to a massive codebase, duplicated logic, data redundancy, complex bi‑directional integration, and poor adaptability to new requirements.
Applying DDD, the system was re‑modeled into multiple Bounded Contexts such as Account Management, Calendar Management, Work Record Management, File Sharing, Consent, Notification, and Questionnaire. Each context became a micro‑service with its own REST API, allowing independent deployment, dedicated feature teams, and clearer integration.
Domain Model – Abstracting Domain Knowledge
A domain model captures concepts, rules, and relationships of the business. It provides a shared language, reduces ambiguity, and isolates business details from technical implementation, making the system more adaptable to change.
Case: Project Management System Domain Model
The system must support various project‑management methodologies (Waterfall, RUP, XP, Scrum). By analyzing commonalities, a unified domain model was derived, featuring entities such as Phase, Release, Iteration, Activity, Task, and Specification. This model guides implementation and eases the addition of new lifecycle types.
When product managers requested a plan‑template feature, the model was extended with a LifeCycleSpecification concept (a Specification pattern) to encapsulate lifecycle constraints.
In summary, by applying DDD principles—isolating concerns via layered/hexagonal architectures, defining bounded contexts, and building expressive domain models—software teams can tame both technical and business complexity, achieve high cohesion and loose coupling, and evolve large systems with confidence.
Author Introduction
Zhang Yi , architecture practitioner, IT cultural worker, big‑data platform architect, lover of OO and FP, passionate about programming languages, dedicated to combining mainstream DDD with functional, reactive, and micro‑service architectures. Follow his WeChat public account "Yi Yan" or visit his blog at http://zhangyi.xyz .
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Continuous Delivery 2.0
Tech and case studies on organizational management, team management, and engineering efficiency
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
