Silicon Valley Patterns Group
18-Nov-2003
Domain Driven Design (Evans), I.
Notes by Jeff Miller
This meeting revisits the final published form of a book that SVP reviewed
in an earlier draft two years ago.
Russ: (introduces Eric Evans as author). The group spent 9 weeks 2 years
ago with an early draft of this book. It was already good, and has matured
since, so we should have high expectations. Anything to say?
Eric: I’d like to let it speak for itself. I found the group’s input
very valuable during the reading of the draft. It was very helpful to
me. Now what I’d like to do is focus on what can you get out of the book
and how can I give back to the group.
Russ: We have some faces from the Thursday group, now that the Thursday
group has finished their track through the Gang of Four patterns book.
I know that there is some interest in starting a reprise track on Thursdays.
There are some other
interesting potentials for future readings, including new books and books
in progress. Maybe we can talk about that up front later.
Russ: So again, to open, remember we’re focusing on getting information
rather than providing help to the author. Do people have questions on
the conversation at the beginning, the printed circuit board example?
Robert: It feels pretty representative in terms of the level of congruence
between the software guys and the domain experts.
Eric: It seemed to me to convey… first, it was a domain that I knew
nothing about, so it was an example where the software guy didn’t know
anything to speak of about the domain. It also had interesting behavior
on the object side. I had another complete version of this with a different
scenario, but some of the readers of the draft said that the objects were
really a data structure, not too compelling as a first example.
(discussion of drawings schematically representing the domain, some are
more domain specific in style, see page 41)
Eric: But eventually you want something that could represent the object
model. From the early, domain-specific diagrams, I move toward UML. Domain
experts can usually understand it without much trouble. But deciding whether
something should be a class or a method, that is probably in the realm
of the software developer rather than the domain expert. But the whole
sequence of interactions should make sense to the
domain expert.
Charlie: Do you always start with boxes, to UML-style things?
Eric: I jumped into the conversation at just about the point where I
could start drawing boxes. But it also shows the way that we were communicating
in a frustrating earlier period where we were trying to define common
terms. So when I
looked at all the use cases, they all mentioned nets. What’s a net? It’s
something that connects several chips. So chips and nets became objects
in the model. When the words and the pictures and the explanation all
match up, for the simple cases that you can become confident about, and
you can draw some simple UML models that the domain experts can understand,
that’s where you start. I stay away from the more
complex UML, maybe as far as I go would be diamond for aggregation, or
perhaps numbers on each sides of a line to describe how many instances
might be associated.
It’s not enough at this point to build a system, but it’s a step toward
building a common language, partly visual, partly verbal.
Jeffrey B: So what you’re saying…when you have a conversation, and
you draw boxes, and have the domain expert confirm that how you describe
them is how they would
describe them…
(pause to finish ordering food, get coffee and salad)
Eric: So on the subject of Figure 1.1, I don’t want to emphasize UML.
When I sketched the boxes … eventually the layout person found a font
that looked really hand-drawn.
I didn’t want to emphasize the diagrams by showing them rendered in this
crisp, sharp way. That’s why I show them as if they are roughly sketched.
Tim: I’ve seen that people who have multiple names for the same things
sometimes have trouble understanding UML. They make connections implicitly,
and it takes a while to drag out that information. And they describe different
connections under different preconditions.
Eric: This sounds like you were getting into more sophisticated questions
about modeling, rather than about notation.
Tim: So I’d draw a representation, and they wouldn’t understand that
the diagram was trying to capture all the connections, all the information.
They’d carry along their
implicit knowledge of relationships.
Jeffrey B: People with a background in OO, they understand about why
you might break things up, to separate responsibilities. It can confuse
people who don’t have
this background of analysis and design about why you would break things
up a certain way.
Jeff M: Q: to get a little phase-ist here, isn’t this a question of the
design phase rather than the analysis phase? You break things up when
it becomes important to turn them into objects and collect groups of related
responsibilities.
(Eric makes a gesture of warding off evil re “phase-based”
software development)
Jeffrey B: I think that maybe the conversation here may go too quickly
toward the design, rather than capturing information at a higher, summary
level.
Russ: So when you’re drawing at a whiteboard, are you introducing more
words to the language, or are the domain experts?
Eric: I usually listen to them talk, and then draw and label boxes. It’s
rare that the domain expert will add something to the diagram. But even
before the first diagram,
there’s a lot of talk. You never know where the initial discussions will
take you, but it gives you a place to start. For the circuit board example,
I learned early that a chip
can connect to many nets, a net can connect to many chips.
Tracy: So maybe you have some concept about chips, and wires, and nets.
But do you really understand what they mean by these terms that you think
you have in common?
Eric: And in the other direction, there were cases where unfamiliar terms
in the domain experts’ vocabulary got turned into terms of more common
use for the ubiquitous language. For example, they talked about “Ref-des”
rather than
“component”, which was the word that the common language later
settled on.
Russ: How far down do you go in modeling?
Eric: As far as is useful. That’s how you make a judgment on a model,
if it makes hard things easier. There’s always more than one way to model
things. Occasionally there may be two models which are equally useful.
Like a mathematical iteration, you don’t necessarily have to start out
your model in a good place. With any sort of reasonable starting place,
you will converge, following an iterative path. And you may
converge on a different valid solution, a different useful model, than
you would from a different starting place. For example, if I had started
out with the Signal as an
object rather than the Net, I would have ended up in a reasonably useful
place. If you get down to a point where you’ve gone a long way down the
path, and the model is
not feeling like it’s solving your problems, it’s useful to pull back
and ask if some of your initial assumptions were wrong.
Russ: So if you started with wires and endpoints?
Eric: I could have, but I imagine that I would pretty quickly find out
that it was below the level of abstraction at which the printed-circuit
designers are actually operating in
creating their designs. Later on, talking about “deep modeling”,
with respect to the shipping model… you have cargos, ships, containers,
places to pick them up and
drop them off. But it ends up more useful, rather than thinking about
ships, that thinking about a “voyage”, about some cargo capacity
available from point A to point B at a time, is the right way to think
about planning and allocating cargo. And you find out that even though
they may talk about a ship, the ship is not the thing they care about
in making their plans. They could substitute a ship at the last moment.
Russ: So what would they say?
Eric: That would often come from their side, the domain expert would
ask, “why are you fixating on particular ships? We care more about
voyages… ” If a ship doesn’t
usually have a meaningful identity to them, if it fills a role of “cargo
capacity provider”, then perhaps ships are secondary to the model
which helps the domain person the most. Later in the book I spend time
talking about how to /listen/ to the
domain expert. There’s a difference between a model and a language, but
they are tightly bound, and it helps to listen very closely to how the
domain experts would
naturally like to express their concepts. If the domain experts are tripping
over the language of the model, perhaps the model needs refinement. Or
perhaps they’re not
quite familiar with how the model is expressing the concepts in the domain.
I don’t believe you should have an important abstraction in the domain
part of your design
that your domain experts don’t understand. It comes up all the time because
software developers are good at abstraction, often better than the domain
experts.
Russ: I’m wondering if you have any rules for words that you might hear
in describing the domain, or the design, that indicate a need to dig deeper.
My “watchwords” for “needs more information”: “thing”,
“stuff”
Charlie: “activity”
Tim: “manager” (an object which is a “cargo-manager”,
perhaps).
John: When you see their arms waving off into space, or in CRC card design,
pointing to a blank card as an actor in the design.
Patrick: When is a noun used to describe the domain not an object in
the model?
When it’s too vague or abstract.
Russ: Or when it’s over-concrete, like the wires in the printed circuit
design.
Eric: I find that “nouns=objects, methods=verbs,” is often
a better way of explaining OO programming rather than a way of doing it.
I would lay aside that whole thing.
Russ: Do you have rules-of-thumb for the early stage, for retaining meaty
pieces of information that will make it into the eventual domain model?
How do you keep yourself from going out too far into the woods on irrelevant
detail?
Eric: Well, it’s sort of a question of use cases. In the printed circuit
board example, we started with a use case that ended up as a “nice-to-have”.
The objects and concepts that came out of it weren’t all retained in the
domain model created with the application. But it ended up being valuable
in developing understanding of the model in depth. I would rather end
up going down a path where we threw some stuff away,
as long as we chose a use case that had some behavioral meat on it, not
too far off the mainstream things to do, but related to the core objects
of the system.
Tim: Would you ever pick something smaller to try and get the communication
dynamic with the domain experts going? So, assuming you have some idea
of the system, might you pick up a well-contained chunk that neither you
nor they think is
the most complex, but it would help to get into the give-and-take pattern
of crunching knowledge?
Eric: It might in some cases be useful to start out off on the side,
but I really advise people to start out close to the core domain. For
this PCB example, the use case we
chose really allowed us to explore the domain well, even if we didn’t
implement it as a story in the end.
Carlos: Do you delay putting things down on paper or on a whiteboard
to avoid steering the conversation into premature concreteness, to avoid
fixating on early things?
Eric: I haven’t found this too much of a problem. Usually I can get people
un-fixated. You don’t want to do it too early, you need enough background
to find a starting place. By the time I describe, entering the printed
circuit conversation, we’ve had
maybe a couple of days of discussing use cases.
Carlos: When do you start writing things down for the model?
Eric: Whenever it feels like it’s time. But if it doesn’t feel useful,
you stop and go back to the use cases. There’s a tremendous amount of
trial and error in the process,
brainstorming and experimenting. You’ll have a lot more bad answers than
good answers. You have to keep throwing up more models, more variations,
more possibilities, and going round and round, back to the use cases if
you need to ground
yourself.
Charlie: For use cases, do you prefer them to be verbal descriptions?
Or in some particular format?
Eric: I wouldn’t be too prescriptive, a lot of things work. I’d rather
just say that any form would work, as long as it’s pretty concrete, really
talking about what is the system doing for the user that is useful to
the user, not just the user interacting with the UI. More like the Cockburn
trimmed-down sort of use case. Not as high-level as, say, “book a
cargo”.
Jeff M: Sounds similar to Larry Constantine’s “essential use cases”,
especially the focus on value to the user.
Russ: I like this phrase, “powerful new features emerge as corollaries
to existing features” as a benefit of a good domain model. Will we
read more about that?
Eric: I hope so. If you think about software as changing and evolving,
I’ve seen several paths it can take. Either, it’s typical, it changes
quickly to start, then slows
down, then slows to a point at which it’s considered “legacy”
and continues to run, but changes little. Or sometimes the code starts
slowly, but can accelerate in
development at a certain point.
John B: So is refactoring more about preventing the progress from slowing
down, and deep modeling about enabling acceleration of progress?
Eric: Yes.
Shiva: How do you avoid analysis paralysis?
Eric: Don’t separate analysis phase from design. Code up a prototype
that you can demonstrate and play with to help discuss what was needed.
If you get a wrong
answer, then it helps the domain experts catch an issue, discuss it with
you, clarify it.
Until you get through a full circle, use case, design, and prototype,
you’re not really firing on all cylinders. Analysis and design are really
based on each other, fused together, which is another reason why it’s
important to have a running prototype early, based on the model.
(Ubiquitous Language, p. 24)
Russ: Do you have some thoughts about, to name a couple of examples,
“toast and dumptrucks”, programmers’ metaphors that don’t communicate
with the domain experts.
Eric: Perhaps you could model the system that way. For example, you could
model creating a shipping route as a parse tree, or an interpreter. But
that’s not part of the
domain model. You could have a component which provides a routing service
that uses these computer-science metaphors, and it may be the most useful
way of
handling the problem of constructing a route for a cargo. So when people
talk about wacky metaphors, you may abstract a descriptive pattern or
map of what the system
is doing, but you have not captured the meaning of what it is doing. A
metaphor or model defined in colorful terms can simplify your entry into
a complex body of code,
but it doesn’t really help you see the purpose of the complex activity.
Robert: So… why do you think “regular” software development,
often lacking a good domain model, works at all?
Eric: I don’t know. Victorian machines certainly worked. They were complicated
things, looms driven with programs punched on cards. The end result is
whatever the machine is intended to produce, but if you all those moving
parts, they have no
meaning in isolation. That meaningless intricacy, the endless detail…it’s
what you might see in a movie to convey the bewildering feeling of being
caught in the gears of a machine. Modern machinery tends to be simpler
to the eye because the control has been extracted from the machinery.
Russ: So, to those of us who haven’t worked in enough dysfunctional shops,
maybe you could outline what you’re contrasting it with?
Tim: I’ve got a few examples. With a few previous failures, management
stops thinking of products as members of a product line… “just
kick it out the door, we’ll fix it later” and “oh, that one
didn’t work? Let’s start over.” No attempt at capturing or identifying
the domain, or understanding the connections to the problem. We ended
up having to add more special cases, more exceptions, more conditions.
We never have the case where a new feature was, “aha, we can drop
that in quickly, right there, there’s a space for it!”. The most
successful managers at dysfunctional companies leave right before the
inflection point.
John B: Mozilla is a good example. The Netscape code was running fast
from 1994 to about 1997, and the code got more brittle and harder to work
with over time. You could look at the CVS tree.
Eric: I’d contrast a domain-based approach with conditional logic…pages
and pages of four-deep nested ifs, elses, whiles. No abstraction.
Eric: It’s hard to recover once you’ve gone down that path too far. I
recall with one client, there was a chunk of business logic. And then
in the middle of all that was a subroutine that checked for dangerous
Javascript. So I thought that at least they could move it out into a utility
class. I looked to see if it was used. And I saw that it wasn’t used at
all. But the same method signature was implemented 4 times in different
places, looking like copies of one another. The point is that once you’ve
got a big system that’s built like that, it’s really hard to get out of
it.
(some discussion of “who’s left the dead code in there?”, “who’s
made the copy?”)
Charlie: In software I worked on, developed by a small team quickly,
there ended up being the same fields, essentially, called by three different
sets of names in the database, the domain layer, and the UI.
Eric: Even in dysfunctional groups, where there isn’t a ubiquitous language,
you end up having little groups each using their own terms, and they you
have a couple of the
best developers translating between the terms used by one group and those
used by another — the database, the UI, the other parts. It’s easier
just to translate than to
try to bring the language back together.
Eric: Do I emphasize speech enough? I feel that the speech center of
our brain is one of the best modeling tools. You can say, “a net
connects chips”. You can draw diagrams, but they are often hard to
relate to what we can describe in speech.
Debbie: So even written language may not be a good substitute. In written
language we tolerate more complexity, as we spend more time in writing
and reading.
Eric: But it’s not as fluid. In speech, we could go through a hundred
variations of a model in an hour. You really need that. Tweaking the little
pieces, changing the nature of a relationship, dropping an object, it
makes things a little better. When I’m really working with a domain expert,
I need to move quickly and fluidly.
Robert: So in a traditional project, you might have that cycle once a
year.
Debbie: So if you don’t have a real domain expert, or the domain expert
is busy with their other responsibilities…they might want to send off
their requirements.
Eric: You can do this to some extent with a set of developers, to talk
with one another, to refine their understanding.
Carlos: Speaking exposes awkward terms in a way that writing doesn’t.
Eric: Even reading out loud is enough like speaking that it picks up
these things. I don’t want to overstate these things, because a software
model requires you to be much more structured, more restrictive than in
a natural language.
Jeffrey B: I often feel like I wish I could roll back something I said
in a discussion, to capture the words I just spoke which were the perfect
way to express something.
Russ: We need to Tivo ourselves.
Eric: Like those people who wear cameras everywhere they go.
Russ: When you mention “pidgin”, not sure why you’re ringing
it up here. Isn’t the ubiquitous language a subset of the domain experts’
language?
Eric: No! You’re not trying to shield the domain experts from the process
of development, since the model, the terms of the ubiquitous language,
needs to be useful in designing a software system. The way domain experts
would be happiest to describe a problem is not a way that you could use
to program a solution for them. That’s why I introduce pidgin as a metaphor
for the ubiquitous language for modeling the domain and the application.
p. 34, Venn diagram of overlapping ovals, the center overlap is the realm
of the ubiquitous language.
Russ: Is the pidgin in there? (pointing to the center)
Eric: Yes, there is some of that. And you do learn some things in the
right side, the business terms and context that may not appear in the
model.
Russ: What part of the technical side shows up in the overlap?
Eric: Objects. But the domain experts’ world is probably not broken into
objects in the same way a software model would break things into objects.
For example, a “voyage” may be an object in the model, where
they consider it something that
happens. And I didn’t mean that you couldn’t invent an abstraction that
the domain experts hadn’t already created. You might break a piece off
one of their abstractions
and re-cast it in a way useful for the system.
Russ: Though in terms of the vocabulary of the ubiquitous language, it
sounds more like a subset of the terms used in the business arena rather
than incorporating technical language.
Eric: You don’t want to introduce purely technical concepts, but the
way we break things down for software purposes shows up in the structure
of the ubiquitous language. If you just brought a panel of shipping experts
together, they could create a model of their industry, but it wouldn’t
be an /object model/. That’s the technical aspect which shows up the most.
There’s a /thing/, and a /thing/, and a connection between them, and there
are actions that can be taken on them.
Russ: So would a rule be something like that, a layout rule, a way of
expressing what they’re doing that the domain expert might not have thought
of?
Eric: Yes, perhaps the overbooking rule. If you ask an expert, “is
an overbooking policy a separable thing”, they will answer “yes”,
but they won’t have the OO point of view of thinking of it as the same
order of concept as a ship or a voyage or a cargo.
Mark: People think about what happens, not necessarily breaking it down
into the terms of objects and responsibilities.
Eric: You could apply probably half of the book in a non-OO context,
though that is what I’m most familiar with. Getting knowledge from your
domain experts, “grinding it down” until you have what you need
for your model, these would be common factors.
Patrick: Does OO frame of mind bias you toward creating more objects
than you might need?
Eric: Since everything is an object in OO development, you are forced
to express everything as an object in one way or another.
Patrick: But does that impede communication with your domain experts?
Having too many objects?
Eric: Then you may need to pare down your model.
Russ: Objects are a nice way of breaking down many problems.
John B: Not something that’s primarily rules-based, for example.
Mark: Yes, people tend to think about business rules, usual flows of
work and exceptional cases, it’s hard to translate that into object-speak.
Eric: And mathematically oriented models are also not so naturally matched
to objects.
John B: Or classic E-R relationships, in a database context.
Tracy: Eric, I think you and I have both have an experience like this.
When you discover a new insight, and all of a sudden see that what you
have isn’t quite
matching what you really need for your model, what often happens is that
the model collapses down into a finer, more perfect example. And a lot
of objects just go away
in the better-matched model. Russ and I had an experience with this happening.
The new model was so simple that it was almost embarrassing to present,
but if you looked at it, you wondered if you could have done it any other
way.
Eric: If you find that you can compose your model components in flexible,
powerful ways, often your application logic will get much, much simpler.
Or you probably haven’t got it. That’s what you’re going for. I relate
model and language on a lot of
different levels. Your application code is /saying things/ in terms of
the model language. And when you really get it right, not that your domain
experts will be able to read Java, but you could sit there with the domain
experts, and translate it line-by-line into how they would express it
in terms of the model.
Russ: A lot of people report that their domain experts can read their
unit tests.
Eric: When you design for testability, you are also designing for something
that is easy to manipulate, and easy to explain.
[Some discussion of the shipping example, the “overbooking allowance
of 10%” re the code sample on p.19… when to change “*1.1”
to put in an explaining variable for “1.1”, or perhaps “overbooking allowance = 0.1, compare
voyage capacity * (1+overbooking allowance) to the booked cargo size.]
[some discussion of 0.1 as a non-terminating binary fraction which might
cause a rounding issue; discussion of accounting for pennies in a banking
context]
Russ: I liked what you said about documentation. (p.37-40). About XP
focusing on the running, functional aspects of code. Though there are
aspects of code that can
get out of date, like naming conventions.
Tracy: We had an experience where the domain experts had decided they
needed to change a name to make it more clearly express what they meant.
We had to translate
for a while since the code had the old name, and it was uncomfortable.
Russ: And it was pretty tedious to change all of the names of the places
it was referenced.
[…]
Eric: I feel that in Java, where you’ve already had to declare the type
of something three times, if you can find a name for the variable reference
that expresses something more, it’s best to do so. Something like “nextDepartingShip”
rather than
aShip.
Jeff M: So it may be better to find a way to express a reference name
as a role, perhaps, rather than anInstanceOfSomething.
(some return to naming discussion re overbooking allowance)
Debbie: The biggest missed opportunity I see for local variables is to
name one “result”. I often have to read back to the beginning.
I prefer something like, say, matchingEmployee” rather than “result”.
Charlie: I have conventions for naming return values.
Eric: Maybe we’ve drifted a little off the topic, but I feel it expresses
something about this style of coding — that naming instance variables
within a method is tying it to
the model, the ubiquitous language reaching down into the finest grain.
That’s why
it’s important, I think. In other modeling books, we’d be talking about
high
abstractions, and here we’re talking about the details of practice that
make things
work.
Charlie: As I’ve worked, I’ve found it more and more important that you
choose the
best name.
(discussion of object-relational interface as a place where changes in
the model may
be slow to propagate, or the cost of change may be a deliberate choice;
domain layer
and UI is another possible interface where you may have to work to maintain
a
ubiquitous language)
(discussion of “watershed moments” in losing agility — first,
where you have a
database; then, when you have data you can’t just throw away but have
to migrate/
preserve)
(discussion of comments, commenting styles, limits of translating comments
into
self-expressive code, usefulness of explanatory comments)
Charlie: There are some books we’ve read that seemed a little rough,
but were too
close to publication for our comments to make a lot of difference. It’s
really
gratifying to see how good this book is, in its final version.
Eric: I’m glad the work shows.
Tracy: I think the addition of the examples really adds a lot. And the
explanation of
the back-and-forth, so that we see you learning as you go. I think it’s
going to be a
classic.
Jim: I’ve been reading and re-reading these first three chapters. This
is great stuff,
and if people really read it, they will make better programmers.
Attending:
Tim Huske
Carol Thistlethwaite
Patrick Manion
Walter Vannini
Wayne Vucenic
Mark Taylor
Robert Benson
Russ Rufer
Debbie Utley
Jeffrey Blake
Ken Scott-Hlebek
Carlos Sepulveda
Shiva JayaramanBatman/Tao
Tracy Bialik
Jeff Miller
Chris Lopez
Charlie Toland
John Brewer
Azad Bolour
Jim Sawyer