What Are The Major Questions/Solutions Encountered In Domain-Driven Design? - domain-driven-design

What questions/solutions arise when Domain-Driven Design is practised?
I have found getting a grasp of it somewhat difficult as new situations keep arising, so I am trying to compile a list of good resources/questions in one place to assist me and anyone alike me having trouble grasping/implementing it.

Some questions you can find searching for the tags domain-driven-design or ddd here in SO. The book from Eric Evans also give some good insight of some situations you may face.
One important note is ddd is like tests, in the aspect that it increases development time of new features, but increase quality (and consequently, reduces development time in the long term). You might need constant contact with domain experts, so you can refine the model each time an issue appears.
IMHO, the most important issue of ddd is having a good, meaningful domain. Most issues (though not all of them) root problem is poor understanding of the domain
It is difficult to say what issues are the most common, as for every domain is a different domain, with its own peculiarities...

In my experience, one of the top rules is "Build the Ubiquitous Language". Don't forget it, it's one of the most valuable aspects DDD provides to the development process. With a strong and shared ubiquitous language comes a meaningful domain and a shared vision of the problem that helps a lot.
My second rule is "The model is only one": don't model data, objects, classes, tables... just face the domain an model it, everything else must be derived naturally from this model, there is no gap between a UML class in the model and the Java (or the language you are using) class.

Related

Is DDD suited for all kinds of application?

One common reaction that I see for a lot of questions asked here and other forums are like "You don't need to do DDD for that. Its a simple CRUD application, DDD is an over-engineering".
Well I am new to DDD and I feel there are a lot of elements in DDD that has universal appeal and can be used across the board, irrespective of the fact whether your application is complex enuf to mandate DDD. For example, layering of application, differnent artifacts that DDD recognises etc. May be start with the basics and admittedly anemic models and then work/refactor towards as much purity as one can get.
Does this approach sound good?
Or would you say that there is a fundamental choice in design of every application in terms of whether to go DDD way or not , kind of "all-or-none" choice?
UPDATE (to provide more context, in response to hugh's comment below)
I am building a webapp around an existing RuleEngine kind of application, basically CRUD and some validations, invariants and then a process of deployment. The rule-authoring and semantic check is done by a standalone piece of code that i call as part of the CRUD and none of that semantic specific logic is there in my code. I am trying to use DDD for this application, but i see it might not be complicated enough to fit into the DDD paradigm. There is no ubiquitous language defined for the domain i.e the language is not specialized enough beyond naming the set of entities involved. I hear my domain expert speaking in terms of creating, editing, deleting entities.
DDD is not all-or-nothing. Also, many of the patterns described in DDD are not new and can be found all over the place. Eric Evans (the author of the DDD book) just assembled them, formalized them where needed, and set them in relation to each other. You are free to use what fits to your problem space.
What is often overlooked: DDD describes implementation patterns as well as analysis patterns. The analysis patterns may be overkill in many (if not most) applications, but the implementation patterns (i.e. Entities, Specifications, Services) can be of great use in less complex scenarios as well.
In short,
If it's just CRUD, I wouldn't bother.
On the other hand,
If it's got behavior, where the next state of something relies on the previous state, then DDD is something you probably want to consider.
DDD approach is based on two type of patterns: Strategics patterns and Tactical patterns. IMHO, be free to use tactical patterns in every case that you sure can be helpful. But using Strategic patterns can be overkill for some type of domains. If CRUD style thinking, does not have negative impact in modeling process, certainly you doesn't gonna need it.

How does Behaviour Driven Development (BDD) work with Domain Driven Design (DDD)

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"

Domain-driven-design (DDD) pitfalls

I am quite new with DDD and would like to know about any pitfalls you might want to share. I will summarize it later for more newbies to read :)
Thanks
Summary so far:
Anemic domain model where your entities are primarily only data bearing and contain no business logic
Not using bounded contexts enough
Focusing too much on patterns
There is a good presentation on this topic as well here (video).
Probably the most important one: not grokking the central, fundamental principle of the Domain Model and its representation in Ubiquitous Language. With the plethora of technology options around, it's very easy for your head to fill up with ORMs, MVC frameworks, ajax, sql vs nosql, ... So much so there's little space left for the actual problem you're trying to solve.
And that's DDD's key message: don't. Instead, explicitly focus on the problem space first and foremost. Build a domain model shorn of architectural clutter that captures, exposes and communicates the domain.
Oh, and another one: thinking you need Domain Services for everything you can do in the domain model. No. You should always first try to put domain logic with the Entity/Value type it belongs to. You should only create domain services when you find functions that don't naturally belong with an E/V. Otherwise you end up with the anaemic domain model highlighted elsewhere.
hth.
One of the biggest pitfalls is that you end up with a so-called anemic model where your entities are primarily only data bearing and contain no business logic. This situation often arises when you build your domain model on top of an existing relational data model and just make each table in the database an entity in your domain model.
You might enjoy presentation of Greg Young about why DDD fails.
In short:
Lack of intent
Anemic Domain Model
DDD-Lite
Lack of isolation
Ubiquitous what?
Lack of refinement
Proxy Domain Expert (Business analyst)
Not using bounded contexts enough. It's toward the back of the the big blue book but Eric Evans has gone on record as saying that he believes that bounded contexts and ubiquitous language are THE most important concepts.
Similarly, people tend to focus too much on the patterns. Those aren't the meat of DDD.
Also, if you do not have a lot of access to domain experts you are probably not doing DDD, at best you are DDDish.
More concretely, if you end up with many-to-many relationships, you've probably designed something wrong and need to re-evaluate your aggregate roots/contexts
Only adding to what others have already said;
My personal experience is that people often end up with an anemic model and a single model instead of multiple context specific models.
Another problem is that many focus more on the infrastructure and patterns used in DDD.
Just because you have entities and repositoriesand are using (n)Hibernate it doesn't mean you are doing DDD.
It's not from my personal experience with subject, but it was mentioned for a couple of times in DDD books and it's what I've been thinking about recently: use Entities when you really need identity, in other cases use Value Object. I.e., Entity pattern often happens to be the default choice for any model noun, and it's not the way it should be.
Beware of the Big Ball of Mud.
One of the pitfalls of domain driven design is to introduce ambiguity into a model. As explained in the article Strategic Domain Driven Design with Context Mapping:
Ambiguity is the super-villain of our
Ubiquitous Language
This may happen when two distinct concepts share the same name, or when the same concept can have different uses. It may be necessary to
expose the domain structure in
terms of bounded contexts in a context
map
If a model is used in too many different ways, or has too many responsibilities, it may be a sign that it should be divided.

Service Oriented Architecture & Domain-Driven Design

I've always developed code in a SOA type of way. This year I've been trying to do more DDD but I keep getting the feeling that I'm not getting it. At work our systems are load balanced and designed not to have state. The architecture is:
Website
===Physical Layer==
Main Service
==Physical Layer==
Server 1/Service 2/Service 3/Service 4
Only Server 1,Service 2,Service 3 and Service 4 can talk to the database and the Main Service calls the correct service based on products ordered. Every physical layer is load balanced too.
Now when I develop a new service, I try to think DDD in that service even though it doesn't really feel like it fits.
I use good DDD principles like entities, value types, repositories, aggregates, factories and etc.
I've even tried using ORM's but they just don't seem like they fit in a stateless architecture. I know there are ways around it, for example use IStatelessSession instead of ISession with NHibernate. However, ORM just feel like they don't fit in a stateless architecture.
I've noticed I really only use some of the concepts and patterns DDD has taught me but the overall architecture is still SOA.
I am starting to think DDD doesn't fit in large systems but I do think some of the patterns and concepts do fit in large systems.
Like I said, maybe I'm just not grasping DDD or maybe I'm over analyzing my designs? Maybe by using the patterns and concepts DDD has taught me I am using DDD? Not sure if there is really a question to this post but more of thoughts I've had when trying to figure out where DDD fits in overall systems and how scalable it truly is. The truth is, I don't think I really even know what DDD is?
I think a common misconception is that SOA and DDD are two conflicting styles.
IMO, they are two concepts that work great together;
You create a domain model that encapsulates your domain concepts, and expose entry points into that model via services.
I also don't see what the problem is with ORM and services, you can easily use a session/uow per service call.
Just model your service operations as atomic domain commands.
a naive example:
[WebMethod]
void RenameCustomer(int customerId,string newName)
{
using(var uow = UoW.Begin())
{
var customerRepo = new CustomerRepo(uow);
var customer = customerRepo.FindById(customerId);
customer.Rename(newName);
uow.Commit();
}
}
Maybe the problem you are facing is that you create services like "UpdateOrder" which takes an order entity and tries to update this in a new session?
I try to avoid that kind of services and instead break those down to smaller atomic commands.
Each command can be exposed as an operation, or you could have a single service operation that receives groups of commands and then delegate those to command handlers.
IMO, this way you can expose your intentions better.
The most important things about Domain-Driven Design are the big picture ideas:
the ubiquitous language,
the strategic decision-making where you are adding value by working in the core domain (and insulating yourself from other nasty systems), and
the approach to making testable, flexible designs by uncoupling infrastructure from business logic.
Those are broadly applicable, and are the most valuable pieces.
There is a lot of design-pattern stuff about Factories, Services, Repositories, Aggregates, etc., I take that as advice from one experienced developer to another, not as gospel, because so much of it can vary depending on the language and frameworks that you're using. imho they tend to get overemphasized because programmers like us are detail-oriented and we obsess on that kind of stuff. There is valuable stuff there too, but it needs to be kept in perspective. So some of it may not be that relevant to you, or it might grow on you as you work with it.
So I would say it's not like there's a checklist that you can run through to make sure you're using all the patterns, it's a matter of keeping the big picture in mind and seeing how that changes your approach to developing software. And if you pick up some good tips from the patterns that's great too.
Specifically with respect to the SOA thing, I've developed applications that defer all their state to the database, which have used persistence-ignorant domain objects. Writing tests for services that have to mock daos and feed stuff back is drudgery, the more logic I can put in the domain objects the less I have to mess with mocks in my services, so I tend to like that approach better.
There are some concepts introduced with DDD which can actually confuse you when building SOA.
I have to completely agree with another answer, that SOA-services expose operations that act as atomic commands. I believe that a very clean SOA uses messages instead of entities. The service implementation will then utilize the domain model to actually execute the operation.
However there is a concept in DDD called a "domain service". This is slightly different than an application service. Typically a "domain service" is designed within the same ubiquitous language as the rest of the domain model, and represents business logic that does not cleanly fit into an entity or value.
A domain service should not be confused with an application service. In fact, an application service may very well be implemented such that it uses a domain service. After all, the application services can fully encapsulate the domain model within SOA.
I am really really late in this, but I would like to add the following in the very good answers by everyone else.
DDD is not in any conflict with SOA. Instead, DDD can help you maintain a better Service Oriented Architecture. SOA promotes the concept of services, so that you can define better boundaries (oh, context boundary is also a DDD concept!) between your systems and improve the comprehension of them.
DDD is not about applying a set of patterns (e.g. repository, entities etc.). DDD is mostly about trying to model your software, so that all the concepts (i.e. classes in case of object-oriented programming) align directly with concepts of the business.
You should also check this video (especially the last 5 minutes), where Eric Evans discusses exactly this topic.
I've even tried using ORM's but they just don't seem like they fit in
a stateless architecture.
I don't have any reference handy to back this up. However, you're right, ORMs do not fit nicely with DDD as well. This is because, they're trying to bridge the object-relational impedance mismatch, but in a wrong way. They force the software towards an anemic domain model, where classes end up being "plain data holders".
I am starting to think DDD doesn't fit in large systems but I do think
some of the patterns and concepts do fit in large systems.
In the video I've linked above, you can also find Eric explaining that DDD concepts can "break" in very large-scale systems. For instance, imagine a retail system, where each order is an aggregate containing potentially thousands of order items. If you'd like to calculate the order's total amount strictly following DDD, you'd have to load all the order items in memory, which would be extremely inefficient compared leveraging your storage system (e.g. with a clever SQL statement). So, this trade-off should always be kept in mind, DDD is not a silver bullet.
Like I said, maybe I'm just not grasping DDD or maybe I'm over
analyzing my designs?
Excuse me, but I'll have to quote Eric Evans one more time. As he has said, DDD is not for perfectionists, meaning that there might be cases, where the ideal design does not exist and you might have to go with a solution, which is worse in terms of modelling. To read more around that, you can check this article.

