Anemic Domain Models
April 10, 2012 Leave a comment
From our experience as technical auditors, we noted more and more frequent situations where we observe “Anemic Domain Models”. Driven by a lack of understanding of the “Separation of concern” principle, it seems that some unexperimented developers tend to over-create classes applying what they have understood of architecture principles in a very clumsy and ineffective way of coding.
Let’s come back to basic as described a few years ago by Martin Fowler in his post :
The basic symptom of an Anemic Domain Model is that at first blush it looks like the real thing. There are objects, many named after the nouns in the domain space, and these objects are connected with the rich relationships and structure that true domain models have. The catch comes when you look at the behavior, and you realize that there is hardly any behavior on these objects, making them little more than bags of getters and setters. Indeed often these models come with design rules that say that you are not to put any domain logic in the the domain objects. Instead there are a set of service objects which capture all the domain logic. These services live on top of the domain model and use the domain model for data.
That’s exactly what we try to avoid in our projects: those business logic empty classes, often wrapped in an extra layer of procedural services, which in the end just create a procedural style design. Furthermore, as many people think that anemic objects are real objects, thus completely missing the point of what object-oriented design is all about.
Instead, as Eric Evans states about the Domain Layer (or Model Layer):
Responsible for representing concepts of the business, information about the business situation, and business rules. State that reflects the business situation is controlled and used here, even though the technical details of storing it are delegated to the infrastructure. This layer is the heart of business software.
And we completely agree: especially right now, on the verge of a new technology wave (e.g. HTML5 & WinRT) the real key is your architecture. If you already have this rich domain layer, upper layers should just be consumers of it, empty shells providing user interaction to the heart of your business software. Consequently supporting a new platform (going from desktop to web, or Web Forms to MVC for instance) gets down to creating this new shell.
That’s exactly the reason why we created CodeFluent Entities, with the first goal of generating a real .NET Business Object Model: it generates a full .NET domain layer containing your business logic and which can be used across all .NET technologies (Windows Forms, WPF, SharePoint, ASP.NET MVC, ASP.NET Web Forms, Windows Workflows, etc.) this way securing your investments.
This is possible as the Business Object Model producer (= code generator) can generate:
- Classes: plain old classes (not deriving from a base technical class), human readable, that are all partial and meant to be easily extensible by developers, implementing an extensive set of interfaces (ICloneable, IComparable, IDataErrorInfo, IEquatable, INotifyPropertyChanged, etc.) to ease development of upper layers, and easily debuggable as no code is dynamically generated at run time
- Enumerations: since CodeFluent Entities is not an ORM, you can create your own .NET enumerations or reuse existing ones,
- Multiple namespaces: as its common to have more than a single domain in real enterprise class applications,
- Rules: to validate your data, set-up transactions, and implement your business logic,
- Methods: create your own methods aside default generated ones,
- light objects as structures or non-persistent objects useful to gather-up cross entity information,
- components as a binary large object http handler to manipulate blobs in web environments, or a cache manager based on the standard ASP.NET cache manager, and more.
Last but not least, we don’t think that tools can generate entire enterprise-class applications, that’s not what we’re saying, developing applications is a complex operations that needs more than data access and/or UI controls. Instead what we’re saying is that we provide a tool to developers which helps them set-up rock-solid foundations for their .NET applications, built on a consistent domain model, which developers will have to extend and fill-in the gaps.
The recipe we provide through CodeFluent Entities ends-up creating .NET applications based on a rich Domain Layer built by the tool and developers, containing the full business logic of your application. It’s a complete and consistent API which can be used on all platforms (x86, x64, desktop, web) across all technologies (.NET 2 to 4) this way securing your investments.
And even if you are not considering using our tool, we still think it is a very bad idea to follow this path of “Anemic Domain Models” and that you should create real domain models, either by hand or by finding another tool can do it the right way.
Daniel COHEN-ZARDI, with the support of the R&D team