Anemic Domain Models

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.

image

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

The “No Services on Entities” dogma

Today, we would like to open a new category on our blog under the topic “Trendy patterns that can kill you”.

Since in the field, we observe a lot of confusion in the interpretation of key architecture concepts and their translation at implementation level, we decided it would be worth sharing our point of view with others.

We are aware that some of these interpretations tend to be “broadly accepted” by the community at this stage, and this is why we call them “trendy”, but we still think that these interpretations are often irrelevant or simply useless, at least on the .NET platform.

An important point is that our opinion is anything but dogmatic, and we might even change it over time if we get convinced that it provides a tangible benefit in some scenarios, but we have selected patterns that – to date – have done more harm than good to the .NET projects we know. In the end, everyone will make its own opinion and base decisions for his projects depending on objectives and constraints.

Let us start by the “No Services on Entities” dogma.

What is it?

Many architects argue that no service should be implemented directly on business object classes. Instead, the recommendation would be to create another kind of classes dedicated to implementing the services and consolidate appropriate methods, possibly across several objects.

What is the driver?

The arguments usually emphasize the separation of concerns, and the fact that services cannot always be clearly attached to one specific object.

Why don’t we buy those arguments?

First of all, with a cumulated experience of hundreds of projects, we never faced a situation where the service could not be relatively naturally attached to a business entity.

And the reason is quite easy to understand, a service is not different from a method, except that it is exposed to the outside world. So if you are used to object-oriented programming design, you should always be able to find the relevant class to support the behavior this service is about. Second, separation of concerns is not a goal as such.

It is interesting to separate elements that should not be too closely coupled, either because:

· Those elements can be used separately and separation could then improve reusability (a driver or a plug-in for example)

· Those elements have different evolution cycles and they will not evolve at the same rhythm (business rule intensive components or web user interfaces that need to be frequently revisited for instance)

In our views, and as explained above, a service primarily exists to serve as an interface to external systems, and .NET provides you with all the relevant mechanisms to create interfaces for your objects which need to be exposed as services.

If you need to create interfaces, just do so, once you do have at least two implementations or if you are sure you will have more than one. Do not do it before though, as you won’t be able to change it once you have created the "contract". We will comment further on interfaces in an upcoming post.

Why is this harmful?

We truly believe that adding layers and complexity that are not strictly needed is always harmful, as the biggest challenge of this industry is to deal with systems that are already getting more and more complex, just by technology evolution.

A second argument is that it greatly reduces code readability. It is not easy to find a name for these classes that will support services. In fact they usually end up with names such as SomethingManager, and it does not map to any concrete object, contrarily to what object-oriented programming was primarily designed for.

If you struggle naming your entities, properties or methods, give yourself more time to design, since you are probably on the wrong path. And it is likely that it’ll give a hard time to the ones who will maintain your code in the long run.

The .NET Framework itself is heavily object oriented and does not follow any complex service pattern. If it did, it would simply contain 40,000 classes instead of 20,000.

Follow

Get every new post delivered to your Inbox.

Join 103 other followers