Mi opinión al respecto es que los objetos de dominio (no de dominio entidades, como el título lo indica algo que ver con una base de datos) no deben ser las interfaces a menos que tenga una razón muy convincente para creer que tendrá que soportar múltiples implementaciones en algún momento en el futuro.
Tenga en cuenta que el modelo de dominio es el modelo humano. El negocio/servicio/documento es, literalmente, el dominio. La mayoría de nosotros desarrolla software para un solo negocio o propósito. Si el modelo de dominio cambia, es porque las reglas comerciales han cambiado y, por lo tanto, el modelo de dominio anterior ya no es válido; no hay ninguna razón para mantener el anterior, ejecutándose junto con el nuevo.
El debate obviamente no es en 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 negocios al mismo tiempo, y al mismo tiempo tenga una necesidad genuina de integrarlas en una arquitectura unificada. Pero, al menos en mi experiencia, estos casos son la excepción y no la regla, y aunque en general no me gusta el término, este podría ser un caso en el que deberías pensar en ti mismo, YAGNI.
El acceso a datos es un área común donde desea mejores abstracciones (persistence ignorance). En su ejemplo, tiene atributos NHibernate en su clase de modelo. Pero agregar atributos de persistencia hace que deje de ser una verdadera clase de dominio porque introduce una dependencia en NHibernate. NHibernate y Fluent NHibernate admiten mapeo de POCO utilizando una declaración de mapeo externo en lugar de atributos en la clase de datos, y este tiende a ser el enfoque preferido cuando se utilizan ORM como NHibernate o EF4, porque rompe la dependencia entre el modelo de persistencia y el modelo de dominio.
Si no fueron apoyados estos métodos de mapeo, y que tenía utilizar atributos, entonces podría sugerir el uso de las interfaces de hecho en su lugar, pero ORM hoy son más sofisticados que los que, mediante la reflexión y proxies dinámicos e intercepción método para hacerlo la mayor parte del trabajo pesado, por lo que no necesitas crear tus propias abstracciones aquí.
Algunos tipos de objetos que se le desea exponer como interfaces son:
- repositorios, que son responsables de cargar/guardar objetos de dominio;
- Complementos/extensiones de su programa;
- Modelos de visualización/presentador, para que se puedan enchufar diferentes UI;
- Tipos de datos abstractos con muchas implementaciones (matriz, lista, diccionario, conjunto de registros y tabla de datos son todas las secuencias AKA
IEnumerable
);
- Operaciones abstractas con muchos algoritmos posibles (ordenar, buscar, comparar);
- Modelos de comunicación (mismas operaciones sobre TCP/IP, canalizaciones con nombre, RS-232);
- Cualquier cosa específica de la plataforma, si planea implementar en más de una (Mac/Windows/* nix).
que de ninguna manera es una lista completa, pero debe iluminar el principio básico aquí, y es que las cosas más adecuados para interconectar las abstracciones son las cosas que:
- dependerá de factores que pueden más allá de tu control;
- Es probable que cambie en el futuro; y
- Son funciones horizontales (se usan 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 total sobre el diseño. Por lo tanto, a menos que las clases mismas asuman dependencias indirectas (que es una situación que debe intentar evitar siempre que sea posible), no realizaría el esfuerzo extra de crear una interfaz para cada clase en el modelo de dominio.
@Aaronaught: Ok, para ORM específico, ahora supongo que estoy usando Características de FullText, usaré Lucene.NET que también usa Atributos. Y hasta donde sé, no hay forma de usar un mapeo externo de atributos como FluentNhibernate do. Entonces, ¿cuál es el mejor enfoque para mantener a mis entidades de dominio como verdaderas POCO? ¿Quizás las interfaces funcionan de esa manera? –
@Yoann. B: No sabía que Lucene.NET usaba atributos de decorador; definitivamente no los requiere. Si desea utilizarlos, tiene dos opciones: (a) hacer que su modelo de dominio sea dependiente de Lucene.NET, lo que parece una mala idea (¿qué ocurre si quiere usar SQL FTS en su lugar?) ¿Qué sucede si una versión futura de ¿Lucene.NET admite POCOs?), O (b) mueve sus objetos de búsqueda y repositorios a un espacio de nombres/ensamblaje diferente y utiliza una herramienta como AutoMapper para convertirlos en objetos de dominio. De cualquier manera, no creo que la creación de interfaces para los objetos sea de gran ayuda. – Aaronaught
@Aaronaught: ¿Dijiste que Lucene.NET no requiere atributos? es sobre otra pregunta que publiqué (http://stackoverflow.com/questions/2356593/lucene-net-and-poco-entities) pero ¿cómo se puede hacer sin usar atributos con Lucene.NET? –