quickly por patron method guiado example driven dominio domain diseño design-patterns domain-driven-design

design patterns - patron - Diseño impulsado por el dominio y el papel de la clase de fábrica



patron factory android (6)

No estoy seguro de cuáles son los roles y la responsabilidad de la clase de fábrica. Sé lo suficiente que la clase de fábrica debería ser responsable de la creación de objetos de dominio (raíz de agregado) junto con sus entidades asociadas y objetos de valor.

Pero lo que no está claro para mí es dónde se encuentra la "capa" de fábrica con una arquitectura DDD. ¿Debería la fábrica llamar directamente al repositorio para obtener sus datos o la biblioteca de servicios?

¿Dónde encaja la fábrica en el siguiente marco?
UI> Aplicación> Dominio> Servicio> Datos

Además, como la fábrica es el único lugar permitido para la creación de objetos, ¿no obtendría referencias circulares si quisiera crear sus objetos en las capas de datos y servicios?

Si el rol de la clase de fábrica es para la creación de objetos, ¿qué beneficios tiene la capa de servicio?

He hecho muchas preguntas y aprecio cualquier respuesta. Lo que me falta es una aplicación de muestra que demuestre cómo todas las capas en un proyecto de diseño impulsado por dominio se unen ... ¿Hay algo por ahí?


¿Debería la fábrica llamar directamente al repositorio para obtener sus datos o la biblioteca de servicios?

Yo diría que tampoco, se debería pasar la información que necesita directamente si es posible.

¿Dónde encaja la fábrica en el siguiente marco: UI> Aplicación> Dominio> Servicio> Datos

No estoy seguro de dónde viene esta estratificación, las capas no están fijadas en DDD pero diría que sería mejor enfocarse en este estilo

UI> Aplicación> Dominio

Dentro del Dominio, tienes varios tipos de objetos y yo establecí reglas sobre las relaciones entre ellos:

  • Las fábricas deben pasar todo lo que necesitan para hacer su trabajo, por lo tanto, no los llamaría a otros servicios o repositorios en la mayoría de los casos.
  • En la mayoría de los casos, las entidades no deben contactar a los repositorios, sino que los servicios (u otras capas superiores) deberían ser responsables de este trabajo.
  • Las entidades no deben llamar a servicios, los servicios se encuentran sobre las entidades / objetos de valor / especificaciones y los coordinan según corresponda.
  • Los servicios dentro del dominio están ahí para coordinarse, no contienen un comportamiento significativo de dominio / negocio.

Si el rol de la clase de fábrica es para la creación de objetos, ¿qué beneficios tiene la capa de servicio?

Eric lo explica bastante bien en el libro, así que me referiría a él, pero en última instancia es genial si tienes un comportamiento o comportamiento global agregado que no encaja bien en un agregado (por ejemplo, el ejemplo de cuenta en el libro).


Pero lo que no está claro para mí es dónde se encuentra la "capa" de fábrica con una arquitectura DDD. ¿Debería la fábrica llamar directamente al repositorio para obtener sus datos o la biblioteca de servicios?

La fábrica debe ser la ventanilla única para construir objetos de dominio. Cualquier otra parte del código que necesite hacer esto debe usar la fábrica.

Normalmente, hay al menos tres fuentes de datos que se utilizan como entrada en una fábrica para la construcción de objetos de dominio: entrada de la interfaz de usuario, resultados de consultas de persistencia y solicitudes significativas de dominio. Entonces, para responder a su pregunta específica, el repositorio usaría la fábrica.

Aquí hay un ejemplo. Estoy usando el patrón de Holub''s Builder aquí. Editar : ignore el uso de este patrón. Empecé a darme cuenta de que no se combina muy bien con las fábricas DDD .

// domain layer class Order { private Integer ID; private Customer owner; private List<Product> ordered; // can''t be null, needs complicated rules to initialize private Product featured; // can''t be null, needs complicated rules to initialize, not part of Order aggregate private Itinerary schedule; void importFrom(Importer importer) { ... } void exportTo(Exporter exporter) { ... } ... insert business logic methods here ... interface Importer { Integer importID(); Customer importOwner(); Product importOrdered(); } interface Exporter { void exportID(Integer id); void exportOwner(Customer owner); void exportOrdered(Product ordered); } } // domain layer interface OrderEntryScreenExport { ... } // UI class UIScreen { public UIScreen(OrderEntryDTO dto) { ... } } // App Layer class OrderEntryDTO implements OrderEntryScreenExport { ... }

Aquí está lo que podría parecer OrderFactory:

interface OrderFactory { Order createWith(Customer owner, Product ordered); Order createFrom(OrderEntryScreenExport to); Order createFrom(List<String> resultSets); }

La lógica para el Producto presentado y la generación del Itinerario van en OrderFactory.

Ahora aquí está cómo se podría usar la fábrica en cada caso.

En OrderRepository:

public List<Order> findAllMatching(Criteria someCriteria) { ResultSet rcds = this.db.execFindOrdersQueryWith(someCriteria.toString()); List<List<String>> results = convertToStringList(rcds); List<Order> returnList = new ArrayList<Order>(); for(List<String> row : results) returnList.add(this.orderFactory.createFrom(row)); return returnList; }

En tu capa de aplicación:

