Every developer has an urge to organize their code in the best way possible. However, this isn't always easy. Many paradigms exist in software architecture, but how do you choose the right one for a project?
At liquidfish, we use a concept called Domain Driven Design. Most developers are probably familiar with DDD, but when I first learned about it, something clicked. It made a lot of sense. Some projects we plan for are not enormous enterprise level applications, but they're not small either. This is where DDD helps me wrap my head around things.
There are many different variations of DDD, ranging from basic to complex. But I'd like to focus on the heart of the idea, which is the domain. This architecture consists of layers, as most do, but the domain is the core layer and primary focus. The inclusion of a domain expert is crucial to the implementation.
A domain expert may be a business manager, CEO, analyst or anyone who knows the business inside and out. The technical liaison or development manager should work with the domain expert to establish a set of standard terms called the "Ubiquitous Language". This is the key to DDD.
Ubiquitous Language simply means the words that people involved in the business use to describe things about the business. Words like customer, associate, product bundle, order, group discount, subscription and so on.
Laying a foundation using the ubiquitous language prevents errors due to miscommunication or mental translation between the business and the development team. You design your software to use the language of the domain and avoid synonyms. This even trickles down to variable names in code and provides a ground work for easily understandable and maintainable applications.
In technical terms, developers organize all of the data models and business logic into a domain layer. This encapsulates business logic into a core code set (otherwise known as a business layer), that uses the ubiquitous language for model names and behavior. It's important to note that this layer does not "know" about any other layers in the application. It's sole responsibility is to house data models and the logic by which those models behave. In .NET terms, it doesn't have a reference to any other assembly.
Behavior is the most important part of a domain layer. If you have a customer object that has a customer type, the customer object should be able to determine on it's own what type it is, either by accessing other types in the domain or by directly integrating the object relational mapping infrastructure. When the customer object only has getters and setters, this is an anti-pattern known as "anemic model".
The domain layer typically interfaces with a service layer, but that's another discussion. For a more complex topic on DDD, see Martin Fowler's website.