Recientemente estuve refactorizando un método que era tanto un comando como un método de consulta.
Después de separarlo en un método de un comando y un método de consulta, descubrí que ahora hay varios lugares en el código donde estoy llamando al comando y luego obtengo el valor de la consulta, lo que parece una violación del principio DRY.
Pero si tuviera que incluir ese código común en un método, ese método sería tanto comando como consulta. ¿Es esto aceptable?
language-agnostic
refactoring
dry
cqrs
Kris Welsh
fuente
fuente
Respuestas:
Siempre hay compensaciones a considerar entre principios de diseño en conflicto. La forma de resolverlo es mirar las razones subyacentes detrás de los principios. En este caso, ser incapaz de ejecutar una consulta sin ejecutar el comando es problemático, pero ser incapaz de ejecutar un comando sin ejecutar la consulta es generalmente inofensivo. Mientras haya una manera de ejecutar la consulta de forma independiente, no veo ninguna razón para no agregar el resultado de la consulta al comando, especialmente si se hace algo como esto:
fuente
No he oído hablar de Command-Query-Separation (CQS) antes, pero parece que se relacionaría con el Principio de responsabilidad única (SRP), que establece que una función / clase idealmente debería ser responsable de hacer una cosa y solo una cosa .
Si su código de comando es de 20 líneas de código y el código de consulta son otras 30 líneas y están todas en un cuerpo de función, claramente está violando SRP y asumiría también CQS y esas dos piezas de lógica deberían estar separadas entre sí .
Sin embargo, siguiendo su ejemplo hipotético, lo más probable es que cree un método contenedor que combine su comando y consulta para que DRY no se viole en numerosos lugares del código. Tampoco consideraría que esto es una violación de SRP (y tal vez CQS), porque el contenedor todavía tiene una sola responsabilidad: combinar el comando con una consulta y crear una abstracción de nivel superior que sea más fácil de consumir.
Creo que el método wrapper es una solución perfectamente aceptable y, para ilustrarlo, llevemos su ejemplo un paso más allá. ¿Qué pasaría si tuviera que ejecutar 2 consultas en lugar de 1 y luego realizar una acción de comando basada en eso? Entonces, sus 2 líneas de código serían 6 u 8. ¿Qué pasaría si hubiera alguna validación / verificación de datos entre una y otra, por lo que ahora tiene 15 líneas de código? ¿Se lo pensaría dos veces antes de crear un contenedor que haga todo eso, en lugar de rociar esas 15 líneas en varios archivos?
fuente
DRY es más importante, ya que resuelve una necesidad mucho más fundamental: evitar esfuerzos redundantes y malgastados. Esto es algo fundamental: uno no necesita ser un programador para comprenderlo.
CQS es una respuesta a la dificultad, en lenguajes sin soporte para los efectos de seguimiento, de comprender el código que se ejecuta tanto por sus resultados como por sus efectos. Sin embargo:
La necesidad de ejecutar código para sus resultados no se puede evitar, porque esta es la base para componer programas grandes a partir de unidades pequeñas.
Tampoco se puede evitar la necesidad de ejecutar código para sus efectos, porque, aparte de las matemáticas y la informática teórica, el valor de ejecutar un programa radica en lo que puede hacer por nosotros.
La necesidad de causar efectos y producir resultados en el mismo código no se puede evitar, porque, en la práctica, necesitamos efectos y composición, no solo uno u otro.
¡La solución real al problema de que los efectos de seguimiento sean demasiado difíciles para los humanos sin ayuda es, por supuesto, que las computadoras nos ayuden a los humanos ! Algo similar puede decirse sobre el seguimiento de relaciones complejas entre valores de tiempo de ejecución (como la validez de los índices de matriz), para los cuales las excepciones y los contratos ejecutados en tiempo de ejecución constituyen soluciones (no).
En conclusión, las "soluciones" como CQS simplemente se interponen en el diseño de programas de acuerdo con principios sólidos basados en la realidad. Ve por SECO.
fuente