Eric Evans, "A Model Expressed in Software", in Domain-Driven Design: Tackling Complexity in the Heart of Software, 116, 122.The four patterns [ENTITIES, VALUE OBJECTS, SERVICES and MODULES] in this chapter provide the building blocks for an object model. But MODEL-DRIVEN DESIGN does not necessarily mean forcing everything into an object mold. There are also other model paradigms supported by tools, such as rules engines. Projects have to make pragmatic trade-offs between them. These other tools and techniques are means to the end of a MODEL-DRIVEN DESIGN, not alternatives to it.
Here are four rules of thumb for mixing nonobject elements into a predominantly object-oriented system:
- Don't fight the implementation paradigm. There's always another way to think about a domain. Find model concepts that fit the paradigm.
- Lean on the ubiquitous language. Even when there is no rigorous connection between tools, very consistent use of language can keep parts of the design from diverging.
- Don't get hung up on UML. Sometimes the fixation on a tool, such as UML diagramming, lead people to distort the model to make it fit what can easily be drawn. For example, UML does have some features for representing constraints, but they are not always sufficient. Some other style of drawing (perhaps conventional for the other paradigm), or simple English descriptions, are better than tortuous adaptation of a drawing style intended for a certain view of objects.
- Be skeptical. Is the tool really pulling its weight? Just because you have some rules, that doesn't necessarily mean you need the overhead of a rules engine. Rules can be expressed as objects, perhaps a little less neatly; multiple paradigms complicate matters enormously.
Sunday, September 15, 2019
Modeling paradigms
The pitfalls of infrastructure-driven packaging
Eric Evans, "A Model Expressed in Software", in Domain-Driven Design: Tackling Complexity in the Heart of Software, 114-115.Elaborate technically driven packaging schemes impose two costs.
- If the framework's partitioning conventions pull apart the elements implementing the conceptual objects, the code no longer reveals the model.
- There is only so much partitioning a mind can stitch back togheter, and if the framework uses it all up, the domain developers lose their ability to chunck the model into meaningful pieces.
It is best to keep things simple. Choose a minimum of technical partitioning rules that are essential to the technical environment or actually aid development. For example, decoupling complicated data persistence code from the behavioral aspects of the objects may make refactoring easier.
Unless there is a real intention to distribute code on different servers, keep all the code that implements a single conceptual object in the same MODULE, if not the same object.
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.
Sunday, August 25, 2019
Modules (a.k.a packages)
Eric Evans, “A Model Expressed in Software”, in Domain-Driven Design: Tackling Complexity in the Heart of Software, 109-111.Everyone uses MODULES, but few treat them as a full-fledged part of the model. Code gets broken down into all sorts of categories, from aspects of the technical architecture to developers' work assignments. Even developers who refactor a lot tend to content themselves with MODULES conceived early in the project.
It is a truism that there should be low coupling between MODULES and high cohesion within them. Explanations of coupling and cohesion tend to make them sound like technical metrics, to be judged mechanically based on the distributions of associations and interactions. Yet it isn't just code being divided into MODULES, but concepts. There is a limit to how many things a person can think about at once (hence low coupling). Incoherent fragments of ideas are as hard to understand as an undifferentiated soup of ideas (hence high cohesion).
Choose MODULES that tell the story of the system and contain a cohesive set of concepts. This often yields low coupling between MODULES, but if it doesn't, look for a way to change the model to disentangle the concepts, or search for an overlooked concept that might be the basis of a MODULE that would bring the elements togheter in a meaningful way. Seek low coupling in the sense of concepts that can be understood and reasoned about independently of each other. Refine the model until it partitions according to high-level domain concepts and the corresponding code is decoupled as well.
Give the MODULES names that become part of the UBIQUITOUS LANGUAGE. MODULES and their names should reflect insight into the domain.
Sunday, August 18, 2019
Services
Eric Evans, "A Model Expressed in Software", in Domain-Driven Design: Tackling Complexity in the Heart of Software, 105-106.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.
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 an standalone interface declared as a SERVICE. Define the interface in terms of the language of the model and make sure the operation name is part of the UBIQUITOUS LANGUAGE. Make the SERVICE stateless.
Value objects
Eric Evans, "A Model Expressed in Software", in Domain-Driven Design: Tackling Complexity in the Heart of Software, 98-99.An object that represent a descriptive aspect of the domain with no conceptual identity is called a VALUE OBJECT. 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.
When you care only about the attributes of an element of the model, classify it as a VALUE OBJECT. Make it express the meaning of the attributes it conveys and give it related functionality. Treat the VALUE OBJECT as immutable. Dont' give it any identity and avoid the design complexities necessary to maintain ENTITIES.
Entities (a.k.a. reference objects)
Eric Evans, "A Model Expressed in Software", in Domain-Driven Design: Tackling Complexity in the Heart of Software, 91-92.An object defined primarily by its identity is called an ENTITY. ENTITIES have special modeling and design considerations. They have life cycles that can radically change their form and content, but a thread of continuity must be maintained. Their identities must be defined so that they can be effectively tracked. Their class definitions, responsibilities, attributes, and associations should revolve around who they are, rather than the particular attributes they carry. Even for ENTITIES that don't transform so radically or have such complicated life cycles, placing them in the semantic category leads to more lucid models and more robust implementations.
The model must define what it means to be the same thing.
Friday, August 16, 2019
Not a software engineer, but a software cook
Martin Fowler, in Is High Quality Software Worth the Cost?.Even the best teams will have cruft in their software. The difference is that the best teams both create much less cruft but also remove enough of the cruft they do create that they can continue to add features quickly. [...] A common metaphor is that it's like cleaning up work surfaces and equipment in the kitchen. You can't not make things dirty when you cook, but if you don't clean things quickly, muck dries up, is harder to remove, and all the dirty stuff gets in the way of cooking the next dish.