¿Las Entidades de Dominio deben exponerse como Interfaces o como Objetos Simples?


¿Las Entidades de Dominio deben exponerse como Interfaces o como Objetos Simples ?

La Interfaz de usuario:

public interface IUser
{
    string FirstName { get; set; }
    string LastName { get; set; }
    string Email { get; set; }
    Role Role { get; set; }
}

La Implementación de Usuario (Implementada en la Capa de Acceso a Datos LinqToSql):

public class User : IUser
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    public Role Role { get; set; }
}

La Implementación del Usuario (Implementada en la Capa de Acceso a Datos NHibernate):

[NHibernate.Mapping.Attributes.Class]
public class User : IUser
{
    [NHibernate.Mapping.Attributes.Property]
    public string FirstName { get; set; }

    [NHibernate.Mapping.Attributes.Property]
    public string LastName { get; set; }

    [NHibernate.Mapping.Attributes.Property]
    public string Email { get; set; }

    [NHibernate.Mapping.Attributes.Property]
    public Role Role { get; set; }
}

Esto solo ilustra algunas implementaciones específicas de DAL, no tengo una mejor muestra en este momento.

Author: Yoann. B, 2010-03-01

4 answers

Mi opinión sobre esto es que los objetos de dominio (no las entidades de dominio , ya que ese título implica algo que ver con una base de datos) no deberían ser interfaces a menos que tenga una razón muy convincente para creer que necesitará soportar múltiples implementaciones en algún momento en el futuro.

Considere que el modelo de dominio es el modelo humano. El negocio/servicio/documento es, literalmente, el dominio. La mayoría de nosotros estamos desarrollando software para un solo negocio o propósito. Si el cambios en el modelo de dominio, es porque las reglas de negocio han cambiado, y por lo tanto el antiguo modelo de dominio ya no es válido - no hay razón para mantener el viejo alrededor, corriendo junto al nuevo.

El debate obviamente no es blanco y negro. Es posible que esté desarrollando software que está muy personalizado en varios sitios de clientes. Es posible que realmente necesite implementar diferentes conjuntos de reglas de negocio al mismo tiempo, y al mismo tiempo tener una necesidad genuina de encajarlas en un arquitectura. Pero, al menos en mi experiencia, estos casos son la excepción más que la regla, y aunque no soy generalmente aficionado al término, este podría ser un caso en el que deberías estar pensando para ti mismo, YAGNI.

El acceso a los datos es un área común donde desea mejores abstracciones ( ignorancia persistente). En su ejemplo, tiene atributos NHibernate en su clase model. Pero agregar atributos de persistencia hace que ya no sea una verdadera clase de dominio porque introduce una dependencia de NHibernate. NHibernate y Fluent NHibernate admiten la asignación de POCOs mediante una declaración de asignación externa en lugar de atributos en la clase de datos, y este suele ser el enfoque preferido cuando se utilizan OR como NHibernate o EF4, porque rompe la dependencia entre el modelo de persistencia y el modelo de dominio.

Si estos métodos de asignación no fueran compatibles, y usted tuviera para usar atributos, entonces podría sugerir el uso de interfaces en su lugar, peroMs hoy en día son más sofisticados que eso, utilizando la reflexión y los proxies dinámicos y la interceptación de métodos para hacer la mayor parte del trabajo pesado, por lo que no es necesario crear sus propias abstracciones aquí.

