We are attempting to use DDD techniques on my current project and have started going through the process of domain modeling and are experience a lot of friction around "how to" create the Domain Model. I haven't found a lot of examples our guidance on this topic.
We have started by attempting to define the Ubiquitous Language by talking to the business users and coming up with a list of domain entities and their attributes. That's going pretty well but we are having problems with things like:
Behaviors, actions
Permissions
Business Logic (if attributeA = true then foo else bar)
I have a lot of ideas on how we could capture all of these various things (sequence diagrams, uses cases, flow charts, ect...) but if there was a formal process or some resources providing example driven guidance it'd definitely speed things up a good bit.
This is a great question.
One of the first steps I always take is to have a meeting with one (yes one) domain expert and have an open discussion about the problem domain from their perspective. I bring plenty of post-it notes and make sure I have plenty of whiteboard space. As the expert speaks I try to draw a flow or BPMN diagram on the wall using the post-its. I find it's very important to give the domain expert something visual to look at - something which he/she can physically point at and say "no, that's wrong!" (which they usually do, many times).
During these conversations I am listening closely to what the expert is saying and asking for clarification where there is ambiguity. I always find that it's better to let the ubiquitous language emerge naturally this way - rather than trying to forcefully establish it (I would never ask a domain expert to give me a list of terms).
I try to express the flow diagram in terms of commands and events - even if I do not end up using CQRS I find this naturally flows into more concrete requirements. When the flow diagram is complete (I can usually tell this because the the expert looks very pleased with it - there's a good chance he/she has never seen the domain mapped out this way and they are often thrilled by the novelty), I start to trace individual routes through the flow diagram. Often these individual routes can be easily expressed as behavioural specifications in terms of Given, When, Then style requirements. (see BDD section 3)
Once you have a collection of Given, When, Thens which cover every route through the flow diagram, you have sufficient specification to start the design phase of a domain model in exactly one Bounded Context.
I repeat the process with other domain experts. With subsequent experts I also listen for correlation between the language and terms they use. Most times different domain experts will share terms in the ubiquitous language, but will mean slightly different things. This is a sign that we are dealing with distinct bounded contexts.
Related
I've started learning the principles of DDD and I'm currently trying to get a grasp of the concept of a bounded context. In particular, how do you decide just how big (or small) it has to be? Yeah, I know, as small as possible and as big as necessary (according to Vaughn Vernon).
Let's say I were to model a blog. I could then go and say there are 3 bounded contexts involved: 1) Front Page (featuring the most recent articles, no comments shown) 2) Discussion (a single article including comments) 3) Article Composer (where I compose an article).
However, this doesn't feel right (the ubiquitous language is the same for all of them), it seems as if I'm coming from a front end point of view and am still thinking in terms of view models or something.
Could anyone please point me in the right direction?
A blog is not a good example for use of multiple bounded context. It's not really a "big enough" software example to warrant their definitions. DDD & BC's are really aimed at big/complex enterprising software systems.
Like you say, the aggregates always have the same meaning in your 3 examples.
I gave this example of Bounded Context in a previous answer, which I hope explains BC's and when to use them: Bounded Contexts and Aggregate Roots
Try to look at your whole domain from different perspectives, as an editor of article, you probably will use sentences like creating a draft of an article, publishing an article, as an article a reader you will in example read article and comment on it. Alongside building your domain language you will identify entities and their behaviour, some of them will appear only in one perspective, some will appear in both, but you will distinct them by their behaviour. Your domain language shows you the boundries of each perspective, that you implement as a bounded contexts.
The best example I read by subdomains so far is the following.
Just examine the actual company! Each department taking part in the business process can have its own subdomain. In an ideal world each subdomain has its own bounded context in your implementation. You should ask yourself whether the company needs a new department to do this? Is it really that big?
The BC must be big enough to describe a department of a company. A typical example is a webshop, where you have a shopping core domain and invoicing, delivery and storage subdomains. Having multi-tenancy and so multiple aspects - as a previous answer described - is not enough. A blog with an author and a few readers does not require multiple departments, so you can solve this with a single bounded context. You can have multiple modules in your bounded context if you think you have medium size structures in your bounded context.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
I am working on an open-source project which shows how to develop software iteratively using test-driven development and some ideas from domain-driven design. I know what I would do, however my formal skills (especially regarding UML) are a little bit rusty.
Below I am going to post my first steps with the diagrams and the explanations I would give to my readers.
I have the following questions:
The last step ends with the question But what will stich together these components?. How to show the reader the way in UML terms, while not skipping anything in the train of thought? What I plan to do is to let each component provide an Environment class. For the purpose of testing, a TestingEnvironment will gather all those environments and inject the right callbacks into the World. But which types of UML diagrams to use for showing my train of thought, and in which order? My problem is, somehow, that I know what I want to do, but I can't rationalize it to myself why I want to do it that way - I guess it has gotten a part of me to the point I don't make such decisions consciously any more.
What mistakes have I done so far, how to fix them, and most importantly: WHY?
Step 1
(0001_user_commands_use_cases.pdf)
(0002_user_commands_use_cases.pdf)
User Use Cases - Analysis
We are starting with an use case diagram (0001_user_commands_use_cases.pdf) as
part of the preliminary analysis stage. This diagram should only help us
understand what our client wants. These use cases may change over time, but
never the less, they help us understand the system we are going to develop.
Please follow the arrows while reading the following explanations.
The role the user plays when interacting first with our system will be Guest.
The Guest sends to the system some registration data, which we process.
In the diagram, we are describing what happens from a logistic point of view,
from the perspective of the client for which we write the application. We are
not referring yet to classes or objects, or the concrete workflow, which may
end up being quite different.
We are also not dealing with errors, because that would only add more
background noise to the idea - and because error handling does not add business
value to the system. Of course, a system has to be robust to errors, but keep
in mind that we're now just making the analysis - not the design of the system.
Logistically speaking, after the Guest has sent us the registration data, there
is a Registered User. A registered user can send us the login data, so that he
becomes an Authenticated User.
Following the diagram, we can see how only an Authenticated User can send to us
a request to log out of the system, thus becoming a Deauthenticated User.
Why a Deauthenticated User, and not a Guest back again? Basically, it comes
down to us not being able to foresee the future. We really have no idea how the
client will want us to extend the system - nor does he himself! Beside that,
the two roles, a Guest which we know nothing about, and a user which has just
deauthenticated, which we do know something about, are really different things.
Of course it may be that the Deauthenticated User will exist in our application
only for a very short period of time, or it may be that it's created for the
sole purpose of being destroyed back again, without being looked at by any
other subsystem of our ERP - but still I cannot stress it enough: logistically,
the role of a Deauthenticated User stands on its own.
The second diagram (0002_user_commands_use_cases.pdf) contains all the
information of the first diagram, with some added items. If you follow the
green arrows, you will see that the process is the same.
In the first diagram we notice how all three things done by the ERP system are
some kind of generalizations of a process. We have introduced this new generic
process in the second diagram as "Process Data".
Another element we have added in the second diagram is a generalization of the
three "Sending Data" elements. We are not sure how this will materialize in the
next stage (designing the system), but it looks like there's a generalization
there which may, in the end, make the system easier to maintain and extend.
We always seek new generalizations and abstractions because they have this nice
property of making the code maintainable and extendable.
Conclusion
----------
In our design, the ERP will do one central thing, "Process Data", data which
will come in in a standardized way, represented in our second diagram by the
"Send Data" use case.
We don't know how we will design these things yet, until now we have only
thought about the logistics, since we are doing just the analysis.
In the next commit, we are going to look closer at the application domain, in
order to better see the relations between all these notions and to enable us to
come up with a cohesive design.
Step 2
A rough overview of the components in the context of the application domain
Before looking at the diagram, let me first explain the thoughts I had prior to
coming up with this diagram.
We are going to design an ERP. What is this all about, and where lies the
business value in it?
We are supposedly making the product for a company which makes money by sending
products back and forth. This is the core domain of the application.
The basic idea is that a product P is moved from point A to point B, and in
this process, the company makes money.
The application will allow the company to make money by both being good at
organizing the workflow, and by making an existing workflow cheaper.
Let's say a product can be delivered to point C by taking the route A -> B ->
C, or the route A -> D -> C. The ERP must be capable of deciding which one is
better (in terms of money or time), and must manage the workflow it chooses.
So the whole point is supporting the movement of products around. Around what?
Around the world.
For this reason, let's first draw our first component: the World.
In a real project, I would continue by adding a Product component. I've chosen
not to yet, because this project is an educational one in nature, and I wanted
to get across new ideas about the architecture. If I had focused on the
products, I think there would be too much noise for the type of audience this
project is aimed at, a noise which would make the process of creating the
architecture and the architecture itself harder to understand.
We will introduce a Product component later, when the reader will feel at ease
with the architecture which, at that point, he will feel familiar with.
Instead of focusing on Products, we are going to focus on Users. This is,
incidentally, also the subject of the use cases we have drawn in the previous
commit. I think that any reader can relate to the concept of User.
So let's draw that component, the User.
Architecturally speaking, it's not that much of a difference between an User
and a Product. Instead of having Products moving around, we will have (for
now), users who live in the World and take different roles while interacting
with our system.
In the previous commit, we have concluded that there would be a standard way of
passing in data from the User to the system.
In terms of DDD (Domain-Driven Design), the data that gets into the system is
packed up as a Command. Since it looks like a good name, let's make a port of
the World component called Command Hub which will be used to receive and
process Commands from the outside.
Conceptually, the Command Hub will provide a Command Interface which any other
component can implement in order to send commands to the Hub, if it needs to.
We also want to make the components decoupled and thus reusable in different
types of applications, or to be able to combine them. This is achieved by
making an event-driven architecture.
For this reason, let's give the World component an Event Hub, which will
provide an Event interface.
But what will stich together these components?
This question is so pressing, because it's so central to our architecture, that
we will have to further investigate it.
This is not an asnwer, just a comment that would not fit into the comment box
(1) if you want to "teach your readers" something you can't do yourself, it is strange approach. Show your readers the way which works for you. Show the way "your train of thoughs runs", show the the mental images you saw in your mind, paper/pencil/photo in whatever visualization language you use
(2) you're skipping the uml-diagrams: UML 2.5 Behavior Diagrams as not useful? Even the uml-diagrams.org: UML Interaction Overview Diagrams not useful?
(3) this question looks like too broad(long) perhaps opinion-based and perhaps off-topic much more suitable for https://softwareengineering.stackexchange.com/help/on-topic
(4) for the recommended modeling workflow look at
(4.1) Cangnus's sequence diagramming comment in Stack Overflow: sequence diagram for books exchange
(4.2) BobRodes's use case scenario comment in Stack Overflow: Formal language for UML sequence diagrams
(4.3) Scott W. Ambler's Agile Modeling: Where Do I Start? for what when how and why Agile Modeling Best Practices
to name just a few
In conclusion of this my long comment, I don't see any mistakes you did. If this is description of how Test-driven Development and Domain-driven design works for you so well that you even use it subconsciously then it is just fine and ok. Being a good teach is not an easy task, good luck
My understanding of BDD is that one describes a system in user stories and then developers take those user stories and turn them into an application with the intention of adding real business value with every 'sprint' (period of software development). The result (as far as I can tell) is that the domain model emerges from the user stories throughout the development process. That is, after the first 'sprint' much of the domain model will not have been designed.
My understanding of DDD is that software development continues with reference to a full domain model, albeit an evolving one. In DDD the model is expected to change, but it is nonetheless 'complete' at all times.
This seems to be a fundamental difference between the two approaches. How have people handled this?
BDD done well does not produce a "complete" model. There's a reason that Dan North, the guy who came up with BDD, calls his blog "embracing uncertainty".
I find it useful these days to think of three kinds of things that we can analyze: the known, the knowable and the unknowable.
Known stuff is simple - for instance, logging in. It's well understood. We don't need to talk through the scenarios.
Knowable stuff is usually related to the domain, or to something that has been done before. This is a great place to do BDD, because it helps transfer knowledge - including the domain model - from the business to the developers. Talking through scenarios is a great way to understand stories better. It can also help us to find scenarios we've missed. Chris Matts, who's the analyst who helped put the "Given" in "Given, When, Then" calls this "breaking the model". He actually offered prizes for anyone who could come up with a scenario that wasn't covered in his model, which he uses scenarios to define and refine.
There's also the unknowable stuff. This happens whenever we're working on something new, or something we've never done before, or something in which nobody has expertise. You can tell if you're in this place because business people will start reacting with surprise when you come up with the scenarios they haven't thought of. BDD is a really great way of finding these places, but at this point you probably want to stop trying to nail down the scenarios and just try something out and get feedback instead. Your domain model, and your user stories, and your scenarios, will all gradually emerge (see the complex domain in the Cynefin model).
I know a lot of teams use BDD as a way of apparently eliminating this uncertainty. You can't eliminate it. You can only hide it until later, when the feedback from delivery comes back to bite you.
With respect to DDD, when we do it with BDD we tend to focus on those parts of the domain model that are relevant to the scenarios we're working on, though we might have an idea of the larger domain model overall. If you're using Feature Injection together with BDD you'll already have talked through most of the capabilities of the system, especially the new ones, so you'll have an idea of what kind of things are in the domain. Evolution and all other rules still apply. BDD and DDD work really, really well together, with conversations around scenarios helping to bring out the domain language. They are not fundamentally different, but completely supportive and compatible.
Please also read the answer I gave to this similar question, which features a video of Dan North and myself talking about this very topic.
I would include user stories, DDD and BDD as they are very very dependent of each other. I tried to summarise the link here: http://christophelecoent.wordpress.com/2013/06/17/how-to-link-user-stories-ddd-and-bdd/
I hope this picture is both simple and rich enough to explain the link between these "concepts"
I have done a fair bit of analysis and have used a number of tools to capture requirements: user created storyboards, use cases, GUI drawings, GUI prototypes, User stories & scenarios that can be used as acceptance criteria etc.
While each of these have more or less merit, I think there is one important bit missing. These methods can accurately capture how the user interacts with your app., but it is up to programmer to create and develop a “model” that should be reflected in the code.
I have been reading Evan’s DDD lately and he proposes something different. You need to create the domain model together with the domain expert and share it with him. In order to communicate the ideas with the user, in the book he often uses ad-hoc UML inspired drawings.
I wonder if this is the best way to talk about the model with the domain expert. Are there any other tools, besides UML diagrams, that you could use to capture the domain knowledge and use it while you are discussing the domain with your domain expert?
While the final abstraction into a working domain model (and ultimately a stable model) is your, the developer's, job, I do agree that even the set of tools above can be restricting, and limiting yourself or your communications to just UML can make the conversation seem esoteric to the domain expert.
For systems anatomy, try Block Diagram notation tools at http://www.fmc-modeling.org/.
For white/blackboarding and mind-mapping try FreeMind
For associative organization (and coolness) try TheBrain
For quicker/collaborative graphing (sort of new), try LucidChart
And of course, good ol' Dictionary and Thesaurus to always, always strive for the best terminology.
If these seem right-brained to you, remember that modeling is left-brained analysis done by one party on behalf of two. You're not going to get as much with a purely defined linear process as when that is coupled with trial-and-error, free-running style information mining.
The best way is pencil and paper. UML and what not come after this. Start with a DSL (list of vocabulary that is used when talking about the domain). Then you can use that list to determine what is actually what (model, aggregate, action [verb], etc) then you can do associations.
After all that, then do your UML diagrams and go over it with the domain expert. If they understand it then you're golden.
This book covers doing exactly what I said. I recommend at least skimming this book (actually I dont know if you're using .NET). http://www.amazon.com/Professional-Refactoring-ASP-NET-Wrox-Programmer/dp/047043452X/ref=sr_1_1?s=books&ie=UTF8&qid=1306529986&sr=1-1
There are losts of/ tons of tools THAT you can use:
Actor Map
Actor Table
Business Policies
Business Rules
Context Diagram
Decision Table or Decision Tree
Domain Model
Event Table
Process Map
Scenarios
Statechart Diagrams
Use Cases
Mind Maps
..
There are so many long and boring books about each of them. And sometools work at some context "best" and "may failed" at others. There is nothing like "BEST": Context matter.
But the important thing is not the techniques themself: Important one is How you apply them....
.
The trick is how to "Collaborate" with customers-domain experts-end users.
Collaborative-Workshops generally best at many context. The following book does a nice job at this area.
Requirements by Collaboration: Workshops for Defining Needs ,Ellen
Gottesdiener
Check http://ebgconsulting.com/facassets.php
But be carefull DO NOT BE A TEMPLATE ZOMBIE [ which is a general disease in requirements area ]
And you can use even games for making better Collaboration:
Innovation Games: Creating Breakthrough Products Through Collaborative
Play , Luke Hohmann
Domain experts tend to understand sentences better than anything else. That's why I like Object-Role Modeling. A lot of the development relates to graphical methods, but in practice I find it works best to just use the structured sentences.
I personally find most productive way to just sit down and write domain model on-fly while frequently asking yes/no questions to domain expert that sits next to me. this works only if You are fast enough w/ coding.
Also - well constructed (trees should read like sentences) mind maps in ubiquitous language are great way to communicate. Easy to create, share and understand too.
Real world example:
Payment
comments
can be edited
if user is authorized
with role [Role]
can be approved
if user is authorized
if payment is initiated
if payment is not paid yet
if amount does not exceed allowed budget
when approved
remembers that
saves approving date
can be rejected
if something something...
when rejected
forgets planned pay date
resets amount to be paid
(copy from here if You want to see it in text2mindmap tool)
That translates into:
public class Payment{
public virtual void EditComments(string comments){
Authorize<EditPaymentComments>();
CommentsEntered=true;
CommentsEditedBy=User;
CommentsEditedOn=SysDateTime.Now();
Comments=comments;
}
public virtual void Approve(){
EnsureCanBeApproved();
IsApproved=true;
ApprovedOn=SysDateTime.Now();
Raise(new Approved(this));
}
protected virtual void EnsureCanBeApproved(){
Authorize<AcceptPayments>();
ThrowIf(!IsInitiated,
"Payment is not initiated.");
ThrowIf(IsPaid,
"Payment is already paid.");
ThrowIf(ExceedsAllowedBudget(ToBePaid),
"Amount to be paid exceeds allowed budget.");
}
public virtual void Reject(){
EnsureCanReject();
ForgetPlannedPayDate();
ToBePaid=0;
IsInitiated=false;
IsRejected=true;
Raise(new Rejected(this));
}
private void ForgetPlannedPayDate(){
Deadline=DateTime.MinValue;
DeadlineKnown=false;
}
}
There are many good suggestions so far for tools. Try them and use the ones you like, but the key to success is iteration between code and conversation... what Evans calls knowledge crunching. The more you listen to the domain experts, model what you hear in code, then show them the software, get feedback, and tweak the model, the closer you will come to software that solves the problem at hand.
For me, it depends on the domain expert.
For some, it is a matter of sketching a UI on a whiteboard - showing how it would look on screen - then asking questions like: "Can this one exist without that one?", "Do you have situations, where this one is first added later, or are they always there", "Which order would you prefer them filled out?", "Who needs to know what from this screen?"... Usually, the visual aid helps them get into a situation where they can actually answer your questions very precisely.
Others, I can use naive UML (showing aggregates, valuetypes, properties and collections) and they are fine with that.
Really, to me it is quite simple, I start out simple - keep adding techical stuff until they go blank in their eyes - then take back one step. And always have some kind of starting position to get the creative juices flowing. If you're stuck, just watch'em work - "Wait a minute - why did you not record that information?", "Whoa, you did what there?" - to me, the tools are only there to help me, they rarely help the domain expert.
Basically, knowledge crunching with few to no tools beside a pen and paper (and a whiteboard if possible).
What I do is to create use case diagrams for requirements. I can save all needed information at model level. My use case diagram could save almost all the complex needed system I have to model.
I also can reuse the same use case in more than one diagram and still keep its property. Really superb technology.
Concerning domain with UML I nix use case and class diagram element in the same diagram and all add a database profile which allows me to add persistence in my class diagram. This is therefore object modelling with database specifications.
My modelling is really complex, I create my database and can permanently refactor my requirements and immediately my code without loosing my model.
I use it daily and really like it.
Hope this help.
I am on a tight schedule with my project so don't have time to read books to understand it.
Just like anything else we can put it in few lines after reading books for few times. So here i need some description about each terms in DDD practices guideline so I can apply them bit at a piece to my project.
I already know terms in general but can't put it in terms with C# Project.
Below are the terms i have so far known out of reading some brief description in relation with C# project. Like What is the purpose of it in C# project.
Services
Factories
Repository
Aggregates
DomainObjects
Infrastructure
I am really confused about Infrastructure, Repository and Services
When to use Services and when to use Repository?
Please let me know if anyway i can make this question more clear
I recommend that you read through the Domain-Driven Design Quickly book from infoq, it is short, free in pdf form that you can download right away and does its' best to summarize the concepts presented in Eric Evan's Blue Bible
You didn't specify which language/framework the project you are currently working on is in, if it is a .NET project then take a look at the source code for CodeCampServer for a good example.
There is also a fairly more complicated example named Fohjin.DDD that you can look at (it has a focus on CQRS concepts that may be more than you are looking for)
Steve Bohlen has also given a presentation to an alt.net crowd on DDD, you can find the videos from links off of his blog post
I've just posted a blog post which lists these and some other resources as well.
Hopefully some of these resources will help you get started quickly.
This is my understanding and I did NOT read any DDD book, even the holy bible of it.
Services - stateless classes that usually operate on different layer objects, thus helping to decouple them; also to avoid code duplication
Factories - classes that knows how to create objects, thus decouple invoking code from knowing implementation details, making it easier to switch implementations; many factories also help to auto-resolve object dependencies (IoC containers); factories are infrastructure
Repository - interfaces (and corresponding implementations) that narrows data access to the bare minimum that clients should know about
Aggregates - classes that unifies access to several related entities via single interfaces (e.g. order and line items)
Domain Objects - classes that operate purely on domain/business logic, and do not care about persistence, presentation, or other concerns
Infrastructure - classes/layers that glue different objects or layers together; contains the actual implementation details that are not important to real application/user at all (e.g. how data is written to database, how HTTP form is mapped to view models).
Repository provides access to a very specific, usually single, kind of domain object. They emulate collection of objects, to some extent. Services usually operate on very different types of objects, usually accessed via static methods (do not have state), and can perform any operation (e.g. send email, prepare report), while repositories concentrate on CRUD methods.
DDD what all terms mean for Joe the plumber who can’t afford to read books few times?
I would say - not much. Not enough for sure.
I think you're being quite ambitious in trying to apply a new technique to a project that's under such tight deadlines that you can't take the time to study the technique in detail.
At a high level DDD is about decomposing your solution into layers and allocating responsibilities cleanly. If you attempt just to do that in your application you're likely to get some benefit. Later, when you have more time to study, you may discover that you didn't quite follow all the details of the DDD approach - I don't see that as a problem, you proabably already got some benefit of thoughtful structure even if you deviated from some of the DDD guidance.
To specifically answer your question in detail would just mean reiterating material that's already out there: Seems to me that this document nicely summarises the terms you're asking about.
They say about Services:
Some concepts from the domain aren’t
natural to model as objects. Forcing
the required domain functionality to
be the responsibility of an ENTITY or
VALUE either distorts the definition
of a model-based object or adds
meaningless artificial objects.
Therefore: When a significant process
or transformation in the domain is not
a natural responsibility of an ENTITY
or VALUE OBJECT, add an operation to
the model as a standalone interface
declared as a SERVICE.
Now the thing about this kind of wisdom is that to apply it you need to be able to spot when you are "distorting the definition". And I suspect that only with experience (or guidance from someone who is experienced) do you gain the insight to spot such things.
You must expect to experiment with ideas, get it a bit wrong sometimes, then reflect on why your decisions hurt or work. Your goal should not be to do DDD for its own sake, but to produce good software. When you find it cumbersome to implement something, or difficult to maintain something think about why this is, then examine what you did in the light of DDD advice. At that point you may say "Oh, if I had made that a Service, the Model would be so nmuch cleaner", or whatever.
You may find it helpful to read an example.: