Thursday, October 13, 2016

Domain-Driven Design

thank you all for coming to the stock today I'm glad to see so many people out
here in the audience for this domain driven design talk
so now we're going to be talking about today we're talking about domain driven
design and what wait what do I be when i say a domain domain is a sphere of
knowledge influence or activity
so that's just to be clear that we're all on the same page about what a domain
will be in by domain
this talk is based on the book domain-driven design by eric evans
how many people here have read this book a show of hands to people
awesome i hope that by the end of this talk you are you are motivated to go
read this book because there is way more on this topic that i can cover in a 60
minute 60 minute talks i hope this whets your appetite and get your interested in
learning more about domain driven design also there's a training provided by this
company called domain language this is a company started by eric evans author of
domain driven design the privilege of taking a four day intensive class with
with them and definitely worth it
so highly encourage you if you really want to do a really deep dive into
domain-driven design check out check out the main language more information that
domain language com the key concept behind domain-driven design is the
complexity is in the domain not the technology
so a software developers we tend to think about complexity in terms of our
software the complexity and in the software itself but we have so many
frameworks today and programming the high-level programming languages and so
many tools at our disposal that the complexity really
these days comes from the domain from the actual domain that were modeling so
don't add in additional complexity of the technology that doesn't need to be
there
focus on the actual complexity that exists within the domain that you're
modeling
speaking of modeling in domain driven design we use models as tools to solve
the main problems so model is just a high level abstraction just an abstract
set of tools that were using to solve and reason about the main problems so
don't think of a model just as code model is encoded model is a more high
level , more high-level concepts and just code so model is is an abstract set
of tools
so when I say model and star crafts that's what I'm talking about not
talking about specific code representation and code of the model key
point with domain driven design is to not try to model reality that's not the
goal here
we're trying to create develop tools abstract tools that we can use to to
solve the main problems
I want to show you interesting video here of a illusion called Ames room
so if you can take a look at this video so these two people appear to be quite a
bit different in size
that's interesting optical illusion that's happening here and this is
actually a quite simple illusion
this is just done through through a room with each with a shape like you see here
at this diagram so the person actually is further away than they look
so this this technique is actually used in lord of the rings fellowship of the
ring to make the hobbits appear the correct size relative to relative to
Gandalf
so the point here behind this why bring this up is this an example of our brains
using models to understand the world around us so we're not actually
perceiving an objective reality
we're using a mental model of what a room looks like and we're perceiving
that through that threw that bottle
even though it's completely illogical makes no sense our brains still see it
as one person being much larger than the other
so there is no objective reality we're always wrong with using mental models
whether we realize it or not we're always using models
another example of models out of you can see that ok so which is which model
better Fahrenheit Celsius or kelvin
so personally made this chart obviously thinks that fahrenheit is a better model
but the point here is that it's about models as tools
what - whip whip whip domain is Fahrenheit useful for solving problems
with in one domain would be doing what to wear today
so you know what do you want to know the wet weather weather is outside like it
is like outside celsius and Calvin aren't quite as good at solving that
particular domain problem but if you're doing more scientific work Celsius there
Calvin might be a better model
so again it the point here is that it depends on the context which which model
we're going to pick is a in a factor of what context was trying to solve
problems within to get a little philosophical here
this quote also gets up this concept that the map is not the territory
so what we're talking about here is a is a concept of it's called map territory
relationship where we're always interpreting the world through through a
map where i was using maps and they're always there is this relationship
between a map and a territory in this this concept is illustrated in this in
this painting is this is not a pipe
babe I know what it is it's not a pipe so it's a painting of a pipe in fact
when I could say it's an image of a painting of a pipe or it's a projection
of an image of a painting of a pipe
so this is illustrating that concept of map territory relationship that we never
actually looking at the the territory were always always dealing with these
relationships between the map in the territory
now this is just me have a little bit of fun family wants to scan that gonna slow
joke i put in here
there's a this is not a QR code so so another point here
they're interesting quote along these lines is this quote that everything
simple is false
everything which is complex is unusable so our job as software developers is the
signs find something in the middle between these two points
we need to build something that's not so simple that is completely wrong but not
something that's so complex and so like trying to match reality that it is
completely unusable
so where we're trying to will like the main modeling we're trying to find
something in between these two extremes
another key point with domain driven design is that we want to
collaboratively explore the model with domain experts and software practice
terms so as a software developer
you don't just go work in isolation come up with a domain model this is something
you have to do with the domain expert now if you don't have access to a domain
expert
this is something that's a problem we need to solve first need to figure out
how you're going to get access to a domain expert who you need to talk to to
make that happen because you can't practice domain-driven design without
being able to collaboratively work with a domain expert so ensuring a historical
example of this is a the history of 3d animation so this is actually happened
long before domain-driven design with the idea of dominate in your design came
up but i think it illustrates some of the one of the key points behind
domain-driven design
so there's this guy Edwin capital he was a software practitioner studied physics
and computer science
he made a lot of interesting discoveries in computer graphics field some really
advanced and stuff i'll start out with 2d animation then went into 3d animation
i ended up working at Lucasfilm which of course later became pics are so that he
could bring his expertise to the entertainment field now we take him
combine him with a domain expert John Lasseter he's an animator is his
background in animation was taught by veteran animators at Disney and he
realized
potential for computer generated imagery so he he was a pencil and paper animator
and he realized what computers can bring to the table worked at disney actually
got fired from dizzy ended up working at disney again when they became when they
work pics are so Edwin captain although the the technologists recognize the
importance of bringing on a domain expert so he are hired John Lasseter of
course he didn't have a role for him so he made up a title interface designer
had nothing to do with what he was doing there but gave him a job so he
recognized the importance of bringing on a domain expert
I'm also kind of us trim piece of trivia if anyone ever seen the freebsd be ski
team and that's all that was actually drawn by john lasseter but the key point
why bring up this example is this quote here throughout the process
Lassiter work side by side with the computer scientist last year's request
push them to develop new tools and their feedback help them learn the digital
animation process
so this is this really gets at this idea of working collaboratively with the
domain experts and software practitioners developing new tools and
really pushing the model forward to working side by side together we're
going to apply these concepts first thing we need to do is we have to
understand what our core domain is so what's what's really important here
what's what's the reason why we're writing the software in the first place
so we want to identify that core domain
still it and focus our best resources on that the core domain
how do we distill so we're looking at a given domain that we're dealing with the
way is probably represent one of three things
it's either going to be our core domain it's going to be a supporting domain or
it could be a generic sub domain so core domain that's the reason why we're
building the software in the first place that's the that's the that's the why
it's worth taking the risk of spending all this time on building the software
supporting domain that could still be critical so we really important
but it's not the course not the reason why we're building the software and a
jarek sub domain that could be something like an accounting package or accounting
software where it's this generic concept that the dark already exists
so I said a moment ago you want to focus your modeling efforts on the core domain
some tactics you can take with supporting domains you might want to
consider outsourcing work on those and for generics of Angela might want to use
off-the-shelf software or pre existing libraries first for generic subdomains
how do you identify the core domain so this one here this
this here is useful this definitely useful to talk to the domain experts but
here you also want to talk to organisational leaders people that
understand the strategy while you're building software in the first place and
you want to ask them some questions that will get at and help you i don't
understand what the core domain is so some of some of those questions that
could be helpful or what keeps you awake at night
why is the system worth writing why didn't we just buy it off the shelf
there's gotta be some reason why we didn't just buy some pre-existing
software
why didn't we just outsource it so those are the answers to those questions will
help you understand where the contours of the of the core domain are so you can
really focus your efforts there another important concept is that we always have
multiple models
so there's never just one model so there's all the routers can have
multiple models interacting with each other
so in order to make this possible and saying to work with
we've just a concept called a bounded context abounded context allows us to
tell with in what context a particular model is applicable
so we can say we're working with in this bounded context right now means we're
working with this model later we might be working in another bounded context
working with a different model so allows us to explore each of those models in
isolation and for each pound context we wanted to find who's responsible for it
which parts of the application is this a kind of context applicable to and what
physical manifestations might this bounded context take within our it
within our application what code represents the sound of context what
database schemas so the actual kind of artifacts within our code with any you
within a bounded context it's important to speak a ubiquitous language so with
you with a ubiquitous language you want you to clearly define unambiguous terms
that you use consistently so this is really important when you're working
together with with domain experts so when you're having conversations with a
domain expert you can use the still being like this ubiquitous language to
talk about of further and further more abstract concepts and you can these
terms can have a powerful meaning that you can use to express complex topics
easily in conversation - because language will also end up in your code
so your names of your classes for example will follow this ubiquitous
language your unit tests will use it so is your biggest language will permeate
throughout the entire software through through everything
hence the term ubiquitous and as you work with this ubiquitous language as
you use it and exercise it
it's going to get richer and you'll be able to express more and more complex
concepts with it
now at first when you work with us with a ubiquitous language you'll find it's
kind of rough and doesn't really have some rough edges and doesn't really
quite Express all the concepts needs to express clearly but over time you'll
you'll work with that and and refine that
what talk real briefly about a concept of called strategic design so i said we
talked about behind the context a moment ago
so strategic design we said we have multiple bounded contact with multiple
models
so if you're working on an existing application what you want to do is you
want to identify what bounded context already exists
so we do this through what's called a context map
so what's important here is to assume you're working with existing pre
existing software you want to map it actually exists so you're there is an
ideal of what you're trying to go for how you want these bounded context
interact and how you want them to look but the idea here is to map what
actually exists not what you want to exist and also want to go ahead and
identify relationships between these contacts and there's actually some
relationship patterns will i'll take a look at here real quick
they can help you understand the relationships between bounded context so
partnership
this is where you have two teams working on two different bounded context and
they have a give-and-take relationship so it will work well together we have a
great relationship table 22
that said request back and forth to work together well customer supplier
this is more of a one-way relationship for one party can request things of
another of another party anti-corruption layer this might be where you have a
really messy bounded context with what you need to integrate and you don't want
it to mess up your bounded context you want to keep your model nice and clean
you can create an anti-corruption layer so that that doesn't so that your your
model doesn't get all all messy shared Colonel this is where two bounded
context can actually share share a core piece together a big ball of mud means
just what it says who knows what's going on
there's all sorts of dependencies all over the place everything is
interconnected
who the heck knows a big ball of mud could lead to the next one separate ways
where you just decide you know what we're not gonna integrate these bound
context anymore
we're just going to completely go our separate ways and and not not connect
them anymore
open health service this is one that you're probably familiar with this is a
pretty much any web services API would fall into the category of open house
service where you just put something out there
you say you're welcome to integrate with it like here's how it works
conformist this is kind of the opposite of anti-corruption layer good for mr. is
where you say I'm going to just model my boundary context the exact same way that
they model there so I'm just going to conform to it as as directly as possible
published language this is where the record existing standard that you can go
by
you can reference for example of an atom syndication format around and publishing
protocol could be an example of a published language that you can use
so let's talk about some actual building blocks so some some code we can actually
use to to apply these concepts so all the concepts have talked about so far
can be applied in pretty much any programming paradigm these examples
there are geared towards object-oriented programming so i hope you can see that
this discount these concepts could apply to do anything any program paradigm but
it's likely we're all using object oriented programming here we're going to
be talking about it from that perspective from that perspective
so first concept is an entity an entity is an object that's identified by a
thread of continuity and identity energy has two responsibilities
so you are responsible for two things you don't want to get other
responsibilities
it's responsible for its identity and its life cycle
that's it no other responsibilities that can be composed of other entities other
value objects you can actually end up with an object graph of entities
referencing other entities and other value objects that speaking of value
object value object is something that's not identified by its identity
instead is I don't said it's defined by its encapsulated attributes
so for example a date might be a value object
it doesn't that doesn't have an identity but it's it bores defined by its by its
attributes
now I said it might be a value object the important point with this with here
is that with entities and value objects
it all depends on the context of living within which are working so within one
context
a person might be an entity within another mice might be of value object
telephone number if I ask most view of a telephone number was a value object or
entity
you'd probably say it's a value
object but if you're building a phone switching system the telephone never
mind in fact be an entity not a value object value objects should be treated
as a beautiful
now I'm PHP it's actually quite difficult to make something immutable
there isn't a concept of immutability so the point here is that we're going to
treat it as a beautiful
don't literally have to be a beautiful just as long as all the developers
understand that they need to be treated as immutable and don't change state on
them
this makes it much safer to make safe to pass this value objects around without
worrying about one thing changing state on us you as you pass these value
objects around your system business logic business logic blogs and your
value objects not in your entities so we said the entities are responsible or two
things identity life cycle so value objects
we're on our way of the business logic plans aggregate so i said before that
entity could have an object graphic that reference other entities and other value
objects so the aggregate is a group of related entities and value objects that
we define as one group one object graph so with domain driven design we're
trying to focus on solving the main problems over we're really thinking in
terms of of abstract tools to work with
now at the end of the day though we're building software and we likely need to
persist our data to a database or data store of some sort
so we can completely ignore things like transactions and distribution and
currency
so this is where defining aggregates you might actually base your aggregate
definitions on these on these concepts of what needs to be consistent
vegetables things like eventual consistency do two things need to be
consistent together or not if they need to be consistent
they probably belong in an aggregate together if they don't if they if it's
okay for them to be some inconsistencies that might belong in separate aggregates
and within a bounded context you're going to have multiple aggregates are
just gonna have one aggregate you have multiple aggregates now with an
aggregate we're going to do is you're gonna pick out one entity and you can
say this entity is the aggregate route and you're going to allow only
only its references to that I agree a true you're not gonna allow things to go
in and dive into the aggregate itself and get at of entities or value objects
within the aggregate going to make them go through the through the i agree that
route
persistence when you're persisting in aggregate you're going to persist the
aggregate route most likely
and that's going to also persist the object graph along with it of speaking
of persistence
we're going to use repositories to do this repository pattern that's where we
delegate our persistence - so repository is a pattern where we can send objects
to it and get objects out of it and it acts as if it were an in-memory data
store
it's actually going to to some back-end data store and storing the data but as a
developer work with the repository
we don't know any difference between that and it just being stored in memory
there's no that's the interface that repository gives to us now with this
gives us this is a really interesting technique we can use in your tests you
can actually use an in-memory strategy for your repositories
so instead of your test actually going to real database and storing their data
in real database you can just have a go in memory so you don't need to worry
about persistence yet when your initial domain modeling you can you can just
have all your all your tests happening in memory and so as you're changing
things like database schemas and stuff like that
you have to worry about all that yet you can you can just focus on your modeling
efforts a lot of you are probably using our aims object-relational mapping
errors if you are just quick note repository is going to use your RM it's
going to be
you can have your database then your RM and then your repository
that's the that's the order of how you stack these things so i mentioned before
that value objects are where your business logic lives
that's not always true sometimes you have my business logic that doesn't make
sense
it doesn't belong in a particular value objects and have a doesn't have a real
natural home in that case you can create a service
services should also be a beautiful
now you can they could be configurable so you can instantiate a service with a
particular configuration but once it is instantiated it should be a beautiful
you shouldn't should be able to change its state if you need a different
service if you need another instance of that service for different configuration
you can go ahead and stand she ate that that instance as well but any given
instance of the service once it's constructed should not be should not
have a state change or changeable
likewise operations on services are stateless so there are no side effects
to operations on services
so what does this look like so i want to take a look at some examples of what all
this might look like we're going to go through an example of a application that
i worked on
that's a election reporting application this is actually a really interesting
application for me because I didn't actually do the software development
work on this
I usually that's what i do i am a software developer but this particular
project
somebody else was doing the development work but what i did was i worked with
the domain experts and software developer to document domain knowledge
and try to try to go through this process of a model exploration process
so that was really interesting for me because usually as a software developer
i would want to go and start writing code but it's a great opportunity to
take a step back and really understand the domain first
so this model exploration whirlpool is is a is a graph that shows one way you
can approach this this model exploration process of this is available at domaine
language calm / DVD / whirlpool you want to check it out
basic concept is this iterative process of going to a domain expert getting us
talking to them about a scenario of them tell you a story really work out work on
the flesh out that slip scenario proposed a model for that solves that
Sarah that actually solve that the main problem that actually code that model as
a test
so actually use test here it actually has a model exploration tool and then
what you do is you go back to the doing expert with those tests you walk them
through the test using using the ubiquitous language
and you say does this make sense and you're gonna do this over and over again
and we refine the small exploration process so this is a this is a cycle
give you a man to take a look at that you want
again this is also available at the main language calm / DVD / whirlpool
ok
yep so the question was does it matter what type of tests or is there a
specific type of test i'm talking about
so I suppose I potentially didn't use the word unit testing I'm technically
what I do is I use like phpunit although conceptually what we're doing here is
not unit testing
we're actually doing it's more like integration testing but it's not really
integration testing user either but the tools were using our I or that i use at
least are our phpunit so unit testing frameworks will work fine just fine for
this but just realize you're actually not doing unit test units are supposed
to test just one thing in isolation and here we're testing more of a
scenario-based this thing so but whatever
testing framework you want you could work work could work here
yes
what's up
the question is by using the story based stuff that was in its in PHP file
phpunit no no i'm not using a start this diet is i'm just using straight up the
PHP unit tests with assertions
so yep so I walk you want to walk you through the specific example
so this is the ubiquitous language for this particular this particular
application for this particular model that we're exploring here now there are
some flaws in this language there are some inconsistencies this language could
use some improvement but i think it's okay to leave the flaws in here because
it points out that this is an iterative process and this is something that's
never really truly completed so should we look through this you might see some
things that aren't quite completely consistent or some areas for improvement
that's great if you see that that means you're you're getting the concepts oh ho
hum
so while the advanced concepts we came up with
how was working with domain experts this idea of an election event so in our our
domain election event is a set of districts voting on a set of ballad
items during the same general period of time
election event could include a primary general election or town meeting day so
I'm from vermont in front we have this thing called town meeting days which are
in march where we do just local elections and then we have the general
elections in November where we have both local and statewide elections ballot
item
even election a referendum as presented on the ballot pretty straightforward
election formal decision making process by which a population choose one or more
candidates told office for a given district could be tabulated a polling
place whar disability or district level winner or winners of an election may be
determined by plurality and are waiting threshold so what you see here is I've
actually in this
these are the signals language I've actually underlines the terms that are
defined in our ubiquitous language so candidate has a very specific meeting so
when I talk with the domain expert or talk with other software developers and
I say they were candidate
I mean something very specific not just talking generally
I mean candidate as its defined within our ubiquitous language now other terms
that are under lines aren't things that we've identified as as the ubiquitous
language so there could be concepts in here that are implicit for example
winner or winners notice those are underlined so maybe the concept of a
winner is something that should be made explicit it's an implicit concept here
in our in our ubiquitous language but perhaps we should actually promote it
and make it something more explain more explicitly defined as part of it are
ubiquitous language district district a distinct territory subdivision for
holding separate elections and referendums
blah blah blah I'll read all of it bore you with all of it but basically the
idea is that district could be their mission valley reward can have some
districts etc
municipality specific type of district City Town Village award basically some
municipalities are broken down into awards so award is the type of a
district candidate pretty straightforward winning threshold
so this is the method of determining the winner of a winner or winners of an
election and you can see here that actually some domain knowledge here in
this particular definition we've got some examples of of different types of
of elections and valid items
so here's a so whatever just walk through one scenario that that was that
we created with the the domain experts
this is just one specific Sarah their whole bunch of other scenarios but we're
going to walk through one here to illustrate the concept
so this is a the election for burlington city councilor so Brown against the city
that I live in AZ election for a city councilor and war three
so the town meeting day 2011 left 2011 election event again
ubiquitous language there is underway war three in the municipality of growing
tins holding an election for city councilor this election has three
candidates is a 30 p.m. and war three is indicated the following results
the list of candidates result number for each candidate percentage this election
has a winning threshold of forty percent so candidate Vince Brennan appears to be
the winner
you go so simple enough scenario so
next thing we do we've got with our ubiquitous language we've got our
scenario let's propose a model
so what's a model that could that we could use to to solve those problems
illustrated in that scenario
so again this model is intentionally flawed
there's plenty of room for improvement in this model this is a first pass at
the model again this is we're going to challenge this model we want we want to
work on improving it
but again it's got there with that was important to show you an early iteration
of of the model so you got the concept of how you can just start simple and
then iterate from there
so the proposed model here
well then I'm proposing is that we have a so first of all we're going to find
our aggregate our aggregate is going to be election
the aggregate route is going to be an election
it's going to implement the ballot item interface because we have different
types of all valid items we said that we saw in the ubiquitous language that
there's not just elections but right there also referendums both elections
and referendums are valid items so I decided to make that an interface we
have election event an entity an election can have one election event
election could have one district by district can have a parent district and
then we have specific types of districts war the municipality again these are all
entities winning threshold my threshold is a value object because there's no
reason it does
we can't identify a winning fresh whole that's something that it's a that is a
the Dom represented by its encapsulated attributes so putting threshold we can
implement the winning policy interface here for winning threshold because we
saw in our ubiquitous language that there actually are multiple ways of
determining the winner of an election so we don't want to just want to allow some
room for expansion there
now here's a concept the main concept that I've actually introduced this
concept of a of a winning policy hasn't shown up anywhere yet so i need to go
back to the domain expert and say does this concept makes sense is winning
policy something that we should imply that we should integrate back into our
ubiquitous language
so I'm probably so here's an example of where it's important to circle back with
the domain expert candidate candidate is also an identity an election could have
multiple candidates
so since we're on the slide out know if there's some some other bad design that
will point out here jumping ahead a little bit but candidate elections in a
multiple candidate and a candidate can have one election and you can actually
see if you can tell but the way this is diet way this is UML diagram is written
the election references they can't its candidates in each candidate references
of selection for simplicity you want to try to avoid those bi-directional
relationships if you can
so this is an area where i might actually might actually adding
additional complexity that isn't that could cause problems later
so try to use unidirectional research so don't do what I do there on the on the
left
also if you have one to many relationships try to store the reference
on the many side of the relationship
so ideally candidate would reference it's about its election but the election
would reference
references candidates in those are just some some some design tips for you to
simplify things
those aren't always possible but if you can will simplify things
so let's look at some actual code
so here's our election entity I've kind of stuff this out not all the codes here
but also it should be self-explanatory
we've got our election class election class implements ballad item as a
construct method that takes its identifier remember entities are
responsible for what to think what you think is responsible for the responsible
for identity and lifecycle
so we construct identity for giving an identity were saying here's your
identity life cycle so things like electrical election event as they belong
to so we have a selection event method we have a set district method because we
need to know what district the selection belongs to add candidate we want to be
able to add candidates to to the election will be able to get a list of
candidates back out so we've got to get candidates method and you can imagine i
didn't show the implementation of these methods but should be pretty
straightforward to imagine what they what they look like
any questions so far
Kennedy entity so here's another entity also responsible for its identity so we
passed this identifier
we also passed one election it belongs to the constructor that's really just
for convenience we can set the number of votes that kandi has and we can get the
fraction of votes that candidate has relative to all the other candidates in
the election
so again hopefully you're seeing some flaws in the design already
again this is these laws are our potential
so here's an example of a value object so here's our winning policy value
object that was just the interface willing any policy debate we have about
that as an interface or create that is in their face with one method that
determine which are the winners methods that's what putting policies does
winning policies to determine the winners and winning threshold this is
our value object for winning threshold
now since this is a value object when we construct it
we need to set up in the state that we do set of its state in the constructor
so we don't want to treat it as a beautiful so once it's created once
initiated
we don't want to modify its state so the constructor we pass in the minimum
percentage and the election that the winning special belongs to
now we don't change the state from then on if we need a new winning threshold if
we decide well actually no it was forty percent now it's fifty percent that's
okay
doesn't mean you can't change it what you do is you get rid of this one and
replace it with another one with 50 with a 50-percent minimum percentage
determine winners method here is basically just determines if which
candidates have more than the minimum percentage and add them to the winners
array and the returns that array of winners
so that's how this particular winning threat this particular winning policy
implements the the determiners method
so next we're gonna actually so you've seen them
you see this because language you've seen the scenario you've seen the
proposed model
what does this look like in tests in our actual test so here again the point of
these tests is to is to explore the debate bottle so these are not well
they're written is going to test these are conceptually not unit tests and
they're not really integration test either so you should also have unit
tests you should also have immigration desk you should have all these other
types of tests but that's not the type of test we're talking about here we are
talking about test for a very specific purpose and that is to explore the
domain model that's how we're using test in this this context
another important point is when you're talking when you're writing these tests
when you're writing we're actually coding these scenarios you want to use
very concreted scenarios
you don't want a person a you want actually use a real persons name to be
made-up person for privacy reasons but don't don't use abstract concepts as
software developers were really great abstraction and abstraction has its uses
but night
this is not a place where we really want to use abstraction we want to be very
very specific in these scenarios
so the interesting thing about this election scenario is that what I've done
here have actually added comments please comment these comments are word for word
from the stereo saw earlier so i could actually read this
test back to a domain expert and using the ubiquitous language
I could explain to them what's happening care so you think you'll agree as you
look through this code that the code expresses the concepts in the scenario
so for example the first part of the scenario says again this is word for
word from the scenario with our earlier the town meeting day 2011 2011 election
event is underway
so we instantiate a new election event with an identity of town meeting day
2011
so you can see that we have a
very close symmetry between our scenario and the actual code as we want to
actually be able to explain this to be an expert now
domain expert may not actually be able to read the code but with you sitting
there with them you can translate it for them into the into a language that they
understand board three in the municipality of burlington
okay how do we implement that war 3 equals new war three brokken equals new
municipality or three set parent district to burlington done
we now our war three in the municipality of a Bronco is holding an election for
city councilor
ok create a city councilor election event election
sorry we set the election event to the town meeting day 2011 election event we
set the district of war three their questionnaire
I give you Matt - 40 the next slide to take a look at this but again the point
here is that where we're trying to the goal here is we're trying to create a
model that can express the main concepts so we're trying to make the main
concepts explicit in our in the design of our code and in our tests here we're
trying to express those concepts
ok the next part of the stereo says this election has three candidates
ok here's our three candidates we instantiate are three candidates and we
signed the election to them so we associate the candidate with the
election next part of the scenario is it is 830 p.m. and war three is indicated
the following results
so here i have deviated a little bit from the scenario in that in the
scenario
it lists both the number of votes and the percentage of votes for each
candidate but that would be silly we don't want to set the votes and
percentage we should just have the votes and calculate the percentage
so we're done here as you can see for each candidate set the number of votes
that they received and then I have an assertion on the get fraction of votes
method just to make sure that it's calculating them correctly so that means
brendan brendan has 60 . two percent in music has 29 . one percent and Ron rule
of has ten points seven percent of the votes
this election has a winning threshold of forty percent
ok instantiate a new winning threshold value object setting its minimum
percentage to forty percent or . 40 and associating it with that of the city
council election so candidate then spread in progressive appears to be the
winner
so winners we do call the determined winners method on the winning policy
we then assert that Vince brendan is in that collection isn't that right and
that live music and raoul far not so again you can see we've got we've
actually just literally taken that scenario and Express that scenario in
code is anybody see any implicit concepts that should probably be made
explicit as I think jumped out of people that folks as a pleasant concepts here
so one thing that it's implicit is this idea of what part of the candidate
belongs to
we've actually made the party part of the identity of the candidate
perhaps that should be something that's that separated out and and it's an
implicit concept that should be made made explicit so again in order i don't
know that what I would need to do is I would need to go to the domain expert
and have a conversation with the domain expert so that i could understand
whether or not that was that was the case but it appears here that that might
be might be the case
so we've got our scenario next thing we want to do is we want to challenge that
model that we've come up with so we're gonna throw new scenarios at it we're
gonna going to challenge our model make sure it makes sense and really
rigorously keep throwing scenarios at it so this particular scenario here is a
few questions we don't want to ask our debate expert
what if two candidates reach the forty percent winning threshold
did anybody notice this law and what happened to catch this
so
if in our model that we have two candidates could both get 40 more than
forty percent of the vote right because that's still less than a hundred percent
there are both winners so there's where were actually missing something in our
scenario and that is that it's not just a winning threshold
it's winning threshold and plurality so our model we're missing something in our
model where we actually need to be able to combine multiple winning policies
together we need to be able to combine winning threshold and plurality together
so that if both if to Kandi's get forty percent
we then pick the candidate with the highest number of votes
what if a candidate participates in two elections so perhaps are missing another
concept here because certainly possible that can they could participate in
multiple elections or well I assume it is again
I should make those assumptions that should go ask a domain expert I'll what
about personality without words
this scenario was one with the board should we run it through this area
without warrants see what these any differences
what about one that's what about election was won by plurality you should
probably check check out one of those scenarios referendums of those different
than elections
what's what comes up in those scenarios that's different this was a town meeting
day so this is what this is a local election scenario what about general
election again the point of these questions that these are these are all
conversations conversation starters for you and the domain expert to two to work
together to come up with more scenarios to challenge your bottle
so a couple other useful tips here so this is that with eric evans calls a
simple design
so these are just a few few tips as more of them in the book on some techniques
to keep your design
what he refers to a simple easy to work with
so one . neat concept here is this concept of closure of operations
so closure operation says you have a value object and it has a method on the
value object returns instance of the of the same type of the same value object
and the method arguments are also of the same type
so a really simple example this is two plus three equals five
this is an example of closure of operations
she was a value object of type integer integer has ADD method as methods accept
an argument of type integer so about the returns an integer
so what we can say is we can say the integers are closed under the operation
of addition
so this is actually a mathematical concept of closure of operations
so here's an example of this code I've taken out here I've kind of iterated on
the model a little bit now I have this concept of a validation results versus
just a candidate kind of broken that out this this this example but the point
here though is that we have this method called total unvalidated result the
total method takes an array of validating results and returns about
Adam result
I'm cheating a little bit here because i'm using an array i should probably use
the composite design pattern here
but this shit is straight the concept where we can nom
so with this concept we can actually we could actually wire together
methods and we can actually pass these value objects around and do we can
actually start doing complex operations on this value objects with this closure
of operations concept of the weather and techniques that could be useful in
tension revealing interfaces so basically is if you look at the
interface for a method is it clear what it does is its intention clear based on
its interface side-effect free functions as a method returns a value and modify
state hint it shouldn't do both should only do one or the other
most of the time you don't want to modify state you want to really isolate
state changes to very explicit points in your code state changes are a source of
bub
big source of bugs in code so satisfactory functions are way you can
try to avoid those bugs
of course you have to change that at some point but not saying your daughter
to state kind of useless system if you don't but the idea is to to really
isolate the state changes to where they need to happen
I'm other interactions is your method call out to other objects or other
methods that might be to modifying state assertions the say buddy use the search
function in PHP ever use that couple people also prize
I was expecting no hands so a few people have so the start method or function in
PHP is basically it's something that the function you can call it should all get
the passive boolean expression and it's something that should always be true
so these are exceptions exceptions are things that should mostly up most of the
time be true
should be true eighty percent of time or ninety percent of time assertions are
things that should be true all of the time should never be false
it's okay if it's false something is seriously wrong so assertions can be
useful for checking two things preconditions to method as you enter a
method
what state must be true as you enter that method post conditions as you exit
the method
what state must be true and you can call the assert function to to make these
assertions for the preconditions and postconditions
by default the search function in PHP is on and will trigger a warning you can
configure it too if you'd like you can you can actually write off if you like
so you in production you don't wanna surgeons on running
you could also have a trigger an error instead of a warning which is probably
better and you could even have it do it
call a callback function if you'd like so if you want to do something more
advanced you could you do a call back on a cert
so let's look at let's go back up and look at these examples so
first intention really revealing interfaces so take a look at this
particular interface the gate fraction of votes method on the ballot and the
result is it clear what it does
arguably I'd say it's fairly clear what's intention is maybe could be clear
about side effect for you
so here's an example of a side-effect free method the Chairman winners method
in our in our waiting threshold value object
this doesn't change any state it calculates who the winners are returned
those winners
no state has changed the way in the process preconditions and postconditions
so in our determine winners method
let's add some assertions it's very beginning we have two assertions minimum
percentage of must be greater than or equal to 0 or less than or equal to 1
million percentage has to be zero percent or on two hundred percent right
what's outside that range something seriously wrong so we can assert those
two preconditions at the very end we can assert the post conditions that the
number of winners the count of the number of winners is less than or equal
to the number of candidates in that election get more winners and you have
candidates right
that's invalid state so we're sorting that out
we're saying that post condition here
yes
absolutely
yep so the question was I'm would you make an exception to change it to the
rule about not changing state for things like caching and whatever there is a
difference between a logical state and physical state
so what we're talking about here is logical state so logically this
shouldn't change any state now if you really know what you're doing and you're
really careful about it and you want to cash stuff and you can guarantee that
logically
it's never changed state even though physically there's a cash that's
happening to improve performance
that's perfectly fine but there's really two think that's a physical physical
thing not a logical logical state change so advanced topic
it's a couple of things these are a little bit outside the scope of of
domain driven design but still related related topics just gonna talk about
really really briefly event sourcing so that's our thing is pretty cool
so the idea with the vent sourcing is that you model your domain around two
main events
so the main events are are important things that happened within your domain
that result in state changes soda main events can trigger other domain events
for example if you're modeling a baseball game
three strikes could trigger it out so as an example of events triggering other
events the main events are like value objects they should be treated as
immutable as well you can create new domain events to correct state if you
need to but a particular domain event
what's the substantiate it should should not be changed
so what you do is you store these domain events in the event log and you can
actually compute the state of your system by reading the event log so we're
actually using actually not ever storing the the actual currency of the system
were calculating the current state of the system
now that could potentially be sparring sessions actually can be pretty fast but
if you'd like you could cash that if you need to again this gets at the
difference between logical and physical state so logically were always computing
Lee
the the event log computer the current state from the event log but we might
want to cash things to for performance reasons
um thanks take care of you the same whenever needed to have in your past me
to build a audit log into your system if you use event sourcing you have a
built-in audit log
so you know you can tell exactly what's changed when by just reading the event
log so it's a sort of really nice added benefit you get for free
another related concept is a command query responsibility segregation or seek
urs
so when we're bottling entities we tend to think in terms of symmetry
you're going to have a get food method and set for the method on an entity in
other words reading data and writing data you're going to do the going to do
the universe of symmetry there that gathers and Senators you can have
together for every Center
why why do we need to do that why does the model for reading data need to be
the same as the model for writing data so will seek your s we actually separate
are read model from our right model have to two different models for reading
Gator writing it so we have commands responsible for writing data and with
queries responsible for reading data now both are conceptually working on the the
same aggregate from a conceptual point of view we're dealing with the same
aggregates here but where were separated how we model this so secure s and events
actually go really well together because you can use
commands that you can use events and commands to change state those going to
an event log and then you can have another system that then reads that data
out for your read model
great so that's all I've got for today we'll take a few minutes for questions
but just real quick I've got a couple of books if you're interested in these
aren't directly related to this topic but writing a query not produced using
couchdb and scaling couchdb I've got some discount codes for those if you're
interested
if you have any questions after this we got a few minutes now for questions if
you have questions later feel free to hit me up on Twitter or
but also find me at my blog at Bradley - hold calm please if you don't mind going
to join in
joined out in / 7025 you get feedback on the stock really appreciate that
if you could let me know what you thought of it just helps to to make
improvements to the talk in the future I'll great so if you don't mind if you
have a question could you please come up to one of the bikes on either end of the
room
anybody with a question we've got probably about five minutes I think
for questions anyone
my question is about forgetting you refer to it
the domain glossary and yep
well you better so ubiquitous language up language yep many times we need to
create more detail granularity for purpose of modeling in the domain
experts are normally used to thinking about because there's things have to be
composed more than made up
we talked about so I faced challenges where I have to create kind of longer
specific ND names that they wouldn't normally interact with and yep
fine maybe I guess I have tended to train them to use those terms in a
certain way it's kind of like a two way street is that forcing the issue a
little too much
no I don't think so I mean I think if those those terms are needed in order to
to solve the problems of the point is that you're trying to solve the main
problems that that are that they're experts for so if you need those tools
as part of its all those problems and they're not familiar with them it that
there's perhaps that's an opportunity to further develop the domain may be there
are things lacking in the in the domain that you can work together with
collaboratively developed is it sounds like you're doing the right thing there
with going back to them and trying to define and use those terms because now
you can actually have more expressive conversations with them because you have
more detail terminology to use to write the challenge
mine is that
- what level of it the surface those new concepts to the UI
you know sometimes it's only important for the people that really understand it
yep and then how to simplify that labeling .
yep so that's a really good question
so what I'm talking about here is all the main modeling layer and you really
want to focus on like not actually how it's going to end up in the UI but
eventually in a real application you're going to have a user interface so what
if at all possible you really want those you make you really want that ubiquitous
language to bubble up and and be used in the UI used everywhere
it can be across the system but I mean they may not always be practical like
issue in that situation you could consider it a form of a translation so
perhaps you out he was a translations or translation tool to say okay for these
users
they're not going to understand this technical jargon we're using so we're
going to translate that word to something something more meaningful to
them
something is your head of our cases you may have a template and then an actual
instance which had this exact same model have to be copied and you need to strip
away some of the difference between them from the users . because they don't
yeah yeah yeah no that definitely that that definitely comes up in user
interfaces where it's as much as you want to stick to that you can kind of
language sometimes things need to be simplified a little bit of that that
level so sure they get any other mushrooms
yes
yeah
someone from the previous johns talking about looking at your example one thing
that kind of noticed was the sort of the scoring of the candidates the fractional
value
yep with the precision look like it like this
yep position with that bother you begin with because this language or is that
getting to sort of dirty
I would probably should be yeah that definitely should be at the real reason
I did that was to make the pH the pH unit tests work because without that
precision that one of you would need to make the unit tests to add more methods
on the the assertion boreham parameters to the assertion so that's why did that
but yeah that was that something that should have been there should be
probably explicitly worked on and what what level position matters here and
perhaps it's you know exactly maybe even the concept of percentage should be a
value object i don't know maybe that's going too far and i want to make
everything about you object to the girls need to be but perhaps it should be
something that's made explicit with explicit concept of of precision to it
so
ok thank you sir and the question looks like
first of all we talked really appreciate it been reading your book
fantastic stuff um can you talk about just real quick
i have an application have been intuitively doing a lot of stuff to talk
about but you know the applications two years in the running in
we've made some mistakes we want to go back and correct it or maybe i have an
application that i haven't used any of the DVD style floor at all how do i take
an existent
I can see how this could work with the new application that I'm building from
scratch
what about applications that already exist how do we apply these principles
yep in a contact yet great records from I'm so I'd point you to the strategic
design section in eric evans book that's where it talks about things like the
context map for example
so where you actually take what's out sit down to spend some time to actually
map out what exists
what the context map is what areas need improvement and and i would say really
in that situation distilling the core is really important because you want to
well as much as you want to clean up the entire code base and and fix everything
it really matters most in the in the core domain so that's why the context
matters because you really want to be able to isolate that define which was
before domain and focus your cleanup efforts there else is just going to
you're going to be no waste your time all over the place and fixing things
that aren't is critical
so I would say there its focus on identify the quarter main focus there
and in and fixed focus on that for cleaning that up and refactoring that
area of the application
sure anything else sir
so for the the domain different design really trying to move towards the group
that I work with four on the testing side or behavior different is on using
be had and was like that you know maybe talk works very quickly about how it
they kind of relate for is more like the CBD is being a feature of being a
particular domain the war
how do you see that playing out yeah I mean I i think they have two different
sides interesting
um I think what I've seen with it with a cultural behavior driven design is it's
the focus tends to be on on letting domain experts actually write that the
test which mixed feelings about i think it's important to work collaboratively
with them
so most usually the problem is that that software developers are going and
bottling it and we're just doing it in isolation and the behavior driven
development potential risk going the other direction where you just have the
domain expert writing the test without a software developer so so i just say i
would say that I think it's definitely be useful but the the key point would be
to make sure you're still working collaboratively between both the
software developer and the domain expert
you have just having one or the other other doing that to network
thanks sure
my question sort of relates to how domain-driven design can work with the
experts on a two-way street
I'm just wondering how your experience has been with trying to help or get
domain experts to sort of
still set so that things aren't always complexity might have something up for a
strange rule set this like you know what we tax everybody at five percent but if
the third character and their name it and it's six percent of these really
weird rules yeah yeah I'm going to talk a little bit
yeah i mean so I mean that's tough one because it's um a lot of those couple of
those issues are actually probably areas where there is complexity and away and
then perhaps they seem like they're arcane rules are things that are added
by the domain expert and why why is it matter
but perhaps there's something that if further conversation further refinement
might get at some concepts hidden in the in those those weird corners of things
so i would say that in software design there are no there are no education and
software design is overdevelopment absolutely but in the design phase edge
cases are probably a sign of of some other thing that's not hasn't really
been explored well enough that needs to be explored further
I more could just be them stuck in their ways about how the existing system works
sometimes you have somebody who used to work on a previous system and they're
thinking in terms of how that system worked
so it could be other think it may be it actually isn't an important concept but
that's the that's where the kind of the subtleties to this is is really trying
to to synthesize that domain knowledge and trying to identify what's important
and what isn't
so no simple answer but hopefully that helps give you some some tactics to work
with so I'm so i think we're probably at a time here so if you have any other
questions feel free to hit me up after and be happy to talk more about this
with you but thank you everybody