Ir al contenido principal

Consultas y comandos

La mayoría de las aplicaciones en las que trabajo siguen un patrón. Son aplicaciones web que tienen consultas y comandos, ya sea acciones con los métodos HTTP GET o POST. Viene siendo el viejo y conocido patrón CQRS. No inicio directamente con el patrón en mente; pero cuando el controlador empieza a tener mucho código en una acción, ahí es donde suena como buena idea introducir un comando o un consulta.



Imagina que estás desarrollando una aplicación para capturar ordenes de trabajo, la aplicación es solo un ejemplo por lo que las reglas serán básicas. Los requerimientos pueden ser los siguientes:
  1. Capturar orden de trabajo
  2. Consultar orden de trabajo
  3. Cambiar el estatus de la orden
  4. Marcar como pagada la orden
  5. Consultar ordenes de trabajo pendientes
Puedes ver que la mayoría son consultas o comandos; pero no inicies el desarrollo de la aplicación usando el patron por todos lados, deja que sea el código el que te diga cuando se necesita introducir una nueva abstracción. Al principio agregarías un OrdersController que use algo como EntityFramework con acciones para cada uno de los requerimientos. Y veras si el código se ve fácil de seguir.

Probablemente te pedirán que al momento de capturar una orden no solo se guarde en la db, sino que también hay que enviar correos, agregar un registro en algún log, realizar ciertas validaciones, etcetera. Si metes todo ese código en el action del controller será difícil seguir el código. Ahí es donde abstraer la creación de la orden en un comando tiene sentido. Lo que puedes hacer es agregar una clase "CreateOrderCommand" que seguramente tendría un método Execute que recibe como parámetro un objeto del tipo CreateOrderModel con toda la información necesaria para crear una orden. Este método puede regresar un objeto del tipo CommandResult que es un objeto con una lista de errores y un objeto con el resultado del comando (en este caso, puede ser una nueva orden). De este modo es fácil ver y modificar todo lo que se necesita para crear una orden en un solo lugar, sin tener que ver detalles de HTTP o del framework MVC. Es sencillo ver qué es lo que necesita el comando para funcionar correctamente.

Lo mismo puede pasar para las consultas, si la consulta es compleja será buena idea encapsularla dentro de un objeto Query que tenga propiedades con los posibles parámetros para la consulta y un método Execute o Find que regrese el resultado de la consulta.

Seguir este patrón también me ha servido cuando no conozco o no tengo control sobre la base de datos del sistema. Puedo ir armando los comandos y consultas que regresan valores fijos de prueba y construir la aplicación aunque aún no tenga acceso a la DB o aun no sepa de donde obtener los datos. Una vez que sé de donde consultar o qué actualizar puedo simplemente cambiar la clase consulta y comando indicado.

Seguir este patron cumple mejor con el principio de responsabilidad única, en lugar de tener una clase gigante "Repository" que hace todas la consultas y todos los comandos, tengo una clase comando o consulta para cada característica de la aplicación.

Comentarios

  1. Divide 'n conquer, muy buen articulo.

    ResponderBorrar
  2. Arturo López Esparzaabril 06, 2018

    Me cae de perlas este Post, estaba apunto de modificar el controlador y ver el tamaño que ya tiene con lo que le agregaría me hacia pensar que se vería como un cochinero sin contar que tardaría en buscar esa parte del código si tenia que modificar algo en el futuro.
    Esta es de la clase de cosas que si bien se practican en otros aspectos, no nos hacen click hasta que nos las muestran.

    ResponderBorrar

Publicar un comentario

Entradas más populares de este blog

Bloqueos

Una de las preguntas típicas de las juntas matutinas en los equipos de desarrollo de software es ¿Hay algún bloqueo? Si lo hay, se trata de ver qué es lo que está esperando esa persona y encontrar la forma de que se desbloquee; pero ¿Qué son los bloqueos? Los bloqueos son obstáculos que te impiden realizar o avanzar en tu trabajo. Evitan que puedas seguir progresando en el proyecto.

He notado que es común en las personas con menos experiencia decir que tienen un bloqueo cuando están batallando, debido a su poca experiencia, en la forma de resolver un problema. Han intentado varias formas y se empiezan a quedar sin ideas de como puede ser resuelto el problema o como pueden cumplir con el requerimiento especificado. Al quedarse sin opciones de qué intentar dicen que tienen un bloqueo con la tarea y que a menos que alguien les diga como resolverlo, no se puede avanzar en la tarea.

En personas con más experiencia, ese tipo de bloqueos no ocurren, una persona con experiencia ha visto pro…

Firebird 2.1 UPDATE OR INSERT

Another great feature that I like in Firebird 2.1 is the UPDATE OR INSERT statement. It's a really time saver and it makes the SQL cleaner.

For example suppose I have a products table like the one I use in my last post and an inventory table to store the product stock. Before Firebird 2.1 if I want to set the stock for a product I needed to check if a record for that product_id already exists; if the product_id already exists then I write an update. If not then I write an insert statement. So I ended up with something like this:


IF EXISTS(SELECT * FROM inventory WHERE product_id = :product_id ) THEN
UPDATE
inventory
SET
stock = :stock
WHERE
product_id = :product_id;
ELSE
INSERT INTO inventory
(product_id, stock)
VALUES
(:product_id, :stock);

In this example I only update one field but when I have to update a big table I ended up with a big chunk of code and thinking: "there should be another (better) way to do this".

Fortunately now with Firebird 2.1 there…

Database Mail en MS SQL Server 2005

Configuración de Database Mail en MS SQL Server 2005

Primero se debe de habilitar, ya que por omisión el componente esta deshabilitado, Utilizando el SSMS (SQL Server Management Studio)


Si no esta habilitado aparecerá un mensaje preguntado si lo habilita, después aparece esta ventana donde se pregunta al usuario que es lo desea hacer.


Seleccionamos la primera opción para crear un perfil.


Configuramos el perfil y le agregamos por lo menos una cuenta.


Seleccionamos el perfil como public y default.


Para mandar correo se utiliza el procedimiento msdb.sp_send_dbmail por lo tanto el usuario que intente mandar correo debe de tener permiso para la base de datos msdb.

Referencias:
http://www.sqlservercentral.com/columnists/cBunch/introtodatabasemailinsql2005.asp