Tell, Don't Ask
Continuamos aprendiendo principios de diseño y desarrollo de software. Hoy toca uno de esos principios sencillos de recordar y de aplicar, pero que te dan un gran beneficio con muy poco esfuerzo. El principio "Tell, Don't Ask".
Este principio nos habla de la base fundamental del diseño orientado a objetos, la encapsulación. Imaginemos que tenemos una clase que representa una reserva de hotel como la siguiente:
Esta clase no tiene ninguna responsabilidad más allá de almacenar los datos de inicio y fin de la reserva. Imaginemos que queremos saber el número de noches que el cliente va a pasar en el hotel, y dependiendo de ese número de noches, sabremos si la estancia es larga o es corta. Según las normas del hotel, una estancia es larga cuando supera las 7 noches (por simplicidad y para eliminar el ruido escribiremos directamente el código cliente sin establecer ninguna estructura compleja). El código para determinar esto podría ser el siguiente:
El cliente (o consumidor) de la clase Booking, está pidiendo al objeto que le proporcione sus datos internos para realizar cálculos y deducciones sobre ellos. En el caso anterior, la clase Booking genera objetos de dominio sin comportamiento propio, provocando que la lógica sobre sus datos viva fuera de la clase, lo que va contra el principio de encapsulación.
El ejemplo anterior tiene dos problemas fundamentales:
- Los consumidores de la clase Booking deben conocer detalles internos de implementación que no deberían conocer para poder utilizarla.
- Al tener que preguntar al objeto "booking" por sus datos internos, creamos un acoplamiento fuerte entre los consumidores y la estructura interna de la clase Booking.
Podemos mejorar el código anterior si la clase Booking asume comportamientos de dominio sobre sus propios datos.
En este ejemplo, la clase Booking contiene su propia lógica de negocio lo que conlleva que, el código cliente ya no necesite conocer su estructura interna. Con esta nueva implementación, el cliente solo necesita utilizar la interfaz pública del objeto booking, para solicitar la información que busca. Al encapsular el comportamiento de dominio dentro de la clase, reducimos el acoplamiento de los clientes a su estructura interna y como consecuencia, obtenemos un código más fácil de mantener y evolucionar.
Como ya he dicho antes, este principio es uno de mis favoritos por lo sencillo que es de recordar y por lo rápido que mejora tu código cuando empiezas a aplicarlo. Al final, la idea es bastante simple: si un objeto tiene los datos y la lógica pertenece a su dominio, no le pidas sus datos para decidir fuera; dale esa responsabilidad al propio objeto.
No siempre será evidente dónde debe vivir cada comportamiento, pero cuando encuentres código que pregunta demasiado por los datos internos de un objeto, probablemente tengas una buena oportunidad para aplicar Tell, Don't Ask.