25-Nov-2003
Domain Driven Design (Evans) II.
Notes by Jeff Miller
This meeting revisits the final published form of a book that SVP reviewed
in an earlier draft two years ago.
(some comments and questions unattributed)
(notes start with discussion in progress)
(previous to this point, Eric compared and contrasted model-driven
design with domain-driven design)
Eric: It depends on whether you demand that the classes in your model
have meaning in the domain.
Russ: “bits of responsibililty”
Eric: It matters that the classes in the model… The reason some
models give you that kick is that they are are close to the domain.
Robert: Is it easier to refactor the model, classes and objects, than
services?
Russ: Let me do a quick check here. “Most talented developers don’t
have much interest in learning about the specific domain in which they
are working” ? (p.4) How true is that?
Robert: Probably, let’s say, at Sun Microsystems, your domain is
technical stuff you’re doing for someone else.
Eric: That’s cheating. That’s the exception that proves the rule.
(“developers get interested in the domain when the domain is
technical”).
Russ: Let’s exclude technical domains, then. What do people think?
Mark: Key word… I think “talented” is misplaced. I’d use
the
generalization without this word.
Eric: You may be partly defining “talented” as a person with
enough
insight to be interested in the domain.
Russ: And connecting “talented” with “successful”.
Mark: People may not care about “widgets” in the product sense
rather
than the GUI sense. The only way you can care about it is to really
learn it.
Eric: Often on larger projects there’s an infrastructure team broken
off… The most talented developers get to pick what team to be on.
Where do they end up? The infrastructure team. They don’t work on the
account reconciliation feature. Instead they do fancy framework
generalization about the UI or something.
[…]
Eric: I’d certainly like for talented developers to have interest in
the domain. When they were working on the account reconciliation code,
they did a better job than the person who replaced them. So part of
what I’m hoping from domain driven design is that we could give the
talented person a better way to think about the domain, a way that it
can be interesting. I don’t think the group here is representative.
Russ: Of talented developers?
(general laughter)
Eric: Present company excepted.
Chris: Technical knowledge is often more transferable than domain
knowledge.
Eric: And the way domain-related development (notice I don’t say
domain-driven development) is done is often very boring. And when you
add things to your resume… if you say you have mastered the specifics
of the cargo handling operations at a port, it would just be clutter.
You wouldn’t put it on at all.
Chris: Yes, accounting, finance, there are a few generic, transferable
domains that would count.
Eric: And does your peer group of other developers… they think you’re
really smart when you can do cool technical tricks. Do other
developers think you’re smart when you find a better way to reconcile
accounts? No.
Tim: Interest…my personal interest sometimes in the complexity of a
domain. Multi-state tax law for multinational companies. So if I
tackle it as a complex problem, it’s interesting, but if I got assigned
to it, it’s not clear at the outset that it’s actually quite an
involved problem. Now I’m working on music playlists, I’m a little
more interested in the domain.
Eric: If people in some domain want a new application to do something
more than create, read, edit, delete… It’s like you’re a
15th-century physicist.
Q: “Getting your head chopped off?”
Eric: Sometimes, perhaps. People may not support and understand your
way of thinking. But think how exciting it could be to be among the
first to see rhyme and reason in how things move. Before that, people
would speculate on motion, and often they got it wrong.
John B: It’s a very similar analogy, actually, to what often happens
in
software development. Speculation rather than testing.
Eric: We’re still at that level with domain modeling with most domains.
There are a few that are better done, say accounting. There are some
powerful abstractions, a ledger, credit, debit, double-entry. It’s
well on its way. But most other domains are virgin territory.
Eric: What’s missing… what’s missing is the idea that domain modeling
is a discipline. Saying “I’m good at diving into domains, finding
a
model, building software based on that.” Being able to put that on
your resume, having it mean something among your peers.
Chris: I’ve certainly seen contract positions advertised for people
with skill doing domain modeling. They call them “Rational Rose
Modelers” or “UML modelers for the domain.”
Eric: I guess there’s a silver lining in that cloud.
Russ: Are you sure it’s silver?
John B: There’s this meta-skill, then, domain modeling, that you can
capture, otherwise you couldn’t write a book on it.
Eric: Well, I guess _I_ couldn’t write a book on it if it didn’t exist.
Q: How do you tell if you have a good model for a domain, vs. a good
architecture in the model. You were saying that there are a lot of
things in the domain that aren’t captured well by UML.
Eric: Perhaps it would be best to keep moving through the material to
answer that question.
Eric: Sometimes, when the code is closely tied to the model. You
might choose to move a method, to re-assign a responsibility. That can
mean the model has changed; the model in your head, not necessarily a
particular UML diagram.
Russ: You had a good example of having to create a larger-grained set
of objects in the system to be able to work well with an object
database, and that caused you to re-think the model and how you were
going to deal with the domain.
Eric: In our original model, perhaps we might call it an analysis
model, we had a large number of small objects in intricate
relationships. It was a serious performance problem in connection with
the database. So we needed to model the problem with fewer objects.
There were 3 possible outcomes: (1) the same concept, but different
implementations, rolling in subcomponents into the object which
aggregates them, absorbing variant behavior; (2) a modified model, not
as nice, but it works; (3) a new way of thinking about the problem that
also works well as a way of breaking down the domain. We had some of
each. But in each case, we said the way we think about the problem
will be tied to the implementation. Maybe the model will not be as
beautiful, but we do have to support it. There might be “teaching
models” to tell people about the domain, but there’s only one domain
model that
Russ: Does anyone have a story about when there was an analysis model
that was at variance with the code?
(1): I had this issue. There were often subtle problems with the
model, things that were not implementable. We had to go back to the
analysts again.
Tim: We didn’t go back to the analysis phase.
Russ: And you’d already used that time?
Tim: Yes. We would have had to cut into QA time. And yes, it was a
problem that the model was not really useful. Did the analysts get
paid? Yes. It met their criteria. Measured against our phase, well,
no. We had a notion of the model, but we were too busy coding
workarounds.
Eric: Did you change your objects to reflect new concepts or stick with
the original ones from the model?
Tim: Both. Sometimes we worked around it with a mapping layer, other
times the model was loosely enough defined that we could implement it
in a reasonably flexible way.
Eric: I’d like to distinguish between “UML”, a representation
of what
someone thought was the model at some time, and “the model”,
which is
how you are thinking about and communicating with the code.
Tim: An interesting part of this is that I’m sure the analysts had a
model which was not the UML. But it was transcribed to UML and we just
had to guess at what was missing.
Eric: UML just doesn’t capture enough.
Russ: Isn’t that what OCL is for?
(2): Usually you give people X and they are happy, occasionally people
ask for X, you give them X, and they wanted Y. But when you hand it
over, it does not provide people what they need to accomplish the task
in the environment — speed, memory use, usability — not a conceptual
mismatch, necessarily, but a poor implementation in terms of the
working context.
Eric: Extreme Programming says, “just don’t try to understand it
all up
front”. So they have elaborate practices to stay customer-focused
and
deliver something useful. You can get something done, delivering
feature-by-feature code. But part of the story is also agility,
responsiveness to changing requirements. Partly it’s things like test
frameworks, refactoring, etc. to keep the _code_ quality high. But if
you have also been using domain driven design, the internals of the
software reflect what the customer cares about and wants to do, not
just the external interface, the services the software provides. So
you need a close relationship with a domain expert. This is not
necessarily the customer who is choosing and assigning value to
features, or the user who will be working about it. There is iteration
in code, while in domain knowledge, there’s what I call knowledge
crunching, reflecting on what you have learned about the domain and
evolving your model to a more representative and more useful state.
Eric: Probably that’s true.
Russ: It goes further than that. By modeling the domain well, by
coding that into the software, you also find that the next thing you
haven’t designed yet, you’re more likely able to fit it into the
existing software because of the way its structure reflects the
structure of the domain.
Eric: XP has more things to guard your process against spinning your
wheels and not making useful progress. You could apply a very
straightforward, procedural approach to an iterative development and
make good progress.
(2): You’re talking about more about architecture, and I’m talking
about features.
Eric: You’ll notice I don’t actually talk about architecture except
toward the end of the book when I talk about architecture teams as a
way to organize larger development efforts. But for a domain with
complex requirements, where there are interrelationships among the
various pieces, then model-driven, domain-driven design is important.
Keith: I’ve worked with code where there’s a model, but it has kind of
evaporated, it isn’t visible in the code as you see it and work with
it. Do you need, at least, a good object oriented language?
Eric: Well, code of that description is not a model-driven design. And
how you get one is much of what this book is about. Especially part 2,
and part 3 is about getting a good one. So modeling — what your
“Rational Rose Modeler” would be expected to do (looking at
Chris), is
the opposite of hands-on modeling.
Keith: In the case I’m thinking about, the team created a model and
implemented it.
Eric: Does it show up in the code?
Keith: You can’t really see it. It’s sort of like a fragmented mirror
or a Picasso painting.
Eric: Then it’s not model-driven design.
John B: “Team = Code” ?
Keith : Conway’s Law? The structure of the code reflects the structure
of the organization?
Russ: I think you were a little harsh about not being able to do
model-driven design in C. You can do object-like stuff if you don’t
need inheritance. We had structures of function pointers, we passed
around a “this” pointer, and everything corresponded and felt
much like
you would feel programming in an object-oriented language.
Eric: I don’t want to overstate it. But I think that choosing the
right language is really powerful. It’s harder to write, it’s harder
to read.
Russ: But I think you could read the code and see right back to the
model we were working with.
Mark: It depends more on the programmer. I’ve seen awful code in C++
and really clean code in C.
Eric: I’m not trying to pick good and bad among languages. But when
you want to do model-driven design…the model belongs to some style,
and mostly these days the model is in terms of interacting objects. So
choosing an object-oriented language gives you code which can be
expressed in terms closer to the model than other languages can easily
express. You need a programming language which supports your modeling
paradigm, whether it’s object-oriented, mathematical equations, or a
chain of logical rules.
Eric: I’d certainly like to see a language that’s better at supporting
object-oriented design than Java. I have worked with Smalltalk, which
I consider to be better, but it is not radically better, not in a
different league.
Keith: Have you considered Scarlet? You write the algorithmic parts,
the object and methods, in one part of the language, and separately
describe how the objects are composed.
Eric: You could consider the current fashion for compiling a system out
of UML and OCL as a programming language which is close to the model,
but I don’t think it’s a good programming language. I’d have to see
Scarlet to see what I think. I don’t want to get into any religious
wars about programming languages, I’d just like to point out that you
want to choose the right tool for the job.
Eric: I try to stay away from the dichotomy between the “analysis
model” and the “implementation model”. Each one is useless
in
isolation, since the analysis model doesn’t tell you whether the system
actually obeys, say, a constraint you’ve noted in the model. This is
not to say that all parts of the model are equally important, but that
the core, meaningful, abstract concepts from the domain are expressed
in the model that your implementation is based on.
Tim:
Eric: I advise people not to get attached to any particular model.
There are always alternatives, or almost always. If you find that your
original model does not work for building the system, then I take that
as a sign for rethinking the model. So the shift I describe in the
book — from composed groups of little objects, to a stack of tokens
and a parser which interpreted these as a little language. It was
equally elegant, but perhaps less accessible to some developers. And
it reflected a different model, a different way of thinking about and
expressing the concepts from the domain.
Russ: Key points from the introduction?
Eric: One point is not so much about whether you have a good model
(that’s more part 3), it’s about how to keep your model in sync with
your development. If your “smart people” are doing nothing but
modeling, but you don’t implement the model in the terms it presents,
then
(3): Don’t you want your junior people in on modeling, so they can get
mentoring and absorb skills?
Eric: I go further than that. I say everyone should be modeling, and
everyone should be programming. If you aren’t doing that, you aren’t
doing model-driven design. You have to do modeling as you program.
Russ: Let me say something heretical. What if you had a “thinker”
and
a “coder”, and the coder goes back whenever there is a problem,
and
asks the model to be adjusted and fed back. Is that model-driven
design? Clearly there are communication costs.
Eric: I guess that could be model-driven design. But if you adapt your
implementation to be more do-able, you introduce a change in the model.
I wouldn’t advocate that. You want someone’s eyes on the code who
understands the model, and can recommend whether it’s consistent with
the model to tweak the code a bit for the sake of implementation, or
whether there is some issue in the model which needs to be re-thought.
Every time I’ve seen this approach succeed, the people who had created
the model were also participating in coding it.
(1): Scaling of this approach?
Eric: Part 4 of the book discusses this. But there are also issues
about how to partition the model into chunks which make good objects
(Part 2).
Russ: Like the comparison between the elements of the model… and
saying that they are not things that you try to identify like
constellations in the night sky.
John: I see that when people try to reverse-engineer a system. They
look at all the stars, and say, “well, there’s a scorpion in there
somewhere.”
Russ: And you can extract the patterns with an automated tool.
Chris: (p.70) You seem to have defined the “application layer”
very
strictly. I might equate it to a “services layer”. There is
some
business knowledge, often, in doing things like exposing tasks, in
doing error handling. That amounts to business logic. Recovery
strategies in the case of failures, perhaps.
Eric: I might not want to put those in the application layer. I talk
about services in the domain layer, services which are fundamentally
domain behavior, and others which are more application behavior.
Chris: I agree that there are two kinds of services. But I find that
even in things, like services for aggregating network traffic, there is
some business logic.
Eric: All right. Then there’s a little workflow in there. But you
want to push it back if you can. A lot of workflow is not really
business related. Things like going from screen to screen in an
application. Or having an application which constructs a new account
in a particular way, but it doesn’t necessarily matter that you do it
in that way to the domain.
Chris: I’m thinking of metaservices, which call to services which exist
in the domain. Have you worked with Struts or JFaces?
Eric: I’ve been on such a project, but I wasn’t involved in that part
of the application.
Chris: I wanted to ask about applications of Struts or JFaces which
might be either in harmony with this approach, or at variance with it.
Eric: J2EE entity beans, I guess the recommended way to use them,
really separates your data from your behavior. Does Struts carry
baggage like that? I don’t know.
Chris: What I wanted to see is if the recommended or common patterns
for using Struts were problematic. As an example from a different
framework, say, the .NET suggested practice of exposing RowSets all the
way from your database up to your UI objects?
(discussion of Microsoft approach… view through to the database as
a
way of scaling through stateless servers)
Azad: And what you might call, not the “Smart UI”, but the
“Smart
Database” pattern, controlling things with stored procedures. For
certain applications, you can get quite a ways with this approach.
Eric: You could make it work in a model-driven way, but your modeling
paradigm would have to be in terms of entities, relationships,
triggers, etc. It strikes me as a rather masochistic way to do
modeling.
Russ: That’s kind of a lead-in to the Smart UI pattern.
Bob: First… having the domain objects responsible for persisting
things. But unfortunately I’ve seen readers and writers all over the
system, knowing bits and pieces about the serialized form, breaking
encapsulation. I wanted to check in about where you were going.
Perhaps “what” should be persisted should belong to the domain
object,
and “how” should belong to the implementation?
John B: I think that is Chapter 6.
Eric: Yes. Let me just refocus on the goal. When you’re looking at
the domain object, you can think about its domain meaning, not about
the implementation details of how it talks to the database. If you
have a framework that lets you disentangle the domain meaning and
behavior with the implementation.
Bob: I’ve used Aspects a lot lately, to isolate things like
persistence.
Eric: I’ve dipped my toe into this, and I thought it was neat. But
I’d just like to focus on whether the persistence framework helps you
read the code in terms of its domain nature (or at least gets out of
the way), or whether it does not.
Russ: I was curious to know about how aspects and refactoring interact
in practice. How well do they work together. Bob, have you been using
Aspects in a serious way?
Bob: More playing at this point, but I can give you a pointer to a blog
from a fellow at Microsoft, an entry something like “A Year With
Aspects”, where he talks about the difficulties with multiple aspects,
dependencies and duplications, after working with AOP for a while.
Azad: How does the model interact with documentation?
Eric: If you start with the core notion that the model is a set of
concepts that you want to be able to communicate, to understand, to use
in talking about the domain and the software implementation, then any
way of documenting that is compatible with that is reasonable.
Azad: Or if you were dealing with something that was more heavily
rules-based. Or when your domain experts are expressing the domain in
different terms than you find useful for implementation.
Eric: I’d recommend using the same style for capturing domain knowledge
from the experts and for designing and implementing the system.
Azad: No question about that.
Eric: Or have a rules engine and integrate that into the system. But
it may be worse than modeling their rules as Java objects. You still
need a ubiquitous language which you can communicate in terms of the
domain, in terms of the design, and the implementation.
Robert: Perhaps in a lot of domains, there are a lot of little surface
rules in the processes you go through. But in order to build things
that will go a longer way, I feel there’s a danger in not trying to
discover the objects.
Eric: The concepts of the domain.
Eric: It’s hard to carry two models with a mapping between them. The
mapping is itself a modeling problem.
(4): Or in some languages, being able to overlay knowledge about how
to
connect things, to expose different ways of
Eric: So you’re introducing candidate abstractions into the language,
in the terms of the domain?
Russ: So if your domain experts are not communicating in terms which
map very closely to the system you are building, you’ve lost a lot of
their expertise.
Azad: So I think that we disagree on one little point.
Eric: “Never do it” on my side, vs. “Avoid it.” But
when I expressed
it that way in the book, the reviewers recommended that I remove all
the caveats and reservations. I really do believe that whenever there
is one model for talking to domain experts and another model for
programming, then we are really missing the boat. We won’t get the
agility in the design.
Azad: Partly what I was trying to express was that in the currently
popular programming language, whatever that might be, there may be some
concepts that are key to the domain that aren’t easily mapped or
modeled.
Mark: Something I wanted to ask that isn’t in the book so explicitly
… trying to get the developers to buy in, having the whole team
involved … but what about management? How do you change the culture
of management to allow teams of developers to do these things?
Eric: Managers are very buzzword-driven. If they are interested in the
buzzword (today maybe it’s XP, tomorrow maybe Domain Driven Design),
you’ll be more likely to be able to do it.
Robert: Managers also pay attention to success as well as buzzwords.
You try and make strong connections between this approach and
successful projects.
Eric: On the web site, there’s actually something called “Managers’
Guided Tour To Domain Driven Design”
Mark: Is it in PowerPoint format?
Russ: A good lead-in to Smart UI. You really need forward-looking
management to take on model-driven development with nice testing and
all that. Smart UI gives you a quick burst of productivity up to a
certain point, then you run into a point where you can no longer scale
it. Model-driven and domain-driven… you start with something kind of
linear, lose a little from complexity, gain some from the set of
strong, interacting abstractions. It takes a little while for the more
advanced techniques to really bring home their benefits.
Eric: I do say that MDD is more important for cases where the domain
is
complex.
Bob: It’s robustness. YAGNI works if you don’t have to go back and
touch it. MDD is about robustness. A small change in the problem
domain is a small change in the objects and classes.
John B: XP’s “system metaphor” speaks to this.
Eric: YAGNI applies a lot in model driven design, as well. For
analysis modeling, you don’t have something that tells you when you can
stop.
Eric: Do the _simplest_ thing that can possibly work… it might be
really hard. Thinking profoundly in order to express the problem most
elegantly and most simply. It’s really a profound breakthrough.
John B: Kent Beck expressed this as a question: “What is the simplest
thing that can possibly work? Why aren’t you doing that?” rather
than
simply “Do the simplest thing that could possibly work.” There’s
a
level of reflection there that’s missing without the questions.
Eric: Especially when you know you’ll have a version 2, you need a
robust way of developing software like model-driven design. There may
be simple ways to solve simple problems where you may not have to use
such techniques. If your problem fits into a pre-existing tool, get it
off the shelf.
John B: I often start with a smart UI. I start in domains where the UI
is the biggest risk. Then I factor the domain objects out of the UI as
time goes on. I’m working on a graphical interface to a text-based
conferencing system, and I can see there are a set of objects wanting
to come out. But the next several stories don’t call for that to
happen.
Russ: And then, when you’ve learned what you can from the first
prototype with the smart UI, you have a choice between factoring out
the domain objects, and retiring the prototype and re-building it.
Eric: You may have different experience from I about how easy it is to
refactor out of a smart UI. My experience has been that when I step
into a client’s place where there isn’t some sort of layered
architecture present, then I often will say that I do not know how to
help them. I’ve had a lot of trouble with escaping from a bad design.
(discussion of experiences factoring out of a smart UI: John B, Russ,
Jeff M)
Eric: Very early in the history of a system, especially if you are
probing for key risks, you can get away with a “Smart UI”. But
if you
plan your system to have any sort of a life in development, you should
plan to have a domain layer.
Bob: How about non-layered architectures. Pipes and Filters?
Blackboard?
Russ: Composite?
John B: Composite sounds like the structure of the domain layer.
Russ: Are we the only people who have made a success out of a
non-layered architecture? (Russ describes a system that separates I/O
and other implementation concerns in specific service classes, but not
separate layers).
Eric: The four-layer architecture diagram I present is probably too
specific. The essence is isolating the domain. Have a domain layer
representing the software constructs relevant to business logic. It
sounds like what you describe is not a layered architecture, but it is
a separation of the domain. It’s too bad it comes across as so much of
a specific prescription.
Bob: For domain-driven business applications, they pretty much do look
a lot like this layered architecture you present.
Attending
(partial list only)
Don Chin
Vince Nibler
Tim Huske
Mark Taylor
Robert Benson
Russ Rufer
Jeffrey Blake
Ken Scott-Hlebek
Carlos McEvilly
Batman/Tao
Tracy Bialik
Jeff Miller
Chris Lopez
John Brewer
Azad Bolour
Keith Ray
Bob Evans
Walter Vannini
(and several more, total 23)