Me pregunto lo siguiente: supongamos que estamos construyendo un sistema en el que debe haber alguna funcionalidad de filtrado para buscar alguna entidad. Por ejemplo, uno podría querer aplicar el filtrado a una tabla que enumere las entidades para encontrar algo, o usarlo para generar un informe en un conjunto filtrado, lo que sea.
El punto es: necesitamos tener una lógica de filtrado en alguna parte. Una mala forma de hacerlo sería replicar la lógica de filtrado donde sea necesario. Lo hice una vez y es una idea terrible.
Por otro lado, creo que debería haber un método como Filter(FilteringOptions filteringOptions)
diseñado para realizar la operación de filtrado y devolver la lista filtrada de entidades.
Ahora, en mi humilde opinión, la lógica de filtrado es una buena lógica de negocios. Los expertos en negocios son los que saben cómo se realiza el filtrado, qué elementos se filtran y cómo. Por eso, creo que la lógica de filtrado debe ubicarse en la capa de dominio.
He encontrado dos opciones para hacer esto: incrustar el método de filtrado en el repositorio correspondiente para esa entidad en particular, o bien, crear un servicio de dominio como EntityNameSearchService
que consumiría el repositorio para realizar el filtrado.
Todavía estoy confundido cuál sería la mejor manera. Entonces, si estoy tratando de usar DDD correctamente, ¿dónde debería estar esta lógica de filtrado? ¿En el repositorio o en un servicio separado?
fuente
Get*
método genérico e introducir filtros diferentes o definidos por el usuario en la capa de servicio. La decisión depende principalmente de usted.Respuestas:
Debe observar que en este punto sus casos de uso para el filtrado se centran alrededor de las lecturas , en lugar de escribir. Este es el patrón normal: una escritura generalmente se dirige a una raíz agregada específica en su dominio.
Si está realizando una lectura, en realidad no le importan los agregados: no le importa la aplicación de la empresa invariante porque en realidad no está tratando de cambiar nada. Solo te importa el estado.
Lo que puede significar que tiene sentido omitir por completo el modelo de dominio.
Solo algo para pensar.
Si y no. Estás recurriendo al lenguaje ubicuo para describir el filtro. Entonces definitivamente estás usando el vocabulario de dominio.
Pero no tiene ningún "comportamiento", en la medida en que no está modificando el libro de registro, por lo que no tiene que preocuparse por los invariantes.
Estás muy cerca de la idea de "Especificación" . Básicamente es un predicado que un repositorio puede usar para identificar qué artefactos coinciden con algunos criterios arbitrarios.
Hay algunas trampas a tener en cuenta. Greg Young los tocó hace algún tiempo, pero resumiré aquí.
Primero, la abstracción de ejecutar un predicado contra una colección es O (N). Probablemente querrá algo más agradable, especialmente si su tienda de persistencia es inteligente sobre la indexación. Su componente de persistencia probablemente querrá poder transformarlo en una restricción específica de implementación (ejemplo: tomar una especificación y convertirla en una cláusula where en una declaración preparada).
Segundo, una interfaz es un medio de documentar el contrato servido por el componente de persistencia. "Explique explícitamente lo implícito": si describe qué es lo que realmente necesita, entonces la interfaz le dice algo acerca de qué características son importantes para su almacén de datos, lo que le brinda un solo lugar para buscar al intentar evaluar si una alternativa La tienda es adecuada.
(Por supuesto, la implementación de esa interfaz podría ser solo un adaptador que crea la especificación a partir de los argumentos del método, y lo reenvía. Eso está bien, ha capturado el requisito real).
fuente