Domain-Driven Design: Tackling Complexity in the Heart of Software
Rate it:
Open Preview
Kindle Notes & Highlights
8%
Flag icon
Domain experts are usually not aware of how complex their mental processes are as, in the course of their work, they navigate all these rules, reconcile contradictions, and fill in gaps with common sense.
11%
Flag icon
Too abstract? Then how do you know the abstractions are sound?
11%
Flag icon
If sophisticated domain experts don’t understand the model, there is something wrong with the model.
12%
Flag icon
The thrust of this book is that one model should underlie implementation, design, and team communication. Having separate models for these separate purposes poses a hazard.
18%
Flag icon
Connecting model and implementation has to be done at the detail level.
18%
Flag icon
A SERVICE is something that is done for a client on request.
19%
Flag icon
Does the user of the application care if I am the same person I was at age five?
19%
Flag icon
Some objects are not defined primarily by their attributes. They represent a thread of identity that runs through time and often across distinct representations. Sometimes such an object must be matched with another object even though attributes differ. An object must be distinguished from other objects even though they might have the same attributes. Mistaken identity can lead to data corruption.
19%
Flag icon
Consider transactions in a banking application. Two deposits of the same amount to the same account on the same day are still distinct transactions, so they have identity and are ENTITIES. On the other hand, the amount attributes of those two transactions are probably instances of some money object. These values have no identity, since there is no usefulness in distinguishing them. In fact, two objects can have the same identity without having the same attributes or even, necessarily, being of the same class.
20%
Flag icon
Add only behavior that is essential to the concept and attributes that are required by that behavior. Beyond that, look to remove behavior and attributes into other objects associated with the core ENTITY.
22%
Flag icon
Sometimes services masquerade as model objects, appearing as objects with no meaning beyond doing some operation. These “doers” end up with names ending in “Manager” and the like.
22%
Flag icon
They have no state of their own nor any meaning in the domain beyond the operation they host.
22%
Flag icon
A good SERVICE has three characteristics. 1. The operation relates to a domain concept that is not a natural part of an ENTITY or VALUE OBJECT. 2. The interface is defined in terms of other elements of the domain model. 3. The operation is stateless.
22%
Flag icon
Statelessness here means that any client can use any instance of a particular SERVICE without regard to the instance’s individual history.
26%
Flag icon
An AGGREGATE is a cluster of associated objects that we treat as a unit for the purpose of data changes. Each AGGREGATE has a root and a boundary. The boundary defines what is inside the AGGREGATE. The root is a single, specific ENTITY contained in the AGGREGATE. The root is the only member of the AGGREGATE that outside objects are allowed to hold references to,
27%
Flag icon
Even calling constructors couples the client to the concrete classes of the objects it is building. No change to the implementation of the domain objects can be made without changing the client, making refactoring harder.
27%
Flag icon
Even worse, if the client is part of the application layer, then responsibilities have leaked out of the domain layer altogether.
28%
Flag icon
The class is the type. It is not part of any interesting hierarchy, and it isn’t used polymorphically by implementing an interface. • The client cares about the implementation, perhaps as a way of choosing a STRATEGY. • All of the attributes of the object are available to the client, so that no object creation gets nested inside the constructor exposed to the client. • The construction is not complicated. • A public constructor must follow the same rules as a FACTORY: It must be an atomic operation that satisfies all invariants of the created object.
29%
Flag icon
When the program is assigning an identifier, the FACTORY is a good place to control it.
30%
Flag icon
any object internal to an AGGREGATE is prohibited from access except by traversal from the root.
30%
Flag icon
In fact, a global search access to a VALUE is often meaningless, because finding a VALUE by its properties would be equivalent to creating a new instance with those properties.
30%
Flag icon
A subset of persistent objects must be globally accessible through a search based on object attributes. Such access is needed for the roots of AGGREGATES that are not convenient to reach by traversal. They are usually ENTITIES, sometimes VALUE OBJECTS with complex internal structure, and sometimes enumerated VALUES. Providing access to other objects muddies important distinctions. Free database queries can actually breach the encapsulation of domain objects and AGGREGATES. Exposure of technical infrastructure and database access mechanisms complicates the client and obscures the MODEL-DRIVEN ...more
30%
Flag icon
But even so, take note of what has been lost. We are no longer thinking about concepts in our domain model. Our code will not be communicating about the business; it will be manipulating the technology of data retrieval. The REPOSITORY pattern is a simple conceptual framework to encapsulate those solutions and bring back our model focus.
30%
Flag icon
For each type of object that needs global access, create an object that can provide the illusion of an in-memory collection of all objects of that type. Set up access through a well-known global interface. Provide methods to add and remove objects, which will encapsulate the actual insertion or removal of data in the data store. Provide methods that select objects based on some criteria and return fully instantiated objects or collections of objects whose attribute values meet the criteria, thereby encapsulating the actual storage and query technology. Provide REPOSITORIES only for AGGREGATE ...more
30%
Flag icon
One particularly apt approach to generalizing REPOSITORIES through a framework is to use SPECIFICATION-based queries. A SPECIFICATION allows a client to describe (that is, specify) what it wants without concern for how it will be obtained. In the process, an object that can actually carry out the selection is created. This pattern will be discussed in depth in Chapter 9.
32%
Flag icon
The tradition of refactoring that has increasingly taken hold in the object world has not really affected relational database design much. What’s more, serious data migration issues discourage frequent change. This may create a drag on the refactoring of the object model, but if the object model and the database model start to diverge, transparency can be lost quickly.