¿Una lógica de filtrado debe estar en un repositorio o en un servicio?


9

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?


2
¿Dónde tiene más sentido la lógica de filtrado, desde una perspectiva de mantenibilidad y usabilidad?
Robert Harvey

A primera vista parecía que en el repositorio, ya que es el objeto responsable, entre otras cosas, de recuperar las entidades. Por otro lado, la lógica de filtrado no necesita aplicarse solo en la recuperación, sino que puede aplicarse a cualquier lista de entidades. De hecho, pensando un poco más al respecto, la capa de dominio contiene solo las interfaces de los repositorios. La implementación real se basa en un proyecto de datos y debe combinarse con el mecanismo de persistencia real, mientras que los servicios se implementan en el dominio. Desde este punto de vista, la creación de un servicio de filtrado parece tener más sentido.
user1620696

1
Filtrar en la capa de servicio costará más tiempo que obtener datos ya filtrados del repositorio a través de un método específico, pero puede reutilizar el 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.
Andy

Respuestas:


4

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.

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.

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.

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.

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.

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).

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.