Last time we discussed the concept of model driven design, and introduced a miniature domain model representing a Business Partner. Yet in real world applications, domain models aren’t that simple, in fact they tend to become pretty unwieldy if not extremely large. As the business domain that we are trying to capture is rather complex, it seems logical that the domain model is complex as well. Still, the practice of Domain Driven Design is trying to tackle the complexity at the heart of the matter. To prevent from having dependencies all over the place, it’s recommended to divide your domain model into distinct parts with little or no coupling between the parts, these parts are called modules. Modules should be named after business terms, in fact if the name of the module isn’t part of the Ubiquitous Language, you probably started of on the wrong foot. Even though modules are designed to reduce coupling between business concepts, dependencies are allowed, but only in one direction. It’s perfectly normal that one part of your business domain depends on another part of the same domain.
I like to represent modules with folders containing classes in the domain. In the future though I hope we can have a nice DSL that displays the domain layer with all modules as simple shapes in a domain diagram, implemented behind the scenes as folders, and that allows to drill down to the components that are contained in the module. The different types of components that can exist in a module will be discussed in upcoming articles, for now we will continue with a real life example of how to determine modules.
To determine modules one should simply look at the business domain. Currently I’m working on a contracting application for the belgian gas flow manager, so the domain is definitly contracting. Now if you think about contracts, you probably think about different Business Partners signing Agreements right? Business partners can take up different roles depending on the agreement that is signed, they could be shippers, traders, gas flow managers etc. Furthermore agreements can come in many forms: first of all there is the master agreement that says that we’re going to do business together, next we have technical agreements that limit for example the pressure of gas that is exchanged or the rules that apply for allocation of capacity to the buyer and there are many more of these kinds of agreements. But just signing a paper isn’t going to cut it! If you want to, for example, store gas, you have to make sure whether it is possible or we may blow up that nice little storage tank. So you have to ask whether you can get a certain Service at a given point or period in time, services could for example consist of rights to store gas, or to inject it, to trade it, etc…
Now if you look at the description above of a typical contracting domain for the gas flow market, one can identify a few big groups of business logic in there. These big groups, like in this example Business Partners, Agreements and Services, are what modules are all about. Note that there is a direct dependency from Services to Agreements to Business Partners, but not the other way around.
To wrap up, if your domain is rather complex ( and which one isn’t? ), split it up in different parts based on the knowledge that you have of the particular domain, but be sure to let the domain be your guide.
Next time we will start to go through the different components that can be found inside a module.
Stay tuned,
Yves Goeleven
Nice article Yves … what about mapping a module to an assembly instead of a directory ?
Pushing the idea further, an assembly being the container for a module, your module becomes a self-contained & re-usable functional unit of work. As a free feature, assembly references will enforce the constraint of one-way relation between your modules.
Eventually, your Domain Model is composed of several ‘mini-functional frameworks’ that can be re-used accros projects of a customer.
Steve,
We used to do that at my current customer, but we stepped away from the approach because we ended up with too many projects in a typical solution, which caused visual studio to perform badly. But if you plan to have only a handful of modules, it will indeed be a valid approach.