domain-driven-design - significado - domain driven design c#
¿Cómo organizar un proyecto de diseño impulsado por un dominio? (5)
Trato de mantener las cosas muy simples cada vez que puedo, por lo que generalmente algo como esto me funciona:
Myapp.Domain: todas las clases específicas de dominio comparten este espacio de nombres
Myapp.Data: capa delgada que abstrae la base de datos del dominio.
Aplicación Myapp: todo el "código de soporte", registro, código de utilidad compartida, consumidores de servicios, etc.
Myapp.Web - La interfaz de usuario web
Entonces las clases serán por ejemplo:
- Myapp.Domain.Sales.Order
- Myapp.Domain.Sales.Customer
- Myapp.Domain.Pricelist
- Myapp.Data.OrderManager
- Myapp.Data.CustomerManager
- Myapp.Application.Utils
- Myapp.Application.CacheTools
Etc.
La idea que trato de tener en cuenta a medida que avanzo es que el espacio de nombres de "dominio" es lo que captura la lógica real de la aplicación. Entonces, qué hay allí es con lo que puedes hablar con los "expertos de dominio" (los tipos que usarán la aplicación). Si estoy codificando algo por algo que han mencionado, debería estar en el espacio de nombres del dominio, y cada vez que codigo algo que no han mencionado (como el registro, los errores de rastreo, etc.) NO debería estar en el espacio de nombres del dominio.
Debido a esto, también soy cauteloso al hacer jerarquías de objetos demasiado complicadas. Idealmente, un esquema algo simplificado del modelo de dominio debería ser intuitivamente comprensible para los no codificadores.
Con este fin, normalmente no comienzo pensando en los patrones con mucho detalle. Intento modelar el dominio de la manera más sencilla posible, siguiendo solo las pautas de diseño orientadas a objetos estándar. ¿Qué necesita ser un objeto? ¿Como están relacionados?
En mi opinión, DDD trata sobre el manejo de software complejo, pero si su software no es en sí mismo muy complejo para empezar, podría terminar fácilmente en una situación en la que la forma de hacer DDD agrega complejidad en lugar de eliminarla.
Una vez que tenga un cierto nivel de complejidad en su modelo, comenzará a ver cómo se deben organizar ciertas cosas, y luego sabrá qué patrones usar, qué clases son agregados, etc.
En mi ejemplo, Myapp.Domain.Sales.Order sería una raíz agregada en el sentido de que, cuando se instancia, probablemente contenga otros objetos, como un objeto de cliente y una colección de líneas de orden, y usted solo accedería a las líneas de orden. para ese orden en particular a través del objeto de orden.
Sin embargo, para mantener las cosas simples, no tendría un objeto "maestro" que solo contenga todo lo demás y no tenga otro propósito, por lo que la clase de orden tendrá valores y propiedades que sean útiles en la aplicación.
Así que haré referencia a cosas como:
Myapp.Domain.Sales.Order.TotalCost
Myapp.Domain.Sales.Order.OrderDate
Myapp.Domain.Sales.Order.Customer.PreferredInvoiceMethod
Myapp.Domain.Sales.Order.Customer.Address.Zip
etc.
Empecé a aprender sobre DDD y quería saber cómo otros han organizado sus proyectos.
Empecé organizando alrededor de mi AggregateRoots:
MyApp.Domain (espacio de nombres para el modelo de dominio)
MyApp.Domain.Product
- Producto
- IProductService
- IProductRepository
- etc
MyApp.Domain.Comment
- Comentario
- ICommentService
- ICommentRepository
- etc
MyApp.Infraestructura
- ...
MyApp.Repositories
- ProductRepository: IProductRepository
- etc
El problema con el que me topé con esto es que tengo que hacer referencia a mi producto de dominio como MyApp.Domain.Product.Product o Product.Product. También tengo un conflicto con mi modelo de datos linq para el producto .... Tengo que usar líneas feas de código para distinguir entre los dos, como MyApp.Domain.Product.Product y MyApp.Respoitories.Product.
Estoy realmente interesado en ver cómo otros han organizado sus soluciones para DDD ...
Estoy usando Visual Studio como mi IDE.
Muchas gracias.
Me gusta tener el dominio en el espacio de nombres raíz de la aplicación, en su propio ensamblado:
Acme.Core.dll
[nombre de raíz: Acme
]
Esto representa claramente el hecho de que el dominio está dentro del alcance de todas las demás partes de la aplicación. (Para más información, vea The Onion Architecture por Jeffrey Palermo).
Luego, tengo un conjunto de datos (generalmente con NHibernate ) que mapea los objetos de dominio en la base de datos. Esta capa implementa las interfaces de repositorio y servicio:
Acme.Data.dll
[nombre de raíz: Acme.Data
]
Luego, tengo un conjunto de presentación que declara los elementos de mi IU-patrón de elección:
Acme.Presentation.dll
[nombre de raíz: Acme.Presentation
]
Finalmente, está el proyecto de UI (asumiendo una aplicación web aquí). Aquí es donde tiene lugar la composición de los elementos en las capas precedentes:
Acme.Web
[nombre de raíz: Acme.Web
]
Su dominio probablemente tenga un nombre, por lo que debe usar este nombre como espacio de nombres.
Usualmente pongo la implementación del repositorio y los detalles de acceso a los datos en un espacio de nombres llamado Persistance en el espacio de nombres de dominio.
La aplicación usa su propio nombre como espacio de nombres.
Aunque también es un desarrollador de .Net, la referencia de implementación de Java de la aplicación de carga de DDD por Eric Evans y Citerus es un buen recurso.
En el código doc''d, puede ver la organización DDD en contextos acotados y agregados en acción, directamente en los paquetes Java.
Además, podría considerar la arquitectura aguda de Billy McCafferty. Es una implementación ASP.Net MVC, NHibernate / Fluido NHibernate que está construida con DDD en mente.
Es cierto que aún necesitará aplicar una solución de carpeta / espacio de nombres para proporcionar los contextos. Pero, combina el enfoque de Evans con #Arch y deberías estar en camino.
Háganos saber a qué se dirige. Estoy en el mismo camino, ¡y no muy lejos de ti!
Feliz codificación,
Kurt Johnson
Revisaría codecampserver ya que la configuración allí es bastante común.
Tienen un proyecto central en el que incluyen tanto la aplicación como las capas de dominio. Es decir, el interior de la cebolla ( http://jeffreypalermo.com/blog/the-onion-architecture-part-1/ ).
De hecho, me gusta dividir el núcleo en proyectos separados para controlar la dirección de la dependencia. Entonces típicamente tengo:
MyNamespace.SomethingWeb <- múltiples UI
MyNamespace.ExtranetWeb <- múltiples UI
Capa de aplicación MyNamespace.Application <- Evans ''con clases como CustomerService
MyNamespace.Domain
- MyNamespace.Domain.Model <- entidades
- MyNamespace.Domain.Services <- doman services
- MyNamespace.Domain.Repositories
MyNamespace.Infraestructura <- implementación de repo, etc.
MyNamespace.Common <- Un proyecto que todos los otros proyectos tienen una dependencia a la que tiene cosas como un Logger, clases de Util, etc.