What are DDD recommendations for inter-domain referencing design?
Should I try to connect them as "Matryoshka" (put one into another) or it is better to create upper-level "inter-domain" business service?
P.S. Crossing this smooth water, I was unable to find anything useful to read in the Internet, and have started thinking that for this kind of things exist better term than "inter-domain referencing"... Am I right?
DETAILS:
I have two models/business services.
Semantically first domain (A) is CRM with sell/maintenance process for our goods, second domain (B) is "design" data of our goods. We have two view points on our goods: from seller perspective and from engineer perspective.
Actually each model is effective ORM (Object-Relational Mapping) tool to the same database.
There are some inter-domain activities e.g. validations (e.g. sometimes we can sell things to smb. only if some engineering rules are valid).
From developer's point of view I have two clear possibilities (reference B in A or create new cross reference domain/service C ). But from designer perspective I am lost in understanding what kind of Business Service I have when I compose business logic from two different domains.
As far as I know, DDD has no strict rules for 'inter-domain' referencing. At the end of the day your domain model will have to reference basic Java or .NET classes. Or it may reference specialized date/time or graph library (aka 'Generic Domain').
On the other hand DDD has a concept of Bounded Context. And it has quite a few patterns that can be applied when you work at the boundaries of the system. For example 'Anticorruption Layer' can be used to isolate you from legacy system. Other integration styles can be used depending on how much control you have over external code, team capabilities etc.
So there is probably no need to introduce artificial glue layer if you just dealing with two subdomains in one Bounded Context. Might also be worth reading Part 4 of DDD book (Strategic Design).
UPDATE:
Based on the information you provided, it looks like you only have one Bounded Context. You don't seem to have 'linguistic clashes' where the same word have two different meanings. Bounded Context integration patterns are most likely not applicable to your situation. Your Sales domain can reference Products domain directly. If you think of Products domain being more low-level and Sales being high level you can use Dependency Inversion Principle. Define an interface like ProductCompatiblityValidator in Sales and implement it in Products domain. And then inject the actual implementation at the application layer. This way you will not have a direct reference from Sales to Products.
In addition to what Dmitry has already said...
I think of any code that crosses bounded contexts as application layer code. I would have that application layer code reference domain types from both contexts (and their repositories) but not have two domains reference each other. I think it's OK to have business logic in an application layer if it specifically crosses domain boundaries and is unit-testable.
If you really have a hierarchy, then it would be OK to have the the more concrete subdomain reference the more abstract domain. However, I would be careful if this causes you to need to have domain objects reference repositories of any type. Pulling objects out of of a repository is rarely a true domain concept. Referencing repositories is best done in an application layer that sits a layer above the domain model.
Of course this is all as much art as science. I'd try modeling a thin slice of your application a couple different ways and see what friction you run into with each approach.
Related
Im new to learn DDD concept and i cant understand something.
1-What difference between Context Map and Bounded Context and SubDomain?
2-How to recognize relation between Bounded Context ?
As said in the comment, this is a wide subject, and very important in DDD. It is the strategic part of DDD. Anyway I will try to answer your questions with an overall explanation:
DDD is about understanding and distilling the domain of the problem we want to solve. It is a continuous process of learning about the domain, talking to the domain experts. All people (developers, business people, etc) speak the same language. This language is used everywhere (conversations, documentation, source code, ...). It is called the Ubiquitous Language (UL).
The problem domain may have different areas of functionality, which would be domains too. They are the subdomains. So a subdomain is a subset of the problem domain. It is like splitting the problem into smaller subproblems, and a subdomain would be the domain of a subproblem. There are 3 kinds of subdomains:
Core: The point of distillation is to discover the subdomain that has value for the business, i.e., the one that will make your product better than others of the same kind. Such subdomain is the "core subdomain". For example, in "project management", the "task assignement" would be core.
Supporting: It is specialized in some business aspect that helps the core functionality. For example, in "project management", a "calendar" (for marking tasks delivery dates).
Generic: Functionality that maybe needed by any kind of application. For example, authentication and authorization of users.
Subdomains belong to the problem space.
To solve the problem, you model the subdomains, and you create bounded contexts (BCs). In practice, a BC is an autonomous application that contains the software model of a subdomain. A BC has its own UL. It is the context on which a term of the UL has a meaning. UL and BCs are the most important things in DDD. UL drives the BCs identification.
Ideally, you should align 1:1 the subdomains of the problem space with the BCs of the solution space, i.e., you should have a BC for each subdomain.
A team can develop one or more BCs, but a BC should be developed by just one team.
BCs belong to the solution space.
Context Map: It is a drawing that shows the BCs, and the relationships among them. Every relationship is classified in one of the following patterns:
Partnership
Shared Kernel
Customer-Supplier
Conformist
Anticorruption Layer
Open Host Service
Published Language
Separate Ways
Big Ball of Mud
Recognizing which pattern to apply in a relationship it will depend on the particular case you have. Some things that you have to consider are:
The 2 teams collaborate together.
One of the teams doesn't care about the other one.
The teams can negotiate.
The teams are independent.
Changes on a model (upstream) affects to the other model (downstream).
As #Augusto mentioned, this is a couple of chapters in the blue book, but here goes.
The domain model is found in the business rules and how people talk but a simplification of it is captured in code. Certain naming is consistent and the necessary invariants are enforced in the model.
A bounded context is mostly conceptual (might be a namespace, module, project in code as well...). It is the intention to keep a domain model consistent within it. So within the context, a certain ubiquitous language is used. And a model need only serve the needs of THAT context. It is the boundary in which the model can be used. In terms of recognizing these relationships? Some might be subtle but most are not. At least some people in the team will want to "avoid duplication" by unifying the model... so that is a clear indication that there is a relationship. Names are often the same or similar... or could be the same but one is better suited to one domain and another to another domain.
A context map is a bit more of a project management tool. It is a map of how different contexts (and the models within) relate to each other. In an Ordering Domain in an e-commerce system you may have a product. It would lead to A LOT of complication trying to have a unified Product in a model that spanned Ordering, Payments, Content for the website and Inventory domains (for example). So each of those domains should have a separate model. The context map is a diagram and related documentation that relates these bounded contexts together since there would be relationships and translation of data across from one model to the next, as an order flows through the system.
The last element you asked about is a subdomain. Here you probably are referring to a generic subdomain. Personally, I think the name is a little confusing. It makes it seem like a subset of the model. Maybe this is on purpose but I generally think of them as their own domain, just one that is not central to the business's proposition. For instance, if the aforementioned e-commerce company was known for its same day or next day delivery, then they probably shouldn't buy an off-the-shelf solution to inventory and shipping management. On the other hand, if they were focusing on a market that just wanted the cheapest deal but didn't mind waiting a few days, then that would be a perfect candidate for a generic subdomain.
My DDD glossary which has plenty of links at the bottom to more detailed articles.
If you are serious about learning this subject and can get your hands on some books:
Domain-driven Design by Eric Evans
Implementing Domain-driven Design by Vaughn Vernon
Domain-driven Design made functional by Scott Wlaschin (my favourite)
In Domain Driven Design, domain services should contain operations that do not naturally belong inside an entity.
I've had the habit to create one service per entity and group some methods inside it (Organization entity and OrganizationService service).
But the more I think about it: OrganizationService doesn't mean anything, "Organization" is not a service, it's a thing.
So right now I have to add a Organization deep copy functionality that will duplicate a whole Organization aggregate, so I want to put it in a service.
Should I do: OrganizationService::copyOrganization(o)?
Or should I do: OrganizationCopyService::copyOrganization(o)?
More generally: is a "service" an abstract concept containing several operations, or is a service a concrete operation?
Edit: more examples given the first one wasn't that good:
StrategyService::apply()/cancel() or StrategyApplicationService::apply()/cancel()? ("Application" here is not related to the application layer ;)
CarService::wash() or CarWashingService::wash()?
In all these examples the most specific service name seems the most appropriate. After all, in real life, "car washing service" is something that makes sense. But I may end up with a lot of services...
*Note: this is not a question about opinions! This is a precise, answerable question about the Domain Driven Design methodology. I'm always weary of close votes when asking "should I", but there is a DDD way of doing things.*
I think it's good if a domain service has only one method. But I don't think it is a rule like you must not have more than one method on a domain service or something. If the interface abstracts only one thing or one behaviour, it's certainly easy to maitain but the granularity of the domain service totally depends on your bounded context. Sometimes we focus on low coupling too much and neglect high cohesive.
This is a bit opinion based I wanted to add it as a comment but ran out space.
I believe that in this case it will make sense to group the methods into one a separate OrganizationFactory-service with different construction method.
interface OrganizationFactory{
Organization createOrganization();
Organization createOrganizationCopy(Organization organization);
}
I suppose it will be in accordance with information expert pattern and DRY principle - one class has all the information about specific object creation and I don't see any reason to repeat this logic in different places.
Nevertheless, an interesting thing is that in ddd definition of factory pattern
Shift the responsibility for creating instances of complex objects and
AGGREGATES to a separate object, which may itself have no
responsibility in the domain model but is still part of the domain
design. Provide an interface that encapsulates all complex assembly
and that does not require the client to reference the concrete classes
of the objects being instantiated.
the word "object" is in a generic sense doesn't even have to be a separate class but can also be a factory method(I mean both the method of a class and the pattern factory method) - later Evans gives an example of the factory method of Brokerage Account that creates instances of Trade Order.
The book references to the family of GoF factory patterns and I do not think that there's a special DDD way of factory decomposition - the main points are that the object created is not half-baked and that the factory method should add as few dependecies as possible.
update DDD is not attached to any particular programming paradigm, while the question is about object-oriented decomposition, so again I don't think that DDD can provide any special recommendations on the number of methods per object.
Some folks use strange rules of thumb, but I believe that you can just go with High Cohesion principle and put methods with highly related responsibilities together. As this is a DDD question, so I suppose it's about domain services(i.e. not infrastructure services). I suppose that the services should be divided according to their responsibilities in the domain.
update 2 Anyway CarService can do CarService::wash()/ CarService::repaint() / CarService::diagnoseAirConditioningProblems() but it will be strange that CarWashingService will do CarWashingService::diagnoseAirConditioningProblems() it's like in Chomsky's generative grammar - some statements(sentences) in the language make sense, some don't. But if your sentence contains too much subjects(more than say 5-7) it also will be difficult to understand, even if it is valid sentence in language.
I have started reading few chapters of the blue book and have read the first three chapters of red book (Implementing Domain Driven Design). I have a two questions:
(1) Can a sub-domain have more than one bounded context? I am particularly looking at the example in Implementing Domain Driven Design book where there is a forecasting sub-domain sort of coupled/overlap with inventory. (Apologies if you have not read the book, but the idea is that there is a strong overlap between the two bounded contexts).
(2) How do I organize my project solution structure (I am using .net), are there any examples of real world projects that I can look at? Should I create folders namely sub-domain, core-domain, generic-domain and then specify the modules under it? I am struggling on how best to define my structure so that it shows the onion/hexagonal layers is in place.
Thanks in advance.
Yes. The Domain is composed from multiple sub domains (if it is complex enough) and each are in fact a group of bounded contexts. The Domain itself can be considered a bounded context (BC) from the app point of view.
A BC doesn't mean that it contains an unique model, but a specific representation of the business concept. So you can have a Book definition in multiple BC but in each, the definition is slightly different, ranging from full details to just an id. So the Book from Inventory is different than a Book from Sales for example. It matters how that BC understands a concept.
The resulting model is valid only in that BC, although it can have the same name as the model from another BC. But that's what namespaces are for.
There isn't a recipe for that, everyone structure their projects how they see fit. But most of the time you'll have at least one Domain project and UI, Persistence, Infrastrcuture projects. I think that the best structure depends on the app and on how the developers thinks so the way I do things might not be the optimum way for you. In a nutshell, structure the app as it makes sense for you.
When you are developing an architecture in OO/DDD style and modeling some domain entity e.g. Order entity you are putting whole logic related to order into Order entity.
But when the application becomes more complicated, Order entity collects more and more logic and this class becomes really huge.
Comparing with anemic model, yes its obviously an anti-pattern, but all that huge logic is separated in different services.
Is it ok to deal with huge domain entities or i understand something wrong?
When you are trying to create rich domain models, focus entities on identity and lifecyle, and thus try to avoid them becoming bloated with either properties or behavior.
Domain services potentially are a place to put behavior, but I tend to see a lot of domain service methods with behavior that would be better assigned to value objects, so I wouldn't start refactoring by moving the behavior to domain services. Domain services tend to work best as straightforward facades/adaptors in front of connections to things outside of the current domain model (i.e. masking infrastructure concerns).
You can also put behavior in Application services, but ask yourself whether that behavior belongs outside of the domain model or not. As a general rule, try to focus application services more on orchestration-style tasks that cross entities, domain services, repositories.
When you encounter a bloated entity then the first thing to do is look for sets of cohesive set of entity properties and related behavior, and make these implicit concepts explicit by extracting them into value objects. The entity can then delegate its behavior to these value objects.
Since we all tend to be more comfortable with entities, try to be more biased towards value objects so that you get the benefits of immutability, encapsulation and composability that value objects provide - moving you towards a more supple design.
Value objects enable you to incorporate a more functional style (eg. side-effect-free functions) into your domain model and thus free up your entities from having to deal with the complexity of adding complicated behavior to the burden of managing identity and lifecycle. See the pattern summaries for entities and value objects in Eric Evan's http://domainlanguage.com/ddd/patterns/ and the Blue Book for more details.
When you are developing an architecture in OO/DDD style and modeling
some domain entity e.g. Order entity you are putting whole logic
related to order into Order entity. But when the application becomes
more complicated, Order entity collects more and more logic and this
class becomes really huge.
Classes that have a tendency to become huge, are often the classes with overlapping responsibilities. Order is a typical example of a class that could have multiple responsibilities and that could play different roles in your application.
Given the context the Order appears in, it might be an Entity with mutable state (i.e. if you're managing Order's commercial condition, during a negotiation phase) but if you're application is managing logistics, an Order might play a different role: and an immutable Value Object might be the best implementation in the logistic context.
Comparing with anemic model, yes its
obviously an anti-pattern, but all that huge logic is separated in
different services.
...and separation is a good thing. :-)
I have got a feeling that the original model is probably data-centric and data serving different purposes (order creation, payment, order fulfillment, order delivery) is piled up in the same container (the Order class). Can't really say it from here, but it's a very frequent pattern. Not all of this data is useful for the same purpose at the same time.
Often, a bloated class like the one you're describing is a smell of a missing separation between Bounded Contexts, and/or an incomplete Aggregate separation within the same bounded context. I'd have a look to:
things that change together;
things that change for the same reason;
information needed to fulfill behavior;
and try to re-define aggregate boundaries accordingly. And also to:
different purposes for the application;
different stakeholders;
different implicit models/languages;
when it comes to discover the involved contexts.
In a large application you might have more than one model, thus leading to more than a single representation of a single domain concept, at least for concepts that are playing many roles.
This is complementary to Paul's approach.
It's fine to use services in DDD. You will commonly see services at the Domain, Application or Infrastructure layers.
Eric uses these guidelines in his book for spotting when to use services:
The operation relates to a domain concept that is not a natural part of an ENTITY or VALUE OBJECT.
The interface is defined in terms of other elements in the domain model
The operation is stateless
I'm really new to DDD and trying to grasp some of the concepts.
Could someone explain me the idea behind Domain Modeling in DDD.
I have already gone through wikipedia explanation: http://en.wikipedia.org/wiki/Domain_model but still seems like there are some gray areas in my understanding.
Based on what I understood, domain modeling involves building a model around the business entities to express their relationships, express the entities that participate in the model etc..
Isn't this something that has been in practice always? in Object Oriented world, you model business entities into classes, objects etc.. and build the software around this.
What I do not understand is the emphasis Domain Modeling gets in DDD. Is it the same object/class modeling that you find in OO world, or is this something new to DDD ?
How does it differ from Object Oriented design/modeling?
Your answers are highly appreciated.
One distinction is that a "proper" implementation of the Domain Model Pattern in DDD is isolated from cross-cutting concerns.
For example, it contains nothing to do with databases or other persistence. Where it contains validation logic, it is business validation, not "does the name exceed the column length?" validation.
The idea is that the domain model encapsulates "the business" -- in business terms ("ubiquitous language"), to the extent possible -- and exposes relevant aspects of the business to "the program" without acquiescing to the needs of the software.
On the flip side, "the software" is concerned with IO, UI, and the like, but delegates all business logic to the domain model.
In principle, you can wrap your domain model up in an assembly and use it across multiple applications. When business rules change, as they do, you have one very logical place in which to affect the changes (because the model is a 1:1 or nearly-so representation of the relevant aspects of the business and is described in the same terms as the business).
The Domain in DDD does not need to be implemented in OO. In my experience an OO domain model is usually best, but there are very valid examples of situations in which it may not be.
You might implement a domain in rules, with a rule engine (example in The Netherlands where this is done for a large mortgage application). Or you might do it in a functional language. The essence is that your domain, in however fashion it is implemented, is isolated from what I usually call the technical aspects of your application (or, as the previous answer calls it, cross-cutting concerns, although I think there may very well be cross-cutting concerns within a domain). An isolating layer, which may be implemented using adapters, makes the domain as much as possible, even completely, independent from the technicalities. This layer usually leverages patterns such as Facade and Observer.