Domain-Driven Design: Tackling Complexity in the Heart of Software by Eric…
Domain-Driven Design: Tackling Complexity in the Heart of Software by Eric Evans
Forward by Martin Fowler
Key to controlling complexity is a good domain model
provides underlying structure
Greatest value of a domain model is that is provides a UBIQUITOUS LANGAUGE that ties domain experts and technologists together
Domain models evolve over time and the best ideas often come after the initial release
Implementation should be considered in design
For most software projects, the primary focus should be on the domain and domain logic
Complex domain designs should be based on a model
Development is iterative
Developers and domain experts have a close relationship
Domain-driven design is a difficult technical challenge that can pay off big, opening opportunities just when most software projects begin to ossify into legacy.
A model is a simplification. It is an interpretation of reality that abstracts the aspects relevant to solving the problem at hand and ignores extraneous detail.
Using a model in these ways can support the development of software that would otherwise take a massive investment of ad hoc development
The model and the heart of the design shape each other
The model is the backbone of a language used by all team members
Can communicate with domain experts without translation
The model is distilled knowledge
creating a lucid model that cuts through that complexity is exciting.
There are systematic ways of thinking that developers can employ to search for insight and produce effective models. There are design techniques that can bring order to a sprawling software application. Cultivation of these skills makes a developer much more valuable, even in an initially unfamiliar domain.
Chapter 1: Crunching Knowledge
Ingredients of effective modeling
Binding the model and the implementation. (Evans used a prototype to implement a model that experts could see)
Cultivating a language based on the model.
At first, domain exerts had to explain basic information, but as the project progresses, domain and technical experts began speaking and understanding the same language.
Developing a knowledge rich model.
Objects had behavior and enforce rules. Not just a data scheme
Distilling the model
Important concepts were added to the model as it became more complete
Concepts that proved not to be useful were dropped
Brainstorming and experimenting
discussions became labs for continued experimentation and refinement of the model
Success comes in an emerging set of abstract concepts that make sense of all the detail. Comes after trying many ideas
Collaborative activity between developers and domain experts
Waterfall: experts talk to analysts who abstract problems for developers to code. No feedback for analysts to improve the model
Iterative projects can still have problems if they fail to build up knowledge because they don't abstract
Developers just have experts describe the problem and they go build it. But programmers learn what the application should do and not the principles behind it.
When we set out to write software, we never know enough. Domains that seem less technically daunting can be deceiving (unknown unknowns)
Highly productive teams grow their knowledge conciously, practicing continuous learning
technical, domain-modeling and domain knowledge
Model should help newcomers learn. Discussing it should result in learning
Don't have to become a domain expert. But should be able to talk with them and sanity check the software being built
Move beyond entities and values to business activities and rules
More than just find the nounds
May be actual inconsistency among business rules.
Example: Cargo-Voyage Overbooking by 10%
Code could be hidden in guard rule for max booking
Overbooking rule could be moved into a POLICY (design pattern known as STRATEGY)
Rule is now in own class, and is clear to both technical and domain experts
As knowledge grew, model shifted from transferring items from place to place to transferring responsibility for items from party to party
Chapter 2: Communication and the use of language
More pervasively the language is used, the more smoothly understanding will flow
Persistent use of the UBIQUITOUS LANGUAGE will force the model's weaknesses into the open
Will lead to changes that will be recognized as changes in the domain model
By using the model-based language pervasively and not being satisfied until it flows, we approach a model that is complete and comprehensible, made up of simple elements that combine to express complex ideas
Use model as the backbone of a language.
Domain experts should object to terms or structures that are awkward or inadequate to convey domain understanding; developers should watch for ambiguity or inconsistency that will trip up design.
Modeling out loud
Play with the model as you talk about the system. Describe scenarios out loud using elements and interations of the model.
Find easier ways to say what you need to say, then take those new ideas back down to the diagrams and code.
One team, one language
Protecting domain experts from technical language: Of course there are technical components of the design that may not concern the domain experts, but the core of the model had better interest them
If sophisticated domain experts don't understand the model, there is something wrong with the model.
Multiplicity of languages is often necessary, but the linguistic division should never be between the domain experts and the developers.
Documents and diagrams
The trouble comes when people feel compelled to convey the whole model or design through UML. They are too complete because people feel they have to put all the objects that they are going to code into a modeling tool. With all that detail, no one can see the forest for the trees.
Attributes and relationships are only half the story. Behavior of those objects and the constraints on them are not so easily illustrated.
UML diagram cannot convey two fo the most important aspects of a model: the meaning of the concepts it represents and what the objects are meant to do
Careful use of language can fill this role pretty will
Diagrams are means of communication and facilitate brainstorming. They serve these ends best if they are minimal
Written design documents
Documents should complement code and speech
Dependence on the code as communication medium motivates developers to keep the code clean and transparent
Documents, comments etc get out of syc with the system
Language and white board illustrations do not persist long enough to get out of touch with the system.
A document shouldn't try to do what the code already does well. The code already supplies the detail. It is the exact specification of the program behavior.
Other documents need to illuminate meaning, to give insight to large-scale structures and to focus attention on core elements.
Documents can clarify design intent when programming language does not support a straightforward implementation of a concept
If a document isn't playing an important role, keeping it up to date through sheet will and discipline wastes effort
Chapter 3: Binding Model and Implementation
What good is a model on paper, unless it directly aids the development of running software?
Model Driven Design
Tightly relating the code to an underlying model gives the code meaning and makes the model relevant.
Software that lacks a concept at the foundation of its design is, at best, a mechanism that does useful things without explaining its actions.
If the design, or some central part of it, does not map to the domain model, that model is of little value, and the correctness of the software is suspect.
MODEL-DRIVEN DESIGN discards the dichotomy of analysis model and design to search out a single model that serves both purposes.
This requires us to be more demanding of the chosen model, since it must fulfill two quite different objectives.
The modeling and design process becomes a single iterative loop.
Design a portion of the software system to reflect the domain model in a very literal way, so that mapping is obvious.
Revisit the model and modify it to be implemented more naturally in software and gain deeper domain insight.
Model should also support a robust UBIQUITOUS LANGUAGE
Letting the Bones Show: Why models matter to users
Favorites in IE. Throws file error, even though the user doesn't think of favorites as files. Bad or multiple models cause confusion.
Model-driven design calls for only one model.
Revealing the model gives the user more access to the potential of the software and yields consistent, predictable behavior
Overseparation of responsibility for analysis, modeling, design and programming interferes with MDD
If the people who write the code do not feel responsible for the model or don't understand how to make the model work for an application, then the model has nothing to do with the software.
Any technical person contributing to the model must spend some time touching the code. Anyone touching code must learn to express a model through the code.
Part 2: Building blocks of a model-driven design
Essential principle is that nay element of a layer depends only on other elements in the same layer or on elements of the layers beneath it.
Concentrate all the code related to the domain model in one layer and isolate it from the ui, application and infrastructure code.
Isolating the domain implementation is a prerequisite for domain-driven design
Chapter 5: A model expressed in software
The ideas of high cohesion and low coupling, often thought of as technical metrics, can be applied to the concepts themselves.
Consistently constraining associations in ways that reflect the bias of the domain not only makes those associations more communicative and simpler to implement, it also gives significance to the remaining bidirectional associations.
Carefully distilling and constraining the model’s associations will take you a long way toward a MODEL-DRIVEN DESIGN
Entity: An object defined primarily by its identity is called an ENTITY
When an object is distinguished by its identity, rather than its attributes, make this primary to its definition in the model. Keep the class definition simple and focused on life cycle continuity and identity. Define a means of distinguishing each object regardless of its form or history
Value object: An object that represents a descriptive aspect of the domain with no conceptual identity.
Value objects are instantiated to represent elements of the design that we care about only for what they are, not who or which they are.
Software design is a constant battle with complexity. We must make distinctions so that special handling is applied only where necessary.
Value objects could just have one immutable object and entities that need it just point to it, avoiding unneeded duplication and waste of resources.
Some concepts from the domain aren’t natural to model as objects. Forcing the required domain functionality to be the responsibility of an ENTITY or VALUE either distorts the definition of a model-based object or adds meaningless artificial objects.
A service is an operation offered as an interface that stands alone in the model, without encapsulating stat as entities and value objects do.
Service should still have a defined responsibility and be defined as part of the domain model
Operation relates to a domain concept that is not a natural part of an entity or value object
Interface is defined in terms of other elements of the domain model
Application service: saving data in various file formats
Domain service: transferring funds between accounts
As previously discussed, fine-grained domain objects can contribute to knowledge leaks from the domain into the application layer, where the domain object’s behavior is coordinated
The MODULES in the domain layer should emerge as a meaningful part of the model, telling the story of the domain on a larger scale.
At the same time, the elements of a good model have synergy, and well-chosen MODULES bring together elements of the model with particularly rich conceptual relationships
Letting the MODULES reflect changing understanding of the domain will also allow more freedom for the objects within them to evolve.
Argument for packaging domain related classes together rather than layers together. (i.e. domain object, domain controller, domain service in a package rather than a services package and a controller package)
These names enter the UBIQUITOUS LANGUAGE. “Now let’s talk about the ‘customer’ module,” you might say to a business expert, and the context is set for your conversation.
There is only so much partitioning a mind can stitch back together, and if the framework uses it all up, the domain developers lose their ability to chunk the model into meaningful pieces.
Use packaging to separate the domain layer from other code. Otherwise, leave as much freedom as possible to the domain developers to package the domain objects in ways that support their model and design choices.
Why object paradigm predominates
Perhaps the pioneers of the field are effective but haven’t yet published their insights in an accessible form.Objects are already understood by a community of thousands of developers, project managers, and all the other specialists involved in project work.
Naturally understood by technical and nontechnical people
Nonobjects in an object world
But when major parts of the domain seem to belong to different paradigms, it is intellectually appealing to model each part in a paradigm that fits, using a mixture of tool sets to support implementation. (Interesting though in reference to microservices )
Chapter 6: The Life Cycle of a Domain Object