In DDD, how to mix repositories ?
For example, a simple social network app where a personn write a post and mention someone.
Do the best way is to check if "the mentioned person" exist in user domain and throw a event for post domain for example ?
I think there are a lot of examples when a API need to mix domain.
I had read some article which explains to use event system.
Is the only solution ? I'm not looking for the best solution or a "pure ddd app".
First of all, there's no such thing as a "pure ddd app".
DDD is architecturally agnostic. There's no architectural style you must follow. It will only depends on the domain complexity of the context you're working on. For example, don’t be afraid to go with a CRUD‐style architecture if you are dealing with a context that contains no logic. Doing so, you'll be more in a DDD mindset than trying to apply things like Hexagonal/Onion/CQRS/EventSourcing and whatever good-looking architecture styles everywhere.
What you're describing in your question above is only related to the tactical part of DDD: what kind of code pattern would be nice to implement in order to solve my problem?
Let's say you have 2 different Bounded Context (see Stategic Patterns in DDD). One that deals with Users and one with Posts, as you mentioned above. As those are two separate contexts, they could have their own storage. In the Posts context, you could store a list of valid UserIDs that people can use when they want to mention someone. That way, you don't have to call any APIs to be sure that this UserID can be mentioned. In order to maintain this list, you also have many options. One could be to listen to events triggered by the Users context like UserSuscribed or UserUnsubscribed. Another option would be to give the responsibility to the Users context to call an API on the Posts context in order to add or delete UsersIDs.
In general, try to avoid coupling between your Bounded Contexts.
Related
I have a web application with news posts. Those news posts should be searchable. In context of DDD what kind of buililng block are search query and search result?
These are my thoughts
They both don't have identity, therefore they are not Entities. But the absence of identity doesn't imply they are Value Object. As Eric Evans states:
However, if we think of this category of object as just the absence of identity, we haven't added much to our toolbox or vocabulary. In fact, these objects have characteristics of their own and their own significance to the model. These are the objects that describe things.
I would like to say that both are value objects, but I'm not sure. What confuses me are examples that I've found on Internet. Usualy value object are part of other entities, they are not "standalone". Martin Fowler gives for example Money or date range object. Adam Bien event compares them to enums.
If search result would be considered value object, that would be value object that consists of entities. I'm not sure that's completely alright.
I don't think they are DataTransferObject. Because we are not current concerned with transferring data between layers, but we are concerned with their meaning for the model in absence of layer.
I don't think search query is command. Because it's not a request for change.
As stated on CQRS
People request changes to the domain by sending commands.
I'm trying to use and learn DDD, can someone clarify this problem to me? Where did I go wrong with reasoning?
The simple answer is that querying is probably not part of your domain. The domain model is not there to serve queries, it is there to enforce invariants in your domain. Since by nature queries are read-only, there are no invariants to enforce, so why complicate things? I think where people usually go wrong with DDD is that they assume since they are "doing DDD" every aspect of the system must be handled by a domain model. DDD is there to help with the complex business rules and should only be applied when/where you actually have them. Also, you can and probably should have many models to support each bounded context. But that's another discussion.
It's interesting that you mention CQRS because what does that stand for? Command query responsibility segregation. So if commands use the domain model, and query responsibility is segregated from that, what does that tell you to do? The answer is, do whatever is easiest to query and display that data. If select * from news table filled to dataset works, go with that. If you prefer entity framework, go with that. There is no need to get the domain model involved for queries.
One last point I'd like to make is I think a lot of people struggle with DDD by applying it to situations where there aren't many business invariants to enforce and the domain model ends up looking a lot like the database. Be sure you are using the right tool for the job and not over complicating things. Also, you should only apply DDD in the areas of your system where these invariants exist. It's not an all or nothing scenario.
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.
I've got a question on my mind that has been stirring for months as I've read about DDD, patterns and many other topics of application architecture. I'm going to frame this in terms of an MVC web application but the question is, I'm sure, much broader. and it is this: Does the adherence to domain entities create rigidity and inefficiency in an application?
The DDD approach makes complete sense for managing the business logic of an application and as a way of working with stakeholders. But to me it falls apart in the context of a multi-tiered application. Namely there are very few scenarios when a view needs all the data of an entity or when even two repositories have it all. In and of itself that's not bad but it means I make multiple queries returning a bunch of properties I don't need to get a few that I do. And once that is done the extraneous information either gets passed to the view or there is the overhead of discarding, merging and mapping data to a DTO or view model. I have need to generate a lot of reports and the problem seems magnified there. Each requires a unique slicing or aggregating of information that SQL can do well but repositories can't as they're expected to return full entities. It seems wasteful, honestly, and I don't want to pound a database and generate unneeded network traffic on a matter of principle. From questions like this Should the repository layer return data-transfer-objects (DTO)? it seems I'm not the only one to struggle with this question. So what's the answer to the limitations it seems to impose?
Thanks from a new and confounded DDD-er.
What's the real problem here? Processing business rules and querying for data are 2 very different concerns. That realization leads us to CQRS - Command-Query Responsibility Segregation. What's that? You just don't use the same model for both tasks: Domain Model is about behavior, performing business processes, handling command. And there is a separate Reporting Model used for display. In general, it can contain a table per view. These tables contains only relevant information so you can get rid of DTO, AutoMapper, etc.
How these two models synchronize? It can be done in many ways:
Reporting model can be built just on top of database views
Database replication
Domain model can issue events containing information about each change and they can be handled by denormalizers updating proper tables in Reporting Model
as I've read about DDD, patterns and many other topics of application architecture
Domain driven design is not about patterns and architecture but about designing your code according to business domain. Instead of thinking about repositories and layers, think about problem you are trying to solve. Simplest way to "start rehabilitation" would be to rename ProductRepository to just Products.
Does the adherence to domain entities create rigidity and inefficiency in an application?
Inefficiency comes from bad modeling. [citation needed]
The DDD approach makes complete sense for managing the business logic of an application and as a way of working with stakeholders. But to me it falls apart in the context of a multi-tiered application.
Tiers aren't layers
Namely there are very few scenarios when a view needs all the data of an entity or when even two repositories have it all. In and of itself that's not bad but it means I make multiple queries returning a bunch of properties I don't need to get a few that I do.
Query that data as you wish. Do not try to box your problems into some "ready-made solutions". Instead - learn from them and apply only what's necessary to solve them.
Each requires a unique slicing or aggregating of information that SQL can do well but repositories can't as they're expected to return full entities.
http://ayende.com/blog/3955/repository-is-the-new-singleton
So what's the answer to the limitations it seems to impose?
"seems"
Btw, internet is full of things like this (I mean that sample app).
To understand what DDD is, read blue book slowly and carefully. Twice.
If you think that fully fledged DDD is too much effort for your scenario then maybe you need to take a step down and look at something closer to Active Record.
I use DDD but in my scenario I have to support multiple front-ends; a couple web sites and a WinForms app, as well as a set of services that allow interaction with other automated processes. In this case, the extra complexity is worth it. I use DTO's to transfer a representation of my data to the various presentation layers. The CPU overhead in mapping domain entities to DTO's is small - a rounding error when compared to net work calls and database calls. There is also the overhead in managing this complexity. I have mitigated this to some extent by using AutoMapper. My Repositories return fully populated domain objects. My service layer will map to/from DTO's. Here we can flatten out the domain objects, combine domain objects, etc. to produce a more tabulated representation of the data.
Dino Esposito wrote an MSDN Magazine article on this subject here - you may find this interesting.
So, I guess to answer your "Why" question - as usual, it depends on your context. DDD maybe too much effort. In which case do something simpler.
Each requires a unique slicing or aggregating of information that SQL can do well but repositories can't as they're expected to return full entities.
Add methods to your repository to return ONLY what you want e.g. IOrderRepository.GetByCustomer
It's completely OK in DDD.
You may also use Query object pattern or Specification to make your repositories more generic; only remember not to use anything which is ORM-specific in interfaces of the repositories(e.g. ICriteria of NHibernate)
When comming accross concepts within a Domain Model where there exists something that has a name and sounds like an object but overlaps with the responsiblility of one of the 5 main DDD building blocks what is the best practice for naming this object and or dealing with design which may or may not include that name or phrase in the actual implementation?
To give a more concrete example lets say that we are designing a time tracking application in the spirit of DDD and encounter something that the domain experts refer to as a "time log" which is supposed to be the log which holds punch-in and corresponding punch-out times for all employees.
With this information my initial thought is that if there were a class written called TimeLog which allowed for querying existing time entries and also for persisting new or amended time log entries that such a class is really playing the role of a DDD repository. For simplicity sake, lets assume that after various discussions and refactoring that we come to a conclusion that each time log entry is essentially it's own aggregate root and thus has the need for a corresponding repository.
Now we are left with the option of either naming our repository as TimeLog which seems more in line with the DDD concept of ubiquitous language or we could call it TimeLogEntryRepository which seems to fit the more general convention for naming Repositories after the Aggregate root that they query/persist. I'm leaning more towards the the idea of using TimeLog since it is more descriptive of the actual role that it plays in the domain model which should in turn help in communicating design to domain experts. The choice of using TimeLogEntryRepository on the other hand follows existing DDD conventions and thus would make the design easier to follow for developers. A compromise could also be to go with the TimeLog naming but to have all repositories implement an IRepository interface or inherit from a common Repository base class to help developers locate and distinguish repository classes from others that make up the domain model. The main concern I have with using a base class is that it may encourage the use of marker interfaces or a weak unnecessary base class just for the purpose of organization and not due to behavioral factors.
What is the best practice in cases like this? I can see the same type of issue perhaps happening for services as they are another piece of the typical DDD building blocks that developers typically name using a "Service" suffix such as in SomeComplexActivityService but for Entities and Value Objects this is really a non-issue. I'm especially interested to see what others may have to say that have more DDD experience under their belt.
I personally prefer TimeLog.
It's actually amazing how much easier it becomes once you switch focus to business instead of technology. Proper naming is main weapon to keep that focus sharp.
The same goes for services - instead of ApplicationRegistrationService, I use ApplicationRegistrator.
Here's quite nice article about repositories.
I second #Arnis L. suggestion. I would also add that in respect to DDD your domain should reflect the actual UL (Ubiquitous Language) which you share with business analysist and other people that are often non technical people. So I think that you will talk with them about TimeLog and not TimeLogEntryRepository. Repository is just a pattern and it's name should not be in the naming conventions.
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.: