DRY: Don’t Repeat Yourself (¡No Te Repitas!)

Descripción general

Principios del diseño orientado a objetos
En diseño orientado a objetos, El principio No te repitas (en inglés Don't Repeat Yourself o DRY, también conocido como Una vez y sólo una) establece que, en un entorno informático, la información no debe repetirse. Es decir, el conocimiento almacenado en un programa informático debe mantenerse en un, y sólo en un, lugar

[TOC] Tabla de Contenidos


↑↑↑

1 DRY: Don't Repeat Yourself (¡No Te Repitas!)

En diseño orientado a objetos, El principio No te repitas (en inglés Don't Repeat Yourself o DRY, también conocido como Una vez y sólo una) es una filosofía de definición de procesos que promueve la reducción de la duplicación especialmente en programación. Según este principio toda pieza de información nunca debería ser duplicada debido a que la duplicación incrementa la dificultad en los cambios y evolución posterior, puede perjudicar la claridad y crear un espacio para posibles inconsistencias. Por "pieza de información" podemos entender, en un sentido amplio, desde datos almacenados en una base de datos pasando por el código fuente de un programa de software hasta llegar a información textual o documentación.

Cuando el principio DRY se aplica de forma eficiente los cambios en cualquier parte del proceso requieren cambios en un único lugar. Por el contrario, si algunas partes del proceso están repetidas por varios sitios, los cambios pueden provocar fallos con mayor facilidad si todos los sitios en los que aparece no se encuentran sincronizados. (Fuente wikipedia)

Cada vez que repites un trozo de código (reglas, procesos, rutinas) debes acordarte de dónde las pones. Si posteriormente cambian las especificaciones, o encuentras una mejor forma de hacer las cosas, o te diste cuenta que hiciste algo que no debías, tienes que cambiar el código en todos los lugares donde existe. Si no lo haces, vas a tener un sistema que se comporta de una forma en unas ocasiones, y de otra forma en otras, porque utiliza estas representaciones inconsistentes, tendrás un sistema inconsistente.

Obsesiónate con este principio, cada vez que uses el editor de texto, y veas que estás repitiendo algo, haciendo mucho "copy & paste" de una serie de ifs para ponerlos en dos o tres métodos diferentes, o si varias clases son muy similares, tal vez es momento de detenerte y hacer una refactorización para colocar todo eso en un sólo lugar y reutilizar toda esa lógica, debes utilizar la herencia, clases abstractas o cualquier recurso que te permita concentrar todo eso en un sólo sitio.


↑↑↑

1.1 ¿Cómo surge la duplicación?

Con respecto al código, no se trata de que los pedazos de código NUNCA se deban repetir, a veces es necesario y menos complejo dejar que algunas líneas se repitan en diferentes clases; donde en realidad lo debes aplicar es cuando tratas de hacer representaciones funcionales de tu aplicación: Ejemplo, si tienes una rutina que va a recuperar los datos de cliente y hacer cierta transformación a esos datos y lo harás a menudo en la aplicación, vale la pena hacer una función llamada (por ejemplo) "RecuperaClienteInfo".

En muchas ocasiones, encontramos que una función existente hace "casi" lo mismo que queremos, pero necesitamos que haga algo extra o que no lo haga. Si te encuentras en este caso, en lugar de duplicar la función, mejor añádele un parámetro, y utiliza la información de ese parámetro para que la función haga el trabajo que necesitas. Una vez hecha esta operación, el problema que se presenta es rastrear el código existente y modificar por todos lados para añadir ese parámetro; puedes entonces tener varias alternativas:


↑↑↑

1.2 Un ejemplo.

Supongamos que estamos haciendo una parte de un sistema en el cual se almacenará un catálogo de productos, digamos de frutas. Normalmente lo primero que haremos es crear la base de datos. En la base de datos se tendrían (por ejemplo) estos campos: id, código, nombre, precio. En la misma base de datos agregamos ciertas restricciones al producto: el código es único y es una cadena de 10 caracteres, el nombre no puede ir vacío, el precio no puede ser cero (observemos que incluso los tipos de esos datos radican en la creación de la tabla en la base de datos).

Una vez creada la base de datos, nos dirigimos a nuestro IDE para crear el código que trabajará con esos datos. Los enfoques varían mucho, y las maneras de trabajar con esos datos también. Pero en este caso vamos a trabajar con una capa de persistencia basada en un ORM (Object-Ralational Mapping). En algún lado de la configuración del ORM estableceremos que la tabla fruta se mapeará al objeto Fruta. Que el objeto Fruta tendrá un id, un nombre, un código y un precio.

Con nuestro mapeo funcionando, nos dirigimos a crear nuestro objeto Fruta. Nuestro objeto tendrá un BigInt para el id, tendrá un String para el código, otro para el nombre y un BigDecimal para el precio. Ahora crearemos los métodos de accesos con su set y su get. (Propiedades en Visual C#). Si la capa de persistencia nos echa una mano no tendremos que verificar que el código sea único, pero si no, tendremos que codificarlo nosotros.

Ahora, si somos queremos que nuestro código sea escalable y pueda mantenerse a largo plazo, utilizaremos alguna implementación del patrón MVC (Model-View-Controller, o Modelo-Vista-Controlador). En cada uno pondremos los respectivos campos de la fruta: el id, el código, el nombre y el precio. Haremos un listado de las frutas que hay almacenadas, y una forma para agregar y/o editar entradas. En la vista le diremos al controlador qué desplegar, y haremos una tabla en el View. El model ya lo implementamos, que es nuestro objeto Fruta. Para la forma haremos lo mismo, pondremos los campos de fruta y lo guardaremos. Para proteger nuestro modelo haremos algunas validaciones del lado del servidor, pero para darle una experiencia interactiva al usuario, también haremos validaciones en el lado del cliente. Usaremos, claro está, uno de esos bonitos frameworks que ahora nos hacen la vida más fácil con javascript. La validación del código único requerirá una llamada de Ajax, y las demás serán simples validaciones con Javascript.

Ahora estamos a punto con el manejo de frutas en el sistema. Tenemos un diseño robusto, altamente escalable, muy legible. Pasamos nuestro trabajo a control de calidad. Control de calidad nos informa que el máximo de caracteres de código es 10 y en el javascript del cliente nosotros pusimos 12. Bueno, un teclazo de más a cualquiera le pasa, ¿no?. Pasado un tiempo nos dicen que en el mapeo del ORM no pusimos correctamente el precio, y permitimos que sea vacío. Cosas, la prisa hizo que se nos pasara por alto. Pero pasado todo eso, todo bien.

Pasados unos días, nos mandan un requerimiento del cliente que pide que el código en vez de ser de 10 caracteres va a ser de 15 (cambiaron un par de cosas del negocio), y que hará falta otro código: el código de bodega que será de 20 caracteres y también hará falta el peso unitario, que será un decimal opcional.

En nuestra mente comienza a correr el tedioso proceso que tenemos que realizar: hacer los cambios en la base de datos, hacer los cambios en el mapeo, hacer los cambios en el objeto fruta, hacer los cambios en el controller y en el view para la lista, hacer los cambios en el controller y en el view (que incluye dos validaciones de javascript). Que tedio no????? Además….qué fácil será confundirnos.

A todo esto la documentación estaba ya lista, y habrá que cambiarla, pero por falta de tiempo creemos que se quedará tal y como está.

He aquí lo que nos pasa cuando violamos el principio DRY. El principio DRY establece que la información, o el conocimiento debe estar almacenado en UN SOLO LUGAR, para evitar el tedio de cambiar las cosas en mil lados cuando hacen falta cambios, además de ahorrarnos la tendencia a cometer errores cuando hay que cambiar muchas cosas que significan lo mismo.

Analicemos los cambios: agregar un campo y modificar otro. Este conocimiento, en gran parte está almacenado en la base de datos (aunque no todo, por ejemplo en la base de datos no podemos hacer ciertas validaciones para los códigos, o cosas parecidas).

Nadie negará la utilidad de patrones como el MVC, o de ideas como el ORM. Pero a veces esas soluciones crean una sobre ingeniería tan grande que no sé si compensan sus soluciones.


↑↑↑

1.3 Referencia bibliográfica

Principios del diseño orientado a objetos

DRY: Don"t Repeat Yourself (¡No Te Repitas!)

Página 1 de 6


↑↑↑

A.2.Enlaces

[Para saber mas]
[Grupo de documentos]
[Documento Index]
[Apuntes sobre principios de diseño]
[Documento Start]
[Imprimir el Documento]