-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path03-putting-the-model-to-work.dj
200 lines (153 loc) · 9.43 KB
/
03-putting-the-model-to-work.dj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# Putting the Model to Work
`\set-counter[id=folio,value=1,display=arabic]`{=sile}
[^:therefore:]: *∴*{custom-style="center"}
Domain-Driven Design is an approach to the development of complex software in
which we:
1. Focus on the _core domain._
2. Explore models in a creative collaboration of domain practitioners and
software practitioners.
3. Speak a _ubiquitous language_ within an explicitly _bounded context._
This three-point summary of DDD depends on the definition of the terms, which
are defined in this booklet.
Many projects do modeling work without getting much real benefit in the end. The
patterns of DDD distill successful practices from projects where dramatic
benefits have come from modeling. Taken together, they lay out a quite different
approach to modeling and software development that runs from fine details to
high-level vision. Rigorous modeling conventions must be balanced with free
exploration of models in collaboration with non-technical people. Tactics and
strategy must be combined to succeed, and DDD addresses both tactical and
strategic design.
## Bounded Context
_Multiple models are in play on any large project._ They emerge for many reasons.
Two subsystems commonly serve very different user communities, with different
jobs, where different models may be useful. Teams working independently may
solve the same problem in different ways through lack of communication. The tool
set may also be different, meaning that program code cannot be shared.
Multiple models are inevitable, yet when code based on distinct models is
combined, software becomes buggy, unreliable, and difficult to understand.
Communication among team members becomes confused. It is often unclear in what
context a model should not be applied.
Model expressions, like any other phrase, only have meaning in context.
:therefore:
*Explicitly define the context within which a model applies. Explicitly set
boundaries in terms of team organization, usage within specific parts of the
application, and physical manifestations such as code bases and database
schemas. Apply Continuous Integration to keep model concepts and terms strictly
consistent within these bounds, but don't be distracted or confused by issues
outside. Standardize a single development process within the context, which need
not be used elsewhere.*
## Ubiquitous Language
> \
> For first you write a sentence,\
> And then you chop it small;\
> Then mix the bits, and sort them out\
> Just as they chance to fall:\
> The order of the phrases makes\
> No difference at all.
^ Lewis Carroll{.smallcaps}, "Poeta Fit, Non Nascitur"
To create a supple, knowledge-rich design calls for a versatile, shared team
language, and a lively experimentation with language that seldom happens on
software projects.
Within a single _bounded context,_ language can be fractured in ways that
undermine efforts to apply sophisticated modeling. If the model is only used to
draw UML diagrams for the technical members of the team, then it is not
contributing to the creative collaboration at the heart of DDD.
Domain experts use their jargon while technical team members have their own
language tuned for discussing the domain in terms of design. The terminology of
day-to-day discussions is disconnected from the terminology embedded in the code
(ultimately the most important product of a software project). And even the same
person uses different language in speech and in writing, so that the most
incisive expressions of the domain often emerge in a transient form that is
never captured in the code or even in writing.
Translation blunts communication and makes knowledge crunching anemic.
Yet none of these dialects can be a common language because none serves all
needs.
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.
Play with the model as you talk about the system. Describe scenarios _out loud_
using the elements and interactions of the model, combining concepts in ways
allowed by the model. Find easier ways to say what you need to say, and then
take those new ideas back down to the diagrams and code.
With a _ubiquitous language,_ the model is not just a design artifact. It becomes
integral to everything the developers and domain experts do together.
:therefore:
*Use the model as the backbone of a language. Commit the team to exercising that
language relentlessly in all communication within the team and in the code.
Within a bounded context, use the same language in diagrams, writing, and
especially speech.*
*Recognize that a change in the language is a change to the model.*
*Iron out difficulties by experimenting with alternative expressions, which
reflect alternative models. Then refactor the code, renaming classes, methods,
and modules to conform to the new model. Resolve confusion over terms in
conversation, in just the way we come to agree on the meaning of ordinary
words.*
## Continuous Integration
_Once a bounded context has been defined, we must keep it sound._
When a number of people are working in the same bounded context, there is a
strong tendency for the model to fragment. The bigger the team, the bigger the
problem, but as few as three or four people can encounter serious problems. Yet
breaking down the system into ever-smaller contexts eventually loses a valuable
level of integration and coherency.
:therefore:
*Institute a process of merging all code and other implementation artifacts
frequently, with automated tests to flag fragmentation quickly. Relentlessly
exercise the ubiquitous language to hammer out a shared view of the model as the
concepts evolve in different people's heads.*
## Model-Driven Design
_Tightly relating the code to an underlying model gives the code meaning and
makes the model relevant._
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.
At the same time, complex mappings between models and design functions are
difficult to understand and, in practice, impossible to maintain as the design
changes. A deadly divide opens between analysis and design so that insight
gained in each of those activities does not feed into the other.
Draw from the model the terminology used in the design and the basic assignment
of responsibilities. The code becomes an expression of the model, so a change to
the code may be a change to the model. Its effect must ripple through the rest
of the project's activities accordingly.
To tie the implementation slavishly to a model usually requires software
development tools and languages that support a modeling paradigm, such as
object-oriented programming.
:therefore:
*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, even as you seek to make it reflect
deeper insight into the domain. Demand a single model that serves both purposes
well, in addition to supporting a fluent ubiquitous language.*
## Hands-on Modelers
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. If developers don't realize that changing code
changes the model, then their refactoring will weaken the model rather than
strengthen it. Meanwhile, when a modeler is separated from the implementation
process, he or she never acquires, or quickly loses, a feel for the constraints
of implementation. The basic constraint of model-driven design---that the model
supports an effective implementation and abstracts key insights into the
domain---is half-gone, and the resulting models will be impractical. Finally,
the knowledge and skills of experienced designers won't be transferred to other
developers if the division of labor prevents the kind of collaboration that
conveys the subtleties of coding a model-driven design.
:therefore:
*Any technical person contributing to the model must spend some time touching the
code, whatever primary role he or she plays on the project. Anyone responsible
for changing code must learn to express a model through the code. Every
developer must be involved in some level of discussion about the model and have
contact with domain experts. Those who contribute in different ways must
consciously engage those who touch the code in a dynamic exchange of model ideas
through the ubiquitous language.*
## Refactoring Toward Deeper Insight
Using a proven set of basic building blocks along with consistent language
brings some sanity to the development effort. This leaves the challenge of
actually finding an incisive model, one that captures subtle concerns of the
domain experts and can drive a practical design. A model that sloughs off the
superficial and captures the essential is a deep model. This should make the
software more in tune with the way the domain experts think and more responsive
to the user's needs.
Traditionally, refactoring is described in terms of code transformations with
technical motivations. Refactoring can also be motivated by an insight into the
domain and a corresponding refinement of the model or its expression in code.
Sophisticated domain models seldom turn out useful except when developed through
an iterative process of refactoring, including close involvement of the domain
experts with developers interested in learning about the domain.