A language structured around the domain model and used by all team members within a bounded context to connect all the activities of the team with the software.
A relationship between two groups in which the “upstream” group’s actions affect project success of the “downstream” group, but the actions of the downstream do not significantly affect projects upstream.
Isolate the domain model and the business logic, eliminate any dependency on infrastructure, user interface, or even application logic that is not business logic.
When a significant process or transformation in the domain is not a natural responsibility of an entity or value object, add an operation to the model as a standalone interface declared as a service.
For each type of aggregate that needs global access, create a service that can provide the illusion of an in-memory collection of all objects of that aggregate’s root type.
Shift the responsibility for creating instances of complex objects and aggregates to a separate object, which may itself have no responsibility in the domain model but is still part of the domain design.
There can be no real guarantees in procedural software. To name just one way of evading assertions, code could have additional side effects that were not specifically excluded.
Decompose design elements (operations, interfaces, classes, and aggregates) into cohesive units, taking into consideration your intuition of the important divisions in the domain.
Where development failure in either of two contexts would result in delivery failure for both, forge a partnership between the teams in charge of the two contexts.
Use a well-documented shared language that can express the necessary domain information as a common medium of communication, translating as necessary into and out of that language.
Declare a bounded context to have no connection to the others at all, allowing developers to find simple, specialized solutions within this small scope.
Refactor the model to separate the core concepts from supporting players (including ill- defined ones) and strengthen the cohesion of the core while reducing its coupling to other code.
Devise a pattern of rules or roles and relationships that will span the entire system and that allows some understanding of each part’s place in the whole—even without detailed knowledge of the part’s responsibility.
When a concrete analogy to the system emerges that captures the imagination of team members and seems to lead thinking in a useful direction, adopt it as a large-scale structure.
Distill an abstract core of interfaces and interactions and create a framework that allows diverse implementations of those interfaces to be freely substituted.