Why can't I model my domain using ERD?

I am fairly new to this discussion but I HAVE to ask this question even at the risk of sounding 'ignorant'. Why is it that we now stress so much on 'DDD'. The more I look into 'DDD' the more complex it seems to make my application. Whereas modeling my domain with the database helps keep my application consistent across layers. Then I can use DAL Helpers such as SubSonic or L2S to easily access that model. What is so bad about this? Even in enterprise applications?
Why do we strive to create a new way of modeling our domain when we have a tried and tested one?
I am willing to hear from the purists here.
You can't sell an old methodology, because too many projects failed and too many people know the old methodology anyway. There has to be a new one to market.
If you're doing fine with the old way then use what works. Do pay attention to new stuff, as some really nice ideas come along. But that doesn't mean everything old is bad and stupid. Usually you can incorporate new ideas into the old models to a large degree.
There does come a time to make a move. Like I wouldn't do OOP with structures and function pointers. ;-)
This is actually a really excellent question, and the short answer is "you can." We used to do it that way, and there was a whole area of enterprise (data) modeling. In fact, the common OOD notations evolved from ERD.
What we discovered, however, was that data-driven designs like that had some difficulties, the biggest of them being that the natural structure for a data base doesn't necessarily match well to the natural structure for code.
OOD, to a great extent, derives from the desire to make it easier to find a code structure that has a couple of desirable properties:
it should be easy to think out the design
it should be robust under changes.
The ease to think out design comes originally from Simula, which used what we now think of as "objects" for simulation specifically; it was convenient in simulation to have software entities that correspond to the things you're simulating. It was only later that Alan kay et al at Xerox saw that as a more general structuring method.
The part about robustness under changes had many parents, but one of the most important ones among them was Dave Parnas, you wrote several papers that identified a basic rule for modularization, which I call Parnas' Law: every module should keep a secret, and that secret is a requirements that is likely to change.
It turns out that by combining Parnas' Law with the Simula idea of a "object" as corresponding to something that can be identified with the real world, you tend to get system designs that are more robust under requirements changes than the old way we did things. (Not always, and sometime you have to be crafty, as with the Command pattern. Most objects are nouns, thing that have persistent existence. In the Command pattern, the ideal objects are verbs, things you do.)
However, it also turns out that that structure isn't necessarily a good way to represent the underlying data in a relational database, so we end up with the "object relational impedance mismatch" problem: how to represent the transformation from objectland to database-land.
Short answer: if all you need is a CRUD system that allows users to edit data, just build an Access front-end to your back-end database (or use a scaffolding framework like you mentioned) and call it a day. You should be able to lop off 70% of your budget vs. a domain-driven system.
Long answer: with a data-driven design, what does the implementation of the business model look like? Usually after a couple years of building on new features to your application, you'll find that it's all over the place: tables, views, stored procedures, various application services, code-behind files, presenters/ViewModels, etc. with duplication everywhere. When you're having a conversation with the domain expert about a new feature they are requesting, you are constantly trying to translate from the business language into the language around your implementation, and it just does not translate.
What typically ends up happening is that you are forced to communicate with the business in terms of the implementation of the system, and the implementation becomes the "ubiquitous language" that the business and developers are forced to use when communicating. This has a wide range of consequences. The domain experts in the business start believing that they are experts in the implementation domain, and they start demanding features in terms of implementation rather than the business need they are trying to solve.
Also, you'll find that most data-driven implementations do not follow the "conceptual contours" of the domain, and the components of the system aren't very flexible in how they can be combined together to solve the problem, because they don't map one-to-one with concepts in the business model. When code isn't cohesive, changes and new features may require modifications all over your implementation.
Domain Driven-Design provides tools for making your implementation so closely resemble the business model that it's easy for everyone to speak the language of the business. It allows you to write "executable specifications" that test your implementation, but can actually be understood by your domain experts.

Resources