As I just said, my new default architecture is based on a Domain Model. We discussed Domain Models a lot in Chapter 1, "Values to Value," but let's discuss it here, also.
Paul Gielens said that a warning is in place regarding the word "Default" in the name of this chapter. The risk is that some readers will get the feeling that this is the way to approach all systems. Let me stress that this is definitely not the case; this book is not aiming to be a template or something like that. Absolutely not! It's in the spirit of DDD to let the business problem govern what your solution looks like!
When one says "Domain Model" in the context of architecture, what is usually meant is usage of the Domain Model pattern [Fowler PoEAA]. It's like old school object-orientation, in that you try to map a simplified view (or more correctly stated, the chosen abstraction) of the reality from your problem domain as closely as possible with an object-oriented model. The final code will be very close to the chosen abstractions. That goes for both state and behavior, as well as for possible navigation paths and relationships between objects.
Someone (unfortunately, I don't remember who) called the application of the Domain Model pattern in C# "programming C# as if it was Small-Talk." To some, that might not sound positive at first, but it was said and meant as a very positive thing.
The Domain Model is not the silver bullet, but it certainly comes with several positive properties, especially for large-scale and/or complex applications that are long lasting. And as Martin Fowler says [Fowler PoEAA], if you start using Domain Model for one project, you will probably find yourself wanting to use it even for small, simple applications later.
From Database Focus to Domain Model Focus
My move from database focus to Domain Model focus was mainly because I changed my emphasis from efficiency to maintenance. It's not that my new design style has to sacrifice efficiency, but I try to avoid those premature optimizations of every little detail that often cost more than they are worth. Instead, I try to create as clear a Domain Model as possible, which makes it easier to do optimizations when really needed. It's not that I'm forgetting about the databaseit's just not my first focus. I try to find suitable compromises, so I do think it's important to deal with the database neatly.
A Domain Model-focused design is more maintainable in the long run because of its increased clarity and an implementation that is more true to the abstractions of the domain. Another very important reason is that a powerful Domain Model is a good tool for decreasing duplication of logic. (Those are all properties of object-orientation as well. I see Domain Model as a style where object-orientation is used in a pure way, pushing the limits to write maintainable code. Oh, and to increase testability.)
When you hear the words "Domain Model pattern" [Fowler PoEAA], it might mean something very specific to you, but of course there are a lot of variations on how to apply that pattern. Let's call the variations different styles.
More Specifically, a DDD Focus
This leads me on to what I consider the main inspiration of my current favorite Domain Model style, that of DDD by Eric Evans [Evans DDD].
As you already know from the lengthy discussion in Chapter 1, DDD is several different things; for example, it is a set of patterns for helping out with structuring the Domain Model. We will get started in applying those tools really soon.
But before focusing on the details, I'd like to take a quick look at layering according to DDD.
Layering According to DDD
In my previous book [Nilsson NED], I talked a lot about a rigorous layering scheme, and I think I need to say at least a few words about how I think about layering today.
In one way, I still stress layering a lot. Because I'm very much into DDD, I try hard to move Infrastructure, such as persistence, into a layer of its own, away from the core Domain layer.
On the other hand, I'm more relaxed about layering and focus a lot of the efforts on a single one: the Domain layer. I won't split that layer, the Domain Model, into finer layers; I let it be pretty coarse-grained. (As a matter of fact, some of the DDD patterns come in handy for some of the problems I previously used layering for.)
We have discussed two layers so far: Infrastructure and Domain. On top of these there might be an Application layer providing some coordination, but it's very thin, only delegating to the Domain layer. (See Service Layer pattern [Fowler PoEAA], which is like scenario classes, delegating all the work to the Domain Model.)
Finally, we have the UI layer on top.
I drew a simplified layering schema example in Figure 4-1.
Figure 4-1. Typical layering for DDD projects
Again, please don't automatically do anything regarding layering just because you read about it in a book! You should challenge every decision!
I think there are few things to note regarding how I use layering now compared to my old style. First of all, the Application layer isn't mandatory; it is only there if it really adds value. Since my Domain layer is so much richer than before, it's often not interesting with the Application layer.
Another difference is that instead of all calls going down, the Infrastructure layer might "know" about the Domain layer and might create instances there when reconstituting from persistence. The point is that the Domain Model should be oblivious of the infrastructure.
It is also important to note we didn't take into account partitioning, or slicing the pieces in the other dimension compared to layering. This is important for large applications. We get back to this in Chapter 10, "Design Techniques to Embrace."
It's time to start our journey and to try out some of the concepts we have been discussing in this and earlier chapters, with a strong focus on the Domain layer. I think a good way of doing that is to set up an example.