experiencia
Servicios - Sepa lo que Ricardo Devis & Asociados pueden hacer por ustedPublicaciones - Consulte los documentos que ponemos a su disposiciónContacto - Conozca como ponerse en contacto con Ricardo Devis & Asociados
 


RPP mayo 1995

Patrones de Diseño: La Calidad Sin Nombre


Ricardo Devis
Botella

El viejo sueño de la comunidad software ha sido emular a la arquitectura tradicional utilizando similares esquemas, procesos, herramientas, elementos y componentes en la construcción de sistemas software. A lo largo del tiempo el desarrollo de tales sistemas ha ido ajustándose de forma metódica a este propósito: las bibliotecas reutilizables, los módulos interconectables, la formalización de fases, etc. muestran distintos aspectos de este acercamiento. Los patrones, al fin, ejemplifican el último estadio de esta relación: bloques que, organizados en catálogos, encapsulan la experiencia de excelentes diseños software.

 


En mi reciente artículo “Gestión de Proyectos Orientados-a-Objetos: Una Incursión Cruenta” (Novática, abril-95) exponía de forma breve el panorama aparentemente confuso y un tanto desolador en el que parece estár sumido el Diseño Orientado-a-Objetos (OOD), necesitado de soluciones formales claras, sectorialmente completas, efectivas, comprensibles y aplicables en la gestión diaria de proyectos software. Se trata, en definitiva, de aplicar la modularidad propugnada para la Programación Orientada-a-Objetos (básicamente según los criterios y principios que expone Bertrand Meyer en “Object-Oriented Software Construction”) a las áreas del Análisis y Diseño Orientados-a-Objetos. Y es en este contexto donde aparecen, como sacados de un cuento de Perrault, los patrones de diseño (inevitable traducción, quizás desafortunada, de Design Patterns: DPs). Basados en la obra del arquitecto y matemático estadounidense Christopher Alexander, los patrones, cual solución balsámica, pretenden encerrar la esencia cualitativa de distintas soluciones sectoriales software y generar componentes de diseño universalmente reutilizables. Bien: el propósito es encomiable, y merece la pena examinarlo en algún detalle.

LA CALIDAD SIN NOMBRE

Los analistas/diseñadores con gran experiencia aplican, de forma mayormente intuitiva y automática, criterios precisos que, de forma global, solucionan de forma elegante y efectiva los problemas de modelación software de sistemas reales. Usualmente estos diseñadores utilizan métodos, estructuras y subsistemas que son, a la vez, herramientas del diseño y partes de la solución final, de una manera que díficilmente puede transmitirse, en un sentido formal, a especialistas menos expertos. Estos bien-dotados diseñadores poseen, también, un sentido especial que “detecta” la completitud, en un sentido eminentemente arquitectónico, de un determinado diseño, con independencia de las posibles métricas y paradigmas utilizados. Naturalmente lo ideal sería extraer la quintaesencia de estos afortunados diseños para formular una suerte de “bálsamo de fierabrás” que pudieran ingerir los diseñadores noveles. Aunque, ¿existe en verdad una parte común en los buenos diseños, a veces tan dispares entre sí? Alexander así lo afirma, y da a esta parte la elusiva calificación de “la calidad que no se puede nombrar”.

Alexander sostiene que existe un “algo innombrable” que no puede ser modelado únicamente por medio de un conjunto arbitrario de requerimientos. Esto es, que los sistemas poseen una esencia cualitativa que les otorga verdadera identidad y equilibra sus fuerzas internas. Y si bien tal calidad no tiene nombre, sí pueden adjetivarse los sistemas que la poseen: vivos, completos, libres, exactos, despersonalizados y eternos. Bien, esto puede sonar un tanto místico, pero así suena Alexander todo el tiempo. Pongamos un ejemplo arquitectónico práctico: si nos fijamos en las construcciones de una determinada zona rural observaremos que todas ellas poseen apariencias parejas (tejados de pizarra con gran pendiente, etc.), pese a que los requerimientos personales por fuerza han debido ser distintos. De alguna manera la esencia del diseño se ha copiado de una construcción a otra, y a esta esencia se plegan de forma natural los diversos requerimientos. Diríase aquí que existe un “patrón” que soluciona de forma simple y efectiva los problemas de construcción en tal zona. Este patrón, no obstante, para ser considerado como tal, y siempre según Alexander, debe encerrar la capacidad de conectar con la cualidad buscada.

