The “No Services on Entities” dogma
May 20, 2011 Leave a Comment
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.