Domain-Driven Design: Tackling Complexity in the Heart of Software
Rate it:
Open Preview
Read between May 28, 2022 - September 10, 2023
13%
Flag icon
A deadly divide opens between analysis and design so that insight gained in each of those activities does not feed into the other.
13%
Flag icon
When a model doesn’t seem to be practical for implementation, we must search for a new one. When a model doesn’t faithfully express the key concepts of the domain, we must search for a new one.
13%
Flag icon
The modeling and design process then becomes a single iterative loop.
13%
Flag icon
The code becomes an expression of the model, so a change to the code may be a change to the model.
13%
Flag icon
Development becomes an iterative process of refining the model, the design, and the code as a single activity (see Part III).
14%
Flag icon
What the script writers were trying to do was to supplement the tool’s domain model with the concept of “bus.”
14%
Flag icon
Their implementation infers the bus’s existence through sorts and string matches, but it does not explicitly deal with the concept.
14%
Flag icon
Now we need to organize those concepts explicitly into a model we can base software on.
14%
Flag icon
With these objects implemented in an object-oriented language, the core functionality becomes almost trivial.
15%
Flag icon
Most of the advice and examples go to the problems of having separate analysis models and design models, but here we have a problem arising from a different pair of models: the user model and the design/implementation model.
16%
Flag icon
The material in the following three chapters is organized as a “pattern language” (see Appendix A), which will show how subtle model distinctions and design decisions affect the domain-driven design process.
16%
Flag icon
Isolating the domain design from the mass of other concerns in the software system will greatly clarify the design’s connection to the model.
16%
Flag icon
Following proven patterns for individual elements helps produce a model that is practical to implement.
16%
Flag icon
We need to decouple the domain objects from other functions of the system, so we can avoid confusing the domain concepts with other concepts related only to software technology or losing sight of the domain altogether in the mass of the system.
16%
Flag icon
Creating programs that can handle very complex tasks calls for separation of concerns, allowing concentration on different parts of the design in isolation.
16%
Flag icon
At the same time, the intricate interactions within the system must be maintained in spite of the separation.
16%
Flag icon
The essential principle is that any element of a layer depends only on other elements in the same layer or on elements of the layers “beneath” it.
16%
Flag icon
Communication upward must pass through some indirect mechanism, which I’ll discuss a little later.
16%
Flag icon
But that user interface could be replaced by a wire request in XML without affecting the application layer or any of the lower layers.
16%
Flag icon
This decoupling is important not because projects frequently need to replace user interfaces with wire requests but because a clean separation of concerns keeps the design of each layer easy to understand and maintain.
16%
Flag icon
Layers are meant to be loosely coupled, with design dependencies in only one direction.
16%
Flag icon
But when an object of a lower level needs to communicate upward (beyond answering a direct query), we need another mechanism, drawing on architectural patterns for relating layers such as callbacks or OBSERVERS (Gamma et al. 1995).
17%
Flag icon
For our purposes, all approaches are fine as long as they maintain the isolation of the domain layer, allowing domain objects to be designed without simultaneously thinking
17%
Flag icon
about the user interface that might interact with them.
Alexandre Gomes
I think this is what react redux does - it makes the global state observable by wrapping the react components with an higher order component that subscribes to global state changes and trickles down the state to its wrapped component as imuttable properties. This forces the wrapped component to re-render with up-to-date properties derived and synchronized with global state.
17%
Flag icon
But not all infrastructure comes in the form of SERVICES callable from the higher layers.
17%
Flag icon
Some technical components are designed to directly support the basic functions of other layers (such as providing an abstract base class for all domain objects) and provide the mechanisms for them to relate (such as implementations of MVC and the like).
17%
Flag icon
(It may seem counterintuitive for a subclass to be in a layer higher than that of the parent class, but keep in mind which class reflects more knowledge of the other.)
17%
Flag icon
But frameworks can easily get in the way, either by making too many assumptions that constrain domain design choices or by making the implementation so heavyweight that development slows down.
17%
Flag icon
When applying a framework, the team needs to focus on its goal: building an implementation that expresses a domain model and uses it to solve important problems.
17%
Flag icon
For example, early J2EE applications often implemented all domain objects as “entity beans.” This approach bogged down both performance and the pace of development.
17%
Flag icon
Instead, current best practice is to use the J2EE framework for larger grain objects, implementing most business logic with generic Java objects.
17%
Flag icon
Newer frameworks will automate or prefabricate more and more of the technical aspects of an application.
17%
Flag icon
elaborate frameworks can also straitjacket application developers.
18%
Flag icon
Unfortunately, there are influences other than infrastructure and user interfaces that can corrupt your delicate domain model.
18%
Flag icon
You have to cope with other development teams who use different models of the same domain.
18%
Flag icon
Chapter 14, “Maintaining Model Integrity,” deals with this topic, int...
This highlight has been truncated due to consecutive passage length restrictions.
18%
Flag icon
as BOUNDED CONTEXT and ANTICORRU...
This highlight has been truncated due to consecutive passage length restrictions.
18%
Flag icon
Next, we’ll look at the nuts and bolts of co-evolving an effective domain model and an expressive implementation.
18%
Flag icon
This discussion will start with the issues of designing and streamlining associations.
18%
Flag icon
Associations between objects are simple to conceive and to draw, but implementing them is a potential quagmire.
18%
Flag icon
we’ll focus on making distinctions among the three patterns of model elements that express the model:
18%
Flag icon
ENTITIES, VALUE OBJECTS, and SERVICES.
18%
Flag icon
A bidirectional association means that both objects can be understood only together.
18%
Flag icon
When application requirements do not call for traversal in both directions, adding a traversal direction reduces interdependence and simplifies the design.
18%
Flag icon
Understanding the domain may reveal a natural d...
This highlight has been truncated due to consecutive passage length restrictions.
18%
Flag icon
Very often, deeper understanding leads to a “qualified” relationship.
18%
Flag icon
Looking deeper into presidents, we realize that (except in a civil war, perhaps) a country has only one president at a time.
18%
Flag icon
This qualifier reduces the multiplicity to one-to-one, and explicitly embeds an impor...
This highlight has been truncated due to consecutive passage length restrictions.
19%
Flag icon
Many objects are not fundamentally defined by their attributes, but rather by a thread of continuity and identity.
20%
Flag icon
Identity is not intrinsic to a thing in the world; it is a meaning superimposed because it is useful.