PATRONES DE DISEÑO SOFTWARE

Tal y como Alexander expone, “cada patrón describe un problema que ocurre una y otra vez en nuestro entorno, para describir después el núcleo de la solución a ese problema, de tal manera que esa solución pueda ser usada más de un millón de veces sin hacerlo siquiera dos veces de la misma forma”. Pero pasemos ya al área software: un patrón de diseño [1] es, pues, una solución a un problema en un determinado contexto. Tal solución es, empero, a la vez parte del “qué” y del “cómo” del sistema completo a construir: esto es, la pieza que conforma el patrón software es como la pieza del patrón de sastre que se utiliza para confeccionar vestidos y trajes, pues tal pieza, aparte de contener las especificaciones de corte y confección del producto final, representa a la vez, en apariencia, una parte de tal producto textil. Pero vayamos a un ejemplo práctico.

Es usual que en el diseño de distintos sistemas software nos encontremos con similares problemas a resolver, y uno de los más frecuentes es el que nos enfrenta a un conjunto de objetos (o estructuras de datos -en fin, seamos comprensivos-) cuyo contenido debemos recorrer, objeto a objeto, con el fin de operar (comparar, coleccionar, etc.) con los valores que encontremos. Usualmente, también, la solución consiste en usar de un objeto “iterador” (o función iteradora) que recorre la colección de elemento en elemento. Pero pronto constatamos que el problema necesita una solución matizadamente distinta en cada contexto en el que se plantea: así, por ejemplo, no resulta igual iterar por una colección que por un objeto compuesto por capas envolventes, como tampoco es exactamente igual un recorrido que la conjunción concurrente de varios iteradores sobre la misma colección, ni resultan iguales los iteradores concretos que aquellos otros polimórficos, aunque, de alguna manera, la esencia de la iteración es la misma para todos los problemas de ese tipo. Aquí tenemos, por tanto, un “patrón”, conocido como “Iterador” o “Cursor”, cuya descripción podría darse de acuerdo con el siguiente esquema (extraído del libro del GOF):

  • Intención : sucinta descripción de lo que se pretende conseguir con el patrón.
  • También Conocido como : otros nombres del mismo patrón.
  • Motivo : explicación justificativa de la necesidad de que el patrón exista como entidad autónoma.
  • Aplicabilidad : lista de usos para los que resulta especialmente adecuado el patrón que se describe.
  • Estructura : descripción gráfica de los comportamientos, acciones y relaciones de los objetos que participan en el patrón.
  • Participantes : diccionario de las partes que componen el patrón.
  • Colaboraciones : diccionario de las relaciones e interacciones entre los participantes en un patrón.
  • Consecuencias : detalle de los posibles beneficios y perjuicios que pueden derivarse del uso del patrón.
  • Implementación : detalle de las posibles implementaciones y catálogo de las decisiones de diseño en la codificación de soluciones concretas basadas en el patrón.
  • Código de Ejemplo : planteamiento de código práctico referido a un ejemplo (o ejemplos) suficientemente representativo del uso del patrón.
  • Usos Conocidos : detalle de bibliotecas, productos y sistemas en que se ha utilizado el patrón.
  • Patrones Relacionados : referencias a otros patrones que bien sean directamente utilizados por el descrito bien representen soluciones complementarias o suplementarias al mismo.

Si accedemos a un catálogo que contenga este patrón (“iterador”), encontraremos que se refiere al acceso secuencial a objetos sin entrar en su representación interna: esto es, sin directamente cambiarlos. Porque resulta que si lo que queremos es actuar de alguna manera sobre los objetos a recorrer, entonces deberemos usar de otro patrón: el conocido como “visitador”. Vemos, pues, que ya existe una granulación diferencial de patrones que pretende encapsular la experiencia adquirida en muchos proyectos software de forma límpida y reutilizable. Y es que, como el lector fácilmente comprenderá, lo difícil de los patrones es precisamente descubrirlos, pulirlos y formalizarlos, porque la realidad, como una alfombra, necesita ser extendida y desenrollada para que se puedan apreciar sus “patrones”, pues si no éstos aparecen desfigurados y confusos [2].

CATÁLOGOS DE PATRONES

Si aceptamos, pues, que los patrones pueden resultar útiles en el desarrollo de software, el siguiente paso es reunirlos en catálogos de forma que resulten accesibles mediante distintos criterios, pues lo que necesitamos no es tan sólo la completa descripción de cada uno de los patrones sino, esencialmente, la correspondencia entre un problema real y un patrón (o conjunto de patrones) determinado. Desafortunadamente, y a pesar de la segmentación en la exposición de los patrones detallada anteriormente, tal objetivo todavía no se ha conseguido: existen catálogos de patrones (como el libro del GOF, que se detalla más adelante), pero la capacidad de elección todavía se basa en el conocimiento completo de los mismos. Pero esto se apreciará mejor en un ejemplo.

Recientemente un cliente nos enfrentó al diseño de una biblioteca genérica de impresión multiplataforma cuyo uso principal sería generar en tiempo de ejecución objetos concretos de tipo “Impresora”, con distintas implementaciones, a los que dirigir mensajes de impresión en base a un interfaz genérico predefinido. Tras el pertinente estudio estimamos que el problema básico de diseño se podía resolver utilizando dos patrones (y en esta elección influyó notoriamente el lenguaje a utilizar, C++): “Prototipo”, para diferir hasta tiempo-de-ejecución la creación de un determinado objeto impresora, clonando un objeto estático, y “Puente”, para separar el interfaz (establecido en una clase base “gruesa” que encerraría toda la funcionalidad) de las posibles implementaciones (los lenguajes de impresora) que se establecen en una jerarquía paralela aparte [3]. Naturalmente este resultado se basó en el anterior conocimiento de un suficiente número de patrones, de manera que, en realidad, si no hubieran existido patrones se habría solucionado de parecida manera, pues se trataba de problemas que ya se habían abordado anteriormente. Pero, claro, lo que se pretende con un catálogo de patrones no es favorecer al diseñador experto (que quizás no necesite en absoluto de los patrones, aunque el estudio de la formalización del conocimiento es siempre recomendable), sino más bien ayudar al diseñador inexperto a adquirir con cierta rapidez las habilidades de aquél, como también comunicar al posible cliente, si es el caso, las decisiones de diseño de forma clara y autosuficiente. Se trata, en definitiva, de un medio para comunicar la experiencia de forma efectiva, reduciendo (o aplastando) lo que sorprendentemente se conoce como “curva de aprendizaje” del diseño.

¿PATRONES ORIENTADOS-A-OBJETOS?

¿Hablamos de diseño de software o más bien de diseño-orientado-a-objetos de software? Parecería que, según lo hasta ahora visto, los patrones habrían de acoplarse bien a cualquier esquema. Bien: en teoría sí, pero en la práctica la casi totalidad de los trabajos y catálogos en este campo (como el libro GOF) se refieren a sistemas orientados-a-objetos. Parece que esto responde a que, simplemente, el “patrón de conducta” en diseño es ahora el OOD. Claro que algunos pretenderían una solución para todo [4], pero parece claro que las ideas de modularidad reutilizable en que se sustentan los patrones encuentran asiento natural en sistemas de diseño con las facilidades modulares de la orientación-a-objetos.

TELEPREDICADORES DE SOFTWARE

La Programación Estructurada , la Orientación-a-Objetos, y ahora ... ¡los Patrones! En la comunidad software, como en la religiosa y en la política, aparecen cada tanto soluciones pretendidamente salvadoras que ofrecen a sus postulantes cambios tan radicales que resultan tentadoramente creíbles [5]. Y es que, ¿con qué herramientas se mide la idoneidad de una teoría empírica? Usualmente infieriendo su correctitud desde exitosos ejemplos prácticos. Entonces, si examinamos los patrones, ¿por qué no examinar, en primer lugar, su aplicación en la arquitectura tradicional? ¿Por qué no estudiar los exitosos trabajos de Alexander? Pues porque el brillante prestigio teórico de Alexander (un tanto discutido en su propia área) está ligado a una desazonadora ejemplificación práctica de sus proyectos: desde inesperados -por no decir turbadores- resultados a fastuosos fracasos (como el de la comunidad de Mexicali). ¿Entonces -preguntará el ahora decididamente inquieto lector- los patrones no funcionan en arquitectura? Bueno, querido lector, piense que Alexander, en sí, no es la piedra angular de ningún sistema software. Recordemos, por ejemplo, que Collodi fue un mediocre escritor antes de “Pinoccio” y siguió siéndolo después de éste. A veces una solitaria buena idea genera resultados extraordinarios, y Alexander expone, en un inglés exaltado, varias excelentes ideas. Piénsese, también, que los hijos no resultan nunca como los padres porfían han de ser, y es que en la comunidad software a Cronos se lo comerían sus hijos sin darle tiempo siquiera a posar para Goya. Parece, por otro lado, que los patrones son “nuevos”, pero en absoluto es así, pues existen patrones-marcos formales desde hace tiempo: MVC de Smalltalk, MacApp, etc., así como patrones-de-rutinas que todos conocemos: las bibliotecas de algoritmos. Resulta, al fin, que nos encontramos en una fase incierta de captura y formalización de la rica experiencia en diseño extendida en multitud de maduros sistemas software, y aparece claro que el sentido de la marcha es irreversible. ¿Patrones? ¡Sí, pero con prudencia!

PATRONES BIBLIOGRÁFICOS

Hay unos cuantos textos relacionados con el tema que nos ocupa, buena parte de ellos de Alexander, naturalmente. He aquí mi selección:

Notes on the Synthesis of Design, de Christopher Alexander, 1964, Harvard University Press. Este es el texto basado en la tesis doctoral de Alexander, y base, a la vez, del estudio de Alexander sobre el sistema BART, en el que el autor establece por vez primera que la funcionalidad del sistema no depende tan sólo de un conjunto de requerimientos.

A Pattern Language: Towns/Building/Construction, de Christopher Alexander, Sara Ishikawa, Murray Silverstein, Max Jacobson, Ingrid Fiksdahl-King y Shlomo Angel, 1977, Oxford University Press. 253 patrones, con el formato específico propuesto por Alexander, se dan cita en este texto, en el que además se propugna una integración del mejor-vivir con el medio físico circundante: gente-gente-patrones-gente. Cuando se habla del “libro de Alexander” (CA patterns book) o del “libro AIS” (las iniciales de los primeros autores) se refieren a esta obra.

The Oregon Experiment, de Christopher Alexander, 1978, Oxford University Press. Aquí se explicitan los planteamientos participativos (usuario-constructor/diseñador) puestos en práctica en el plan maestro de Berkeley de 1970. El resultado, fiel a la trayectoria práctica alexanderiana, no fue el esperado.

The Timeless Way of Building, de Christopher Alexander, 1979, Oxford University Press. Junto con el de “A Pattern Language” esta es una de las obras más difundidas de Alexander. Si a estas alturas ya soportamos bien el estilo pseudo-filosófico-religioso del autor, el texto merece la lectura.

The Production of Houses, de Christopher Alexander, 1985, Oxford University Press. Se relata aquí la desafortunada historia del fallido proyecto de construcción de una comunidad en Mexicali. Este texto es especialmente interesante por cuanto en él Alexander reflexiona sobre los problemas y carencias que llevaron al fracaso del proyecto. Algunas reflexiones resultan emocionalmente ingenuas (sobre todo las relacionadas con la escasa comprensión del gobierno mexicano), pero de ellas se desprende un tono de advertencia al que los nuevos apóstoles de los DPs no debieran resultar ajenos.

A New Theory of Urban Design, de Christopher Alexander, 1987, Oxford University Press.

Advanced C++ Programming Styles and Idioms, de James O. Coplien, 1992, Addison-Wesley. Desde su publicación he venido recomendando efusiva e insistentemente este inteligente libro a todo aquél que de verdad quiera conocer el lenguaje C++ y aun usarlo. Resulta claro ahora, como el mismo autor expresamente reconoce, que los idiomas aquí descritos son en realidad patrones, presentados empero sin formato definido. El libro es, pues, doblemente imprescindible.

Design Patterns: Elements of Reusable Object-Oriented Software, de Erich Gamma, Richard Helm, Ralph Johnson y John Vlissides, 1995, Addison-Wesley. Este texto se conoce como “GOF book” o libro del GOF (Gang-of-Four: Clan-de-los-Cuatro, en evidente referencia a los autores del texto), y es sencillamente indispensable para cualquiera interesado en los patrones de diseño. Tras una adecuada introducción conceptual se introduce al lector en un caso práctico (un editor WYSIWYG) y ante los sorprendidos ojos de éste desfilan patrones donde no parecía haberlos. Seguidamente se detallan distintos patrones agrupados en tres subcatálogos: de creación, estructurales y de comportamiento, con ejemplos en C++ y Smalltalk. Por su solidez este libro puede hacer cambiar de parecer a los que pudieran pensar que es demasiado pronto para redactar un catálogo de patrones. En fin, imprescindible.

Design Patterns for Object-Oriented Software Development, de Wolfgang Pree, 1995, Addison Wesley. Tras un breve examen de la historia, estado y clasificación de los patrones (patrones orientados a objetos, patrones de codificación, recetarios de marcos, contratos formales y catalógos de patrones de diseño), Pree nos adentra en los metapatrones, o piezas reusables que encierran el diseño de complejos marcos-entornos. En realidad el libro trata sobre marcos (frameworks), y sobre cómo puede encontrarse en estos (bien establecidos y maduros) un conjunto mínimo de metapatrones transportable al desarrollo de otros marcos. Pree expone siete metapatrones y después aboga por su integración en el proceso de OOA/OOD mediante lo que él mismo denomina Hot-Spot-Driven Design (HSDD: diseño enfocado-a-zonas-sensibles, en insana traducción). En esencia, una Zona-Sensible es, respecto de un escenario de diseño, un área bien delimitada susceptible de cambio (esto es, un área flexible). El texto es interesante, con varias referencias al libro GOF, pero quizás se centra demasiado en el académico ET++ (un marco para desarrollo de GUIs) obviando otros marcos comercialmente bien establecidos; a la vez, las referencias a los patrones de codificación en C++ resultan un tanto ingenuas. El libro resulta, con todo, recomendable.

PATRONES ELECTRÓNICOS

Después de los libros, y dados la juventud y el estado “de permanente construcción” de los patrones, el lector quizás desee tener acceso a algunas de las fuentes on-line. Helas aquí:

World-Wide-Web: obviaré las referencias Gopher y de ftp-sites, que pueden ser accedidas mediante el WWW.

  • La Página de Patrones (Patterns Home Page) en el Web está mantenida por Richard Helm (sí, uno del GOF) y su URL es: http://st-www.cs.uiuc.edu/users/patterns/patterns.html. Aquellos que no puedan acceder al Web pueden obtener esta página vía e-mail, pues existe un servidor en el CERN que envía por correo electrónico la página WWW que se le pida: sólo hay que envíar un mensaje via correo electrónico a <code>listproc@www0.cern.ch. La línea del asunto no tiene importancia, pero en el cuerpo del mensaje debe figurar <code>"www [URL completa]" (en este caso “www http://st-www.cs.uiuc.edu/users/patterns/patterns.html”).
  • También en el Web, en “http://g.oswego.edu/dl/pd-FAQ/pd-FAQ.html” o en “http://gee.cs.oswego.edu/pd-FAQ.html” puede encontrarse un FAQ (Frequent Answers & Questions: Frecuentes Preguntas y Respuestas) de patrones.

Listas de correo: esta es la materia viva de la que el lector podrá extraer lo último en patrones. Es aquí, también, donde se pueden exponer ideas, pedir consejos, etc.

  • Discusión de Patrones (patterns-discussion): En esta lista se discuten la teoría y aplicación de patrones, incluidos los trabajos de Alexander y si sus ideas pueden o no aplicarse al software, así como herramientas y métodos que soporten patrones en el desarrollo de software, y si los patrones software son similares o diferentes de otras clases de patrones. Para añadirse a la lista debe enviar un mensaje a listserver@cs.uiuc.edu con el siguiente cuerpo: “subscribe patterns-discussion Nombre Apellidos”. Si tienen problemas para obtener la subscripción y contraseña, pónganse en contacto con Ralph Johnson (sí, amable lector, otro del GOF), el propietario de la lista, en johnson @cs.uiuc.edu.
  • Patrones de Negocio (business-patterns): En esta lista se pretenden dejar de lado los patrones de bajo-nivel para tratar de aquéllos con relevancia para el mundo empresarial. Para suscribirse hay que envíar un mensaje a business-patterns-request@cs.uiuc.edu con la línea “subscribe” como cuerpo.
  • Patrones del Clan-de-los-Cuatro (Gang-of-4-Patterns): Esta es una lista centrada en el libro del GOF, aunque sus autores se pasean por las otras listas también. Para añadirse a la lista debe enviar un mensaje a listserver@cs.uiuc.edu con el siguiente cuerpo: “subscribe gang-of-4-patterns Nombre Apellidos”.
  • Compuserve : En la sección 3 (Study Hall) del forum CLMFORUM de Compuserve se está discutiendo actualmente el libro del GOF.

Conferencias: aparte de las que seguidamente se mencionan hay que reseñar la sección de OOPSLA dedicada a los patrones: en realidad la mayoría de conferencias sobre Orientación-a-Objetos empiezan a considerar -si es que ya no lo han puesto en práctica- la inclusión de una sección específica de patrones.

  • PLoP ‘94: La Primera Conferencia Anual sobre Patrones (PLoP: Pattern Languages of Programs) se celebró del 4 al 6 de agosto de 1994 en Monticello, Illinois, USA. El planteamiento de esta conferencia resultó particularmente gratificante, porque los trabajos no fueron expuestos directamente por sus autores, sino por un grupo de revisores pre-seleccionados que en cada caso expusieron sus gustos, quejas y sugerencias, fomentando así la participación entre los asistentes.
  • PLoP '95: La Segunda Conferencia Anual sobre Patrones se celebrará del 6 al 8 de septiembre de 1995 en Monticello, Illinois , USA. Los interesados pueden contactar con los organizadores en plop95@parcplace.com, o dirigirse bien Richard P. Gabriel en rpg@parcplace.com bien a Kent Beck [6] en 70761.1216@compuserve.com.
  • EuroPLoP ‘95 : La Conferencia Europea sobre Patrones (European Pattern Languages of Programs), se celebrará del 7 al 11 de agosto de 1.995 en Aarhus, Dinamarca, en conjunción con ECOOP ‘95.

 

[1] También denominado “patrón software” o “patrón generativo”.

[2] ¡Vaya, esto suena profundo!, pero debo reconocer que el mérito, en traducción libre, es de Themistocles.

[3] En realidad se necesitó algo más que dos patrones (como, por ejemplo, un subsistema gestor de implementaciones), pero esa es otra historia (nadie ha dicho que los patrones sean autosuficientes para completar sistemas software).

[4] Es como si desearan una suerte de quinta sinfonía de Prokofiev (la fusión del clasicismo tradicional y la vigorosa modernidad), pero sólo obtuvieran el poderoso scherzo del segundo movimiento. ¡Ahí es nada!

[5] Remy de Gourmont afirmaba que los hombres son tan estúpidos que dando un nombre nuevo a una cosa vieja creen haber pensado algo nuevo. Bierce, más práctico, ironizaba: “Cogito cogito ergo cogito sum”.

[6] Kent Beck, que pertenece al Grupo de Patrones de Hillside, presentó en OOPSLA ‘89, junto con Ward Cunningham, las fichas CRC, como el lector orientado-a-objetos posiblemente ya sabrá.

 
 
 
volver a la página de publicaciones
 
 
 Pº. Castellana 188, 14º e · 28046 - Madrid · info@a4devis.com