Modelo de dominio anémico

El modelo de dominio anémico es el diseño de un modelo de dominio en el que los objetos de dominio contiene muy poca o ninguna lógica de negocio (validaciones, cálculos, reglas de negocio, etc.)

Visión general 
Este patrón fue descrito por primera vez por Martin Fowler, quien lo considera un anti-patrón. Dice:

"El horror fundamental de este anti-patrón es que es contrario a la idea básica del diseño orientado a objetos; que es combinar los datos y su procesamiento en un mismo lugar. El modelo de dominio anémico es un estilo de diseño procedural, justamente lo que fánaticos de los objetos como yo hemos estado combatiendo desde los tiempos de Smalltalk. Aún peor es que mucha gente piensa que los objetos anémicos son objetos reales, y por lo tanto, es pasar por alto el hecho de que es el diseño orientado a objetos."

En un diseño de modelo de dominio anémico, la lógica de negocio suele ser implementada en clases distintas que manipulan el estado de los objetos de dominio. Fowler llama a estas clases transaction scripts. Este patrón es una enfoque común en aplicaciones Java, (posiblemente motivado por las primeras versiones de los EJB Entity Beans), así como en aplicaciones .NET, siguiendo la arquitectura de tres capas donde los objetos se sitúan en la categoría de "Entidades de negocio" (aunque las entidades de negocio pueden contener comportamiento).

Fowler describe el patrón transaction script de la siguiente manera:
"La mayoría de aplicaciones pueden verse como una serie de transacciones. Una transacción puede ver cierta información y otra puede hacer cambios sobre ella. Cada interacción entre un cliente del sistema y el servidor del sistema ejecuta cierta cantidad de lógica. En algunos casos, puede ser tan simple como mostrar la información que proviene de la base de datos, en otros, puede requerir muchos pasos de validación y cálculos. Un Transaction Script organiza todo esta lógica como un procedimiento, realizando invocaciones a la base de datos o a alguna otra clase que se encargue de ello. Cada transacción tiene su propio Transaction Script, aunque algunas tareas comunes entre ellas pueden ser situadas en subprocedimientos" 
En su libro "Patterns of Enterprise Application Architecture", Fowler indica que el patrón transaction script puede ser adecuado para pequeñas aplicaciones y evita tener que lidiar con todo lo relativo al mapeo de objetos a base de datos relacional

Razones por las que esto puede ocurrir

El modelo de dominio anémico puede aparecer en sistemas que están influenciados por arquitecturas orientadas a servicios, donde el comportamiento no se transporta o no tiende a ello.

 Arquitecturas de mensajería/pipeline
 APIs SOAP/REST

Arquitecturas como COM+ o Remoting permiten comportamiento, pero progresivamente la web ha fomentado las arquitecturas no conectadas y sin estado.

Beneficios 

 Clara separación de la lógica y los datos.
 Funciona bien en aplicaciones simples.
 Produce lógica sin estado que incrementa la escabilidad.
 Impide la necesidad de una capa de transformación objeto relacional.
 Mayor compatibilidad con los marcos de trabajo de transformación e inyección de dependencias.

Desventajas 

 La lógica no puede ser realmente implementada de una forma orientada a objetos.
 Violación de la encapsulación y del principio de ocultación de la información
 Requiere una capa de negocio separada que contiene toda la lógica que debería encontrarse en el modelo de dominio. Esto además significa que los objetos del modelo de dominio no puede garantizar la corrección y el cumplimiento de las reglas de negocio puesto que la lógica está en otro lugar.
 Requiere de una capa de servicios cuando la lógica de dominio se comparte entre distintos clientes.
 Hace al modelo de dominio menos expresivo.
 Dificulta la mantenibilidad al propagar el efecto de onda ante cambios accidentales.
 Genera código repetido para realizar accesos al modelo anémico desde distintos puntos.

Ejemplo 
Anémicoclass Box
{
    public int Height { get; set; }
    public int Width { get; set; }
}No anémicoclass Box
{
    public int Height { get; private set; }
    public int Width { get; private set; }

    public Box(int height, int width)
    {
        if (height <= 0) {
            throw new ArgumentOutOfRangeException(nameof(height));
        }
        if (width <= 0) {
            throw new ArgumentOutOfRangeException(nameof(width));
        }
        Height = height;
        Width = width;
    }

    public int area()
    {
       return Height * Width;
    }
}

Véase también 

 Plain Old Java Object
 Diseño guiado por el dominio
 GRASP

Referencias

Enlaces externos 
 Anemic Domain Model by Martin Fowler
 Three-Layered Services Application
 Application Architecture for .NET: Designing Applications and Services
 Article on why anemic model may be considered good design
 Writing Clean Code in ASP.NET

Arquitectura de software