Cómo escribir un código profesional mediante el principio de separación de consultas de comandos
Un hecho fundamental de la mecánica cuántica desafía nuestra percepción básica del mundo: observar algo altera su comportamiento.
¡Esto es Inaudito! En la vida real, usted no esperaría que el acto de ver televisión altere el contenido original grabado en el estudio.
Por la misma razón, usted no esperaría que un explorador de archivos realice cambios en los archivos que muestra cada vez que se abre. Este comportamiento sería inútil: usted no podría permitirse abrir el explorador de archivos sin preocuparse por cambios no deseados.
En ingeniería de software, se aplica el mismo principio de dividir la observación de datos de la modificación. Tome una base de datos, por ejemplo. Existe una clara separación entre los métodos de consulta, inserción y eliminación. Usted no escribiría código de cambio de datos en la implementación del método query().
Esta segregación facilita el uso de la API de la base de datos sin tener que razonar sobre lo que podría suceder cuando se utiliza cada una de estas funcionalidades.
Si esta segregación tiene sentido para la base de datos, ¿por qué no aplicarla en cada funcionalidad que escribimos en nuestro código base? Después de todo, cada fragmento de código finalmente se reduce a consultar datos o ejecutar comandos que afectan a los datos.
Ejemplo
Puede ser tentador empaquetar algo de código en una función como esta:
Usted puede tener una idea de lo que hace, pero tomemos un momento y pensemos en cómo podemos describir su comportamiento en una sola oración.
De hecho, no hay forma de describir el comportamiento en una oración porque usted debe dividir el comportamiento de la función en dos escenarios diferentes:
1. Función ejecutada si la alarma ya está programada.
2. Función ejecutada cuando la alarma no está programada.
Esto significa que un lector de código que utiliza esta función tiene que invertir un esfuerzo adicional para comprender lo que hace. Probablemente también tendrían que leer la implementación de la función, solo para estar seguros.
Cuando declaramos una función, esperamos reutilizarla más de una vez. Funciones como esta no tienen posibilidad de utilizarse en ningún otro lugar que no sea en procedimientos de lógica empresarial de muy alto nivel.
Aplicar la Separación de Consultas de Comandos
Ahora hay dos funcionalidades separadas. El procedimiento de alto nivel ahora tendrá que contener tres líneas en lugar de una, pero será mucho más legible.
Otro efecto positivo de esta separación es que hay muchos buenos ejemplos de cómo se podría reutilizar cada una de estas dos funciones (o diferentes API). Por ejemplo:
• Otra lógica empresarial podría hacer uso del conocimiento de si la alarma está programada o no.
• Podrían mostrar el estado de programación actual en la interfaz de usuario.
Este enfoque arquitectónico va de la mano con el paradigma de programación funcional, que lo alienta a aislar y evitar el código dependiente del estado y escribir funciones descriptivas con entradas y salidas claras.
La separación de la funcionalidad de "comandos", que muta algo en el sistema, de las funcionalidades responsables de consultar datos, hace que el código funcional sea inevitable.
Puede ser fácil abordar la ingeniería de software como un oficio o un arte.
Sin embargo, creo que nuestro objetivo debería ser establecer reglas y principios para garantizar una forma determinista de producir código robusto, reutilizable y escalable.
Desde mi experiencia, seguir reglas como CQS (Separación de consultas de comandos) mejora estos factores dramáticamente.
Otras lecturas:
https://en.wikipedia.org/wiki/Command%E2%80%93query_separation
https://martinfowler.com/bliki/CommandQuerySeparation.html
Traducido por: Junior Gamez