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.
Related
I am currently taking a course that gives an introduction to project planning. It is mostly about how to draw UML diagrams (blegh), but also has a few other topics.
One part in particular keeps bugging me. In the course they describe a method for going from a set of requirements to an initial class diagram, but everything about the method gives me this feeling that it is most definitely not the way to go. Let me first give an example before proceeding.
Let's consider a system that manages a greenhouse company. The company has multiple greenhouses, and every employee is assigned to his/her own greenhouse. A greenhouse has a location and a type of plant being grown in there. An employee has a name and phone number.
Here's what according to the course's method the class diagram would look like:
To me this looks like a database layout adapted for code. When I go about designing a program, I try to identify major abstractions. Like all the code that interacts with the database or the code that is responsible for the GUI are all different parts of the system. That would be what I consider to be an initial class diagram.
I simply can not imagine that this is a common way to start designing the architecture of a project. The classes look ugly, since if you take a slightly larger example the classes will be flooded with responsibilities. To me they look like data objects that have functionality to them they shouldn't have. It does not give me a clue on how to continue from here and get a general architecture going. Everything about it seems obsolete.
All I want to know if there's someone out there that can tell me if this is a common way to get a first class diagram on paper for reasons I am overlooking.
I would say it's reasonable to start with a logical model that's free of implementation constraints. That logical model is not necessarily concerned with physical implementation details (e.g. whether or not to use a database, what type of database, OS / UI choice, etc.) and thus represents just "real" business domain objects and processes. The similarity to a potential database implementation shouldn't be surprising for the simple example.
By understanding your business domain (through the logical model you've started to construct), you will be better placed to subsequently identify, for example, which architectural patterns are appropriate, what screens you need to build, and database elements to design. Possibly, there will be another part of the course that will aid you in this stage.
In practice, you will often know that you're intending to implement, say, a web-based application using MVC with a back-end database, and may look to model the implementation classes in parallel with your business items. For your course to use a method that emphasises the distinction between logical and physical stages doesn't sound unreasonable.
When I go about designing a program, I try to identify major
abstractions
Same principle in UML as well. You represent abstractions and their relationships and due to existing Visual Tools you can do a presentation of a system to stakeholders or even generate automatically stubs from your design.
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've just begun to delve into my first experiments with Domain Drive Design and I'm taking advantage of the NWorkspace pattern. This pattern seems to make a lot of sense however I haven't been able to find very many examples of places this pattern has been successfully used or even publicly documented. Before I get to far into my implementation I would like to know if anybody has had success using this pattern or whether somebody could point me to any references where NWorkspace has been used in any open source project that I could learn from. Also are there better or more well known alternatives to this pattern that I should know about?
Brief background on NWorkspace
For those who may not be familiar with NWorkspace, it is a pattern introduced by Jimmy Nisson's which abstracts query and persistance responsibilities. In his book Applying Domain-Driven Design and Patterns, Jimmy Nilsson shows how NWorkspace can be used to abstract the infrastructure portions of a DDD Repository as well as provide a mechanism to perform cross Repository atomicity with regard to persistence.
It seems like he's recommending separate interfaces for read and write repositories.
I don't have experience with the pattern described, but I would recommend not having cross-repository transactions. Instead, I would suggest a few solutions popular amongst the DDD community (Eric Evans, Udi Dahan, Greg Young) that have really helped me:
Always use eager loading on your aggregate roots. Then you don't need cross-repository atomicity, and figuring out what's changed when you persist the object is a lot easier.
Use separate classes for writing (i.e. domain classes) and reading (i.e. your viewmodel). Create view model repositories that retrieve viewmodels directly from the database (instead of mapping domain objects to view model classes).
See if implementing the above 2 things simplifies your design.
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.:
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.