public void submitOrder(OrderEntryDTO dto) { Order toBeSubmitted = this.orderFactory.createFrom(dto); this.orderRepo.add(toBeSubmitted); // do other stuff, raise events, etc }

Dentro de su capa de dominio, una prueba de unidad quizás:

Customer carl = customerRepo.findByName("Carl"); List<Product> weapons = productRepo.findAllByName("Ruger P-95 9mm"); Order weaponsForCarl = orderFactory.createWith(carl, weapons); weaponsForCarl.place(); assertTrue(weaponsForCarl.isPlaced()); assertTrue(weaponsForCarl.hasSpecialShippingNeeds());

¿Dónde encaja la fábrica en el siguiente marco: UI> Aplicación> Dominio> Servicio> Datos

Dominio.

Además, como la fábrica es el único lugar permitido para la creación de objetos, ¿no obtendría referencias circulares si quisiera crear sus objetos en las capas de datos y servicios?

En mi ejemplo, todas las dependencias fluyen de arriba a abajo. Usé el Principio de Inversión de Dependencia (enlace PDF) para evitar el problema del que hablas.

Si el rol de la clase de fábrica es para la creación de objetos, ¿qué beneficios tiene la capa de servicio?

Cuando tiene una lógica que no cabe en ningún objeto de dominio individual O tiene un algoritmo que implica orquestar múltiples objetos de dominio, use un servicio. El servicio encapsularía cualquier lógica que no encajara en ninguna otra cosa y delegaría objetos de dominio donde encaja.

En el ejemplo que garabateé aquí, me imagino que crear un Itinerario para la Orden implicaría múltiples objetos de dominio. The OrderFactory podría delegar en dicho servicio.

Por cierto, la jerarquía que describes probablemente debería ser UI> Aplicación> Servicios de dominio> Dominio> Infraestructura (Datos)

He hecho muchas preguntas y aprecio cualquier respuesta. Lo que me falta es una aplicación de muestra que demuestre cómo todas las capas en un proyecto de diseño impulsado por dominio se unen ... ¿Hay algo por ahí?

La aplicación de patrones y diseño impulsado por el dominio de Jimmy Nilsson es un gran complemento al diseño impulsado por el dominio de Eric Evans. Tiene muchos ejemplos de código, aunque no sé si se pone énfasis en las capas. La creación de capas puede ser complicado y es casi un tema separado de DDD.

En el libro de Evans, hay un pequeño ejemplo de estratificación que quizás desee verificar. Layering es un patrón empresarial, y Martin Fowler escribió Patterns of Enterprise Application Architecture , que también puede serle útil.


La diferencia entre un repositorio y una fábrica es que un repositorio representa un almacenamiento persistente abstracto, mientras que una fábrica es responsable de construir un objeto.

Entonces, por ejemplo, digamos que estoy registrando un usuario. Voy a obtener mi objeto de usuario de una fábrica

IUser user = userFactory.Create(name, email);

Luego, páselo al repositorio, que se encargará de resolverlo.

userRepository.Insert(user);

Las fábricas en DDD pueden considerarse como una forma de ocultar algo nuevo, una abstracción de los detalles de la creación de instancias. Le permite programar de manera muy efectiva a una interfaz en lugar de un concreto.

Además, esto permite que los repositorios se centren en su tipo de entidad y, por lo tanto, el uso de genéricos se vuelve muy poderoso.


Los chicos de DDD y yo podríamos discutir sobre esto, pero básicamente la idea de esa clase de "fábrica" ​​es emitir objetos de dominio. los objetos de dominio luego acceden a los datos y se convierten en parte de un "modelo" del dominio con el que está trabajando.

La aplicación contiene la interfaz de usuario, etc., no es una jerarquía de herencia.

Tenga cuidado con ese "tipo de operador"; Mucha gente piensa que debido a que PUEDEN usar herencia, DEBEN usar herencia. La agregación ("contiene" o "tiene un" en lugar de "es un") es a menudo una mejor apuesta.

Actualizar

No necesariamente. Piense en lo que le dice el dominio: es algo así como "Necesito un producto y sé el número de producto del producto. Cuando la fábrica del producto está lista, quiero que me den el objeto completamente poblado que representa mi producto". Cuando crea su objeto Producto, ¿qué necesita hacer para ser un objeto de Producto válido que representa un producto específico?


Probablemente bajo mi propio riesgo, tiendo a no enfatizar los patrones de diseño a menos que realmente esté atascado. Acabo de construir el sistema como lo pienso y refactorizarlo hasta que tenga algún sentido al día siguiente.

Uso una fábrica cuando:

  • Alguna capa necesita crear un objeto con cierta regularidad. y
  • Solo esa capa sabe cuándo crearla, o con qué personalizaciones y
  • Solo otra capa sabe exactamente qué crear.

Veo que la capa de Servicios de aplicaciones tiene la responsabilidad de crear nuevas entidades, llamando a una fábrica para que lo haga. Por lo tanto, la interfaz de factoría de fábrica se define en el módulo Servicio de aplicación, y la implementación real es un servicio de infraestructura, del mismo modo que la persistencia. Para tener una idea clara y clara sobre el servicio de aplicación general frente al servicio de dominio frente a los servicios de infraestructura, obtuve mucha claridad al ver esto: Bob Martin Ruby Midwest 2011