Domain Driven Design (DDD), the brainchild of Eric Evans, aims to map out system representations of business entities directly from business concepts and semantics.
Four basic tenets are often put ahead to characterize DDD:
- Layered architectures.
- Aggregates and threads of continuity and identity.
- Bounded contexts.
- Ubiquitous language supporting the communication between business domains and software representations.
If the meaning and benefits of layers and aggregates are widely understood, there is less of a consensus about practical implementation of bounded contexts and ubiquitous languages.
All too often, modelers overlook the difference between descriptive and prescriptive models, the former depicting business environments and objectives, the latter their symbolic representations in systems. Unfortunately, this seemingly benign neglect seems to imply that descriptive models have no other purpose than supporting the development of systems, which can subsequently stand on their own. But what may once have been a safe assumption is now a very hazardous one considering that today’s IT systems must be weaved with enterprise environment and accommodate continuously to its changes.
On that regard Domain Driven Design seems inconclusive: on one hand it insists upon the tie between concepts and implementations, on the other hand it makes a clear distinction between concepts (roots and aggregates), and their use (contexts). Setting DDD layers with regard to enterprise architecture could help to clarify the point.
With regard to software (as opposed to enterprise) architecture, DDD identifies four layers: users interfaces (or presentation), applications, domains (or models), and infrastructures. Of these, the domain layer seems to be the only one unambiguously set apart, definitions of the others leaving room for overlaps; but potential qualms can be easily remedied by introducing formal criteria:
- Presentation: non shared processing of I/O.
- Application: shared processing of transient representations
- Domain: shared access to persistent representations
- Infrastructure: shared access to services.
Furthermore, these layers are best understood when associated with the platform independent models (PIMs) of the model driven architecture (MDA) framework.
Aggregates & Roots
The distinction between the identity and structure of objects on one hand, features semantics and use on the other hand, is arguably a core tenet of DDD as it brings together objects designs and systems architectures.
With regard to objects design, aggregates to be accessed through a single root (#) guarantee the continuity and integrity of the threads anchoring business entities to their symbolic counterparts.
With regard to systems architectures, features of business entities surrogates can be shared across domains, each according to their own semantics, as epitomized by persons in the example below.
Yet, the fact is that approach combines object with aspect oriented designs and its implementation at architecture level could come with serious drawbacks when functional facets are to be shared across domains. That’s where bounded contexts intervene.
Contexts are introduced to conciliate continuity and integrity, managed through aggregates, and semantics and functional accesses, managed through contexts; bounded contexts (BCs) are ones with shared business entities. Adding to the example above, person usually appears in different functional contexts subject to specific responsibilities, with one and only one with explicit responsibility on aggregates (#).
But as sound and useful as bounded contexts may be conceptually, their implementation is mostly entrusted to maps and best practices. Since the way shared business domains are managed by systems is arguably a key success factor of enterprise architectures, the lack of principled implementation schemes leaves the conceptual gap between business domains and software designs unaccounted for. That would be the purpose of ubiquitous languages (UL).
Ubiquitous or Domain Specific Languages.
The explicit objective of ubiquitous languages is to bring under a common semantic roof domain analysis and software design, and so to tie concepts and implementations. But that very endeavor may also be seen as controversial, shallow, and confusing:
- Controversial: bringing together concepts and implementations appears to contradict OO principles as well as layered architectures.
- Shallow: the so-called languages (as many as domains ?) are in fact just lists of entities and operations, without grammar or unifying semantics.
- Confusing: they are supposedly derived from models, which would suggest specificity instead of ubiquity; that understanding would also belie the customary assumption that models are built with modeling languages.
One way out of the conundrum could be to see ubiquitous languages as variants of domain specific ones whose explicit objective is precisely to tie concepts with implementations. But that option would bypass the issue of principled BC design, and more generally the relationship between business domains, systems architectures, and software designs.
Bounded Contexts & Open Concepts
Open concepts are modeling artifacts whose semantics can be shared by business domains and systems functional architectures. For that purpose they have to meet standard OO principles:
- Open-Closed Principle (OPC): open concepts should have no reason to change, they can only be refined. In other words open concepts are meant to be specialized, but not generalized. That ensures that the semantics of sub-types defined by different projects cannot be modified.
- Substitution Principle (LSP): sets of instances denoted by specialized concepts are subsets of the sets denoted by more general ones. That ensures that individuals are consistently identified across projects.
- Dependency-Inversion principle (DIP): higher levels semantics are defined independently of lower levels. That ensures that the semantics of sub-types are consistently, but not necessarily uniformly, defined across projects.
- Interface-Segregation Principle (ISP): semantics and features are congruent, i.e all features are meaningful for whoever is using the concept. That ensures that there is no overlapping of semantics even when subsets of individuals overlap.
Assuming these criteria can be fulfilled, open concepts can be used as a modeling glue between bounded contexts overlaps.
Open concepts for entities (aka roots):
- Structural inheritance means that the targeted entities (i.e shared between contexts) inherit both structures and aspects: parties are a subset of social agents.
- Functional inheritance means that the targeted entities inherit all the aspects whatever the identified structure: an organization has all the features of a collective agent but is not necessarily identified as such.
Open concepts for aspects (aka features):
- Structural inheritance is equivalent to composition, i.e inherited aspects are bound to domain individuals whatever their structure: symbolic references are an intrinsic component of products but can be used in any kind of domain.
- Functional inheritance is equivalent to aggregation, i.e inherited aspects are not bound to domain individuals: business roles can combine different ones.
On a broader perspective, using open concepts to consolidate the overlaps between bounded contexts enables the formal verification of models, not only for internal consistency but also with regard to best practices. And best practices can be translated into functional (aka representation) patterns formally defined in terms of open concepts.
- Open Concepts Will Make You Free
- Open Concepts
- Functional Patterns
- Projects Have to Liaise
- UML’s Semantic Master Key, Lost & Found
- Conceptual Models & Abstraction Scale