Algunos tipos de objetos que se desea exponer como interfaces son:

  • Repositorios, que son responsables de cargar / guardar objetos de dominio;
  • Complementos / extensiones de su programa;
  • Ver/modelos de presentador, para que se puedan conectar diferentes UIS in;
  • Los tipos de datos abstractos con muchas implementaciones (matriz, lista, diccionario, conjunto de registros y tabla de datos son todas secuencias AKA IEnumerable);
  • Operaciones abstractas con muchos algoritmos posibles (ordenar, buscar, comparar);
  • Modelos de comunicación (mismas operaciones sobre TCP/IP, tuberías con nombre, RS-232);
  • Cualquier cosa específica de la plataforma, si planea implementarla en más de una (Mac/Windows/*nix).

Eso no es de ninguna manera una lista completa, pero debería iluminar la principio básico aquí, que es que las cosas más adecuadas para abstracciones de interfaz son las cosas que:

  1. Depende de factores que probablemente estén más allá de su control;
  2. Es probable que cambien en el futuro; y
  3. Son características horizontales (utilizadas en muchas partes de la aplicación/arquitectura).

Una clase de dominio será ampliamente utilizada, pero no encaja en ninguna de las dos primeras categorías; no es probable que cambie, y usted tiene un control casi completo sobre diseño. Por lo tanto, a menos que las clases mismas estén tomando dependencias indirectas (que es una situación que debe tratar de evitar siempre que sea posible), no pasaría por el esfuerzo adicional de crear una interfaz para cada clase en el modelo de dominio.

 27
Author: Aaronaught,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-28 21:56:18

Las interfaces normalmente se consideran "contratos" y por lo tanto definirían el comportamiento. El otro uso importante es para simular, para que pueda proporcionar entidades de dominio que eran maquetas en lugar de provenir de una fuente de datos específica (y tener dependencias en esa fuente).

Para un objeto de transferencia de datos simple, no puedo ver mucho uso para definir interfaces, pero estoy dispuesto a ser probado equivocado. Yo iría con objetos simples para esto.

 7
Author: Cylon Cat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-28 21:13:38

Objetos planos, a menos que haya una interfaz común para una implementación que pueda cambiar. Para eso están las interfaces. Las clases de valor como el Dinero o la dirección no entran en esa categoría.

Su interfaz de ejemplo no tiene ningún comportamiento más allá de getter/setter. Las interfaces no son para eso.

 1
Author: duffymo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-28 21:10:39

En la mayoría de los casos, no se debe escribir una entidad.

Una Entidad define explícitamente una identidad única para otras entidades del mismo tipo. Una entidad de orden ya debe tener una identidad que sea diferente de todas las demás entidades de Orden en el sistema. También puede ser perjudicial para la identidad de una entidad si se modela a través de la herencia.

Por ejemplo: Digamos que tienes un Customer e implementas Customer como AmericanCustomer. Darle todo el comportamiento y el estado necesario para ser un cliente estadounidense (pista: le encanta ir de compras!). Luego más tarde ese mismo Customer, con el mismo nombre, los mismos hábitos de compra - viajes a Japón. ¿Siguen siendo un AmericanCustomer? ¿Crea un nuevo JapaneseCustomer y copia todos los datos, incluido el ID de ese cliente, en este nuevo tipo? Eso podría tener consecuencias..

¿A ese mismo cliente todavía le encanta ir de compras? Eso puede o no ser cierto para el JapaneseCustomer. Sin embargo, ahora, de repente, dentro de un solo vuelo reservado, esto Customer es diferente. Otros objetos en el sistema lo solicitarán Customer usando su id único y puede terminar con una imagen diferente del objeto de lo que esperaban (un AmericanCustomer). Tal vez el Cliente se modela en torno al origen nacional en lugar de la ubicación actual. Eso podría resolver algunos de los problemas, pero también introducir otros nuevos.

Modele sus Entidades alrededor de su identidad. La identidad no es solo acerca de los campos de identificación. Un modelo es más que eso. Las entidades deben tener un comportamiento significativo en forma de lógica de negocio, sí, pero no son servicios. No deberías esté preocupado por el envío polimórfico a diferentes comportamientos. Lo que es más importante es cómo su sistema ve esta Entidad a través de su identidad única. Evita pensar en tipos de entidades. Organízate en torno a identidades.

 1
Author: Seph,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-22 00:59:05