A Upcoming Pandemic of Domain Anaemia

There’s a well-known anti-pattern called the anaemic domain model[1][2].  This anti-pattern basically says domain entities, chronically, have little or no behaviour (remember, object-oriented design is about attributes and behaviour).


It should be obvious that a domain model that isn’t truly object oriented is a domain model with a problem.  But, let’s look at other reasons why the Anaemic Domain Model is an anti-pattern.  Your Domain is the nexus, the essence, of your system.


An anaemic domain model is basically a reporting system.  Each “Entity” becomes, essentially, a query.  This is fine, reporting systems are necessary and prevalent.  But, to shoe-horn a domain model on top of this leads away from good reporting patterns that could add value and increases complexity, needlessly.  The designers spend most of their time trying to force entities on the system, without recognizing the basic reporting nature of the system.  This usually leads to “reports” that have to pull in multiple domain “entities” to generate the report–rehydringing data into an entity (usually through some sort of ORM) with no value added.  i.e. an ORM that will manage the child-parent relationship (and either pre-load or lazy-load aggregates) doesn’t provide much value here.


The worst case scenario with an anaemic domain model is that there really is behaviour there; but it’s not handled in the domain entities; it’s handled in a different layer.  This is a problem because this circumvents the whole point of a domain model and layering. 


One indication of anaemia is that most of the domain classes  simply contain attributes.  Anyone familiar with patterns should recognize this as a Data Transfer Object, not a Domain Entity.  There’s nothing wrong with DTOs, they’re very important in almost all systems with any sort of complexity; but they’re not Domain Entities.  Let’s be truthful, there are systems with little or no behaviour in the domain; and that’s not a bad thing.  Systems like this likely don’t need a Domain Model and may not need techniques like Domain Driven Design.  The quicker people recognize that, the quicker they can be using a more appropriate architecture and design.  In some extreme cases the anaemic-domain-entity-DTOs service other DTOs


Now, where am I going with this?  Well, there’s been a series of guidance out of Microsoft Patterns and Practice about some application “patterns”.


First, let me describe what a pattern is.  A pattern is a way of “documenting a solution to a design problem” [3].  First, for it to be a pattern, it needs to detail the problem and it’s context, then provide a solution.  The latest “patterns” from P&P do not detail the problem or a context.  They’re simply architectural descriptions.


Now the association between the Anaemic Domain Model and the latest P&P guidance.  In 3 of the 5 recently publish “patterns” the following is detail is included: “A Domain Entity pattern is used to define business entities that contain data only.”  This is the very definition of an Anaemic Domain Model.  Plus, in the RIA pattern the following, contradictory, detail is included: “Domain entities are responsible for implementing business rules.  Entities from the domain model represent business objects that contain data and implement behavior [sic]. In other words, the business objects are responsible for implementing business operations and interacting with other business objects.”


This is disconcerting because historically sample code and guidance from Microsoft is simply reused without thought.  This leads to poorly designed and architected applications, and the .NET community as a whole is seen as one that produces poor-quality code and design.  Without context about the problems these patterns try to solve, they will be misused—likely forced upon contexts and situations where they don’t fit, simply because “they’re from Microsoft”.


[1] MF Bliki- AnemicDomainModel


[2] Anemic Domain Model – Wikipedia, the free encyclopedia


[3] Design pattern (computer science) – Wikipedia, the free encyclopedia




Digg ThisDotNetKick This

It’s More Than Syntax

Writing good software is not just about adhering to a programming language’s syntax.  No programming language syntax enforces good design nor does it enforce good programming in all circumstances.


I’ve seen many systems that compiled perfectly fine; but they weren’t good systems.  Some exhibited reliability problems.  Some exhibited maintainability problems.  Some exhibited performance issues.  Some exhibited resistance to change.  All eventually failed at some point; either the system could not change at the required pace, or could never attain an acceptable reliability, etc.


What was wrong with these systems?  The programmers didn’t look beyond the syntax of the language.  They didn’t accept that programming was about correctly constructing software, not simply writing syntactically correct code.  In almost all cases, the projects didn’t have design experience to guide the programming.  The lack of leadership meant that other factors like time-to-market completely dominated the quality of code written.


Now, I’m not saying that big-design-up-front makes for better software.  Big-design-up-front may help with some of the problems of these systems; but it doesn’t help with others and it introduces more problems.


Any good software system needs a certain amount of design, up front–you need to know what you’re going to be working on both from a requirements point of view and an architectural point of view.  The lowest common denominator is generally some architectural vision based upon established wisdom.  With some systems, this doesn’t even need to be complex.  Just enough to guide everything the programmers do.


With any system, its goal is to fulfill the requirements of the stakeholders.  Some requirements (often many) are known at the onset of the project; but some are elicited throughout the evolution of the system.  I say system instead of project because a successful system generally consists of more than one project.  A project could be as granular as a particular iteration, or may be as wide as a project release.  In either case a system changes over time for as long as the system is in use.  To ignore that is to doom the system to failure.  Ignoring the fact that the system must change over the life of the system usually results in things like “requirements sign-off”, lack of iterations, big-design-up-front, etc.


In any case, gauging the correctness of a system based on errors/warnings from the compiler is a mistake.  The architecture of the system must utilize established patterns for it to be maintainable and for it to be able to evolve over time.  The development of the system must employ unit testing to ensure the correctness of the system in light of its evolution.  The system must be monitored over its evolution to ensure it’s following the architectural design.  If it’s not following the architectural design, find out why; and re-evaluate the architecture if need be.


In short, good programmers know much more than simply the syntax of the language they’re using.


 



Digg ThisDotNetKick This

House of Cards Design Anti-pattern

I’ve had this anti-pattern in my head for years.  It’s an observance of some projects and methodologies that I’ve witnessed over the years.  I believe it’s a form of Voodoo Programming, Programming by coincidence, and is often a side effect of Cargo Cult Programming.

Anti-Pattern Name
House of Cards Anti-pattern

Problem
A problem occurs when software is written that works in a specific observed scenario but no one knows why it works in that scenario.  Observation of "working" is taken as enough evidence of completeness.  It is very often not enough to observe something working in one scenario for the software to be considered "correct".

This is often a result of continual hacks in sole response to correcting bugs without consequence to design or maintainability.  Repeated hacks (cards) are are placed on top of other hacks until something has the appearance of "working" then all development on it stops and no one wants to go near the code again for fear of breaking it.

At the very least, House of Cards design is fragile, hard to maintain, un-agile.  Worst case it’s is of low quality and prone to error and data lose.

This is a general sign of cowboy coding.  I means there is no acceptable methodology, and no real management.  There’s little development direction, and likely no development leadership (at least none with any meaningful experience).  Features are generally driven solely by an external source that communicates directly with developers.

Symptoms

When reviewing code or questioned about code, developers respond with comments like "don’t touch it, it works", or "we don’t want to change it because it works".  There’s a reluctance to change the code because no one really knows why it works.  The code stagnates, new features are slow to be implemented, and there’s a general un-assuredness about the code.

The code is generally procedural, although following object-oriented syntax.

Refactored Solution

Establish experienced development leadership.  Establish a development methodology that separates the stakeholders from the developers.

Invoke Agile methodologies to manage the requirements of the project and begin Agile redesign of the code employing unit testing, refactoring, patterns, etc.  Aggressively refactor the code adding unit tests to test for specific problems as they arise, until the code is robust and reliable.  Mandate adherence to SOLID principles: classes adhere to Single Responsibility Principle, Open-Closed Principles, Liskov Substitution Principle, Interface Segregation Principle, and uses the Dependency Inversion Principle

Digg ThisDotNetKick This