¿Patrones?

Escrito el 19/09/2003 por Sixto

Muchos programadores flash se sorprenden aún cuando oyen la palabra Patrón referido al diseño de la aplicación (sea web o no), ya que no llegan a entender exactamente para que son útiles. Aquí comienza una serie de post que intentarán dar un poco de luz sobre un tema tan controvertido como fundamental para el desarrollo de aplicaciones profesionales.

El concepto de patrón como solución probada a un problema dado, surgió de un área tan poco relacionada con la programación como es la arquitectura en los años 70 (el arquitecto Christopher Alexander comenzo a aplicarlos), dónde eran aplicados cuando requería enfrentarse a un problema general en un diseño. Desde los tiempos de SmalTalk(primer lenguaje orientadoa objetos de los años 80), los desarrolladores han buscado modelos de programación para poder dividir un problema en partes y poder analizarlo por separado. Comenzando con el famoso modelo MVC.

Los patrones se descubren como una forma indispensable de enfrentarse a la programación a raíz del libro "Design Patterns -- Elements of Reusable Software" de Erich Gamma, Richard Helm, Ralph Jonson y John Vlissides, a partir de entonces los patrones de diseño que aparecen en ese libro son conocidos como los patrones de la pandilla de los cuatro (GoF, gang of four), y comienzan a desarrollarse variaciones y nuevos patrones, en poco tiempo se multiplicaron por 100 y no se limitaban a patrones de diseño sino que cubrían todo los que se entiende por ingeniería del software (desde el análisis hasta la implementación).

Una definición de patrón podría ser una solución en forma de reglas para problemas conocidos. Sólo los patrones que han sido muy utilizados son elevados a la comunidad de desarrolladores, por que la base es que son soluciones sobradamente testadas y utilizadas en una gran variedad de escenarios.

Dentro de los patrones de diseño de software, podemos diferenciar tres comportamientos maestros:

- Patrones de creación: En esencia son patrones que escogen o instancian los objetos que les pedimos por nosotros, flexibilizando la tarea de escoger que objetos utilizar.

- Patrones estructurales: No permiten crear grupos de objetos para realizar determinadas tareas.

- Patrones de comportamiento: Nos permiten definir la comunicación entre los objetos de nuestro sistema.

Antes de comenzar con la serie de patrones, deberemos entender dos conceptos de los patrones generales de software para asignar responsabilidades (GRASP - General Responsability Asigments Software Patterns), que corresponden al diseño de software. Dos de los patrones más importantes son los patrones cohesión y acoplamiento en las clases que diseñamos. Estos conceptos son fundamentales para entender el resto de los patrones, por que se puede decir que derivan de forma directa de estos dos..

Cohesión

Cuando decimos que una clase tiene una alta cohesión queremos decir que el objeto tiene bien delimitadas sus responsabilidades, en la programación orientada a objetos, cada objeto tiene una (o varias, aunque eso sería la mayor parte de las veces un mal diseño) responsabilidad que ha de cumplir dentro de un programa. Por ejemplo, no olvidemos que el OOP es una copia del mundo real, en un supermercado cada cajero tiene una única responsabilidad que es la de cobrar a las personas que han comprado (obviemos que cada acción que ha de realizar sería un objeto diferente, como ejemplo tomemos al cajero del supermercado como un elemento que sólo realiza una acción, cobrar). Bien cuando diseñamos al cajero, si además le asignamos la responsabilidad de barrer el suelo y de colocar los productos, diremos que el objeto tiene baja cohesión, por que realiza muchas responsabilidades que no son connaturales a su función. Es decir, la cohesión de un objeto significa cuan relacionadas y enfocadas están las acciones del objeto, de manera que un objeto cuyas responsabilidades (no olvidemos que las responsabilidades de un objeto se traducen después en métodos que realizan acciones) son pocas y limitadas a su función subyacente, por ello un cajero sólo debe de cobrar, en el mismo instante en que hagamos que el cajero que limpie y ordene, complicamos el sistema de objetos, su organización y la posibilidad de mantenerlo en el futuro. Un buen diseño asignará a cada objeto sólo las responsabilidades que realmente requiera cada uno, dentro de un sistema de ventas, el lector de tarjetas de crédito, sólo debe poder validar las tarjetas de crédito, si hacemos además que sume dos números añadimos responsabilidades al objeto que no le corresponden. Siempre hablando desde el punto de vista conceptual no debemos sobrecargar de responsabilidades a un objeto.

Acoplamiento

El acoplamiento hace referencia a las relaciones que tienen los objetos entre sí dentro de un sistema. Teóricamente, cuando una serie de objetos tienen una relación con varios objetos, cuando estos son cambiados, los objetos relacionados han de verse afectados necesariamente. Por ello la situación ideal es que cada objeto tenga las mínimas dependencias posibles con el resto del sistema, para poder realizar modificaciones en partes del programa sin necesidad de cambiar la mitad del sistema. Una de los mas beneficiados por esta actitud es el programador, ya que un objeto con bajo acoplamiento será más sencillo de reutilizar que otro con alto acoplamiento. El alto acoplamiento se da normalmente cuando un objeto ha de saber demasiados detalles internos de otro para su funcionamiento, es decir, rompe el encapsulamiento de otro objeto. Por ello cuanto menos acoplamiento y mayor cohesión mejor diseñado estará nuestro sistema.

Dentro de los patrones GRASP hay muchos más (información, experto, creación,...), pero esta serie de artículos se refiere a los patrones de codificación, no a los de análisis previo y diseño, hemos considerado necesario explicar estos dos conceptos por la lógica que los patrones que desarrollaremos después nacieron para cumplir en su mayor parte, con estos conceptos.