Los patrones de diseño, extensamente utilizados en la industria del desarrollo de software, representan soluciones standard a problemas recurrentes.
La idea de patrón en el contexto del desarrollo se inspira en el arte arquitectónico, proporcionando un recurso conceptualmente próximo. Pese a no ser los inventores del término, los cuatro miembros del denominado Gang of Four (GoF) fueron unos de sus primeros impulsores y probablemente sus mayores divulgadores. Erich Gamma, Richard Helm, Ralph Johnson y John Vlissides propusieron en Design Patterns: Elements of Reusable Object-Oriented Software (1994) una novedosa aproximación al desarrollo orientado a objetos que ha sobrevivido hasta a día de hoy en las aulas de ingeniería.
Los autores del GoF proponen dos principios básicos:
- Programar orientado a una interfaz y no a una implementación.
Este principio busca que el código se utilice como una herramienta que no revele su funcionamiento. La clásica metáfora de la “caja negra” implementada a través del principio de la encapsulación. De este modo, los usuarios del código se centran en la firma abstracta, lo que puede hacer y no puede hacer el código, en vez de en el cómo lo hace. Se establece una separación fundamental entre el programador del código -la persona que lo crea y lo mantiene- y el usuario del código -entendido como el desarrollador que utiliza la librería sin modificar su funcionamiento-. Dicho de otro modo, los patrones GoF buscan proporcionarnos piezas con instrucciones claras sobre con qué se pueden conectar y qué hacen, pero que no nos dicen nada sobre su funcionamiento interno.
- Favorecer la composición antes que la herencia.
En las arquitecturas orientadas a objetos, la composición y la herencia pueden ser muy próximas funcionalmente, pero conceptualmente son distintas. Ambas permiten la agregación de funcionalidades cuando diseñamos una clase y evitan la redundancia de código, pero tienen una diferencia fundamental: la herencia expone el funcionamiento de una clase, mientras que la agregación no lo hace (si trata con clases bien encapsuladas). Siguiendo el principio anterior, es lógico que los patrones GoF favorezcan la composición, ya que la herencia no garantiza la encapsulación. Los autores del GoF llegan a afirmar que la herencia no es compatible con la encapsulación.
Los patrones GoF se dividen en tres tipos fundamentales, agrupados según el tipo de soluciones que aplican.
- Los patrones creacionales son aquellos que aplican soluciones que crean objetos de manera determinada. De este modo buscan encapsular la instanciación de objetos dentro de los métodos de otros objetos opacos, ocultándola al usuario del código.
- Los patrones estructurales abstraen la composición de interfaces a través de otros recursos, como la herencia o la agregación. Se encargan de proporcionar al usuario del código un objeto de firma simple que agrupa múltiples objetos de manera opaca.
- Los patrones de comportamiento buscan proporcionar al usuario del código objetos que aporten una funcionalidad determinada. De este modo los objetos presentan una firma cuyos métodos resuelven un problema específico sin exponer su funcionamiento.
Por supuesto, muchos otros autores han propuesto clasificaciones y patrones alternativos o adicionales. Los patrones GoF representan uno de los pilares de la arquitectura del software, pero no necesariamente tienen la última palabra. Existen otros recursos dignos de mención, como la brillante respuesta de AntiPatterns (1998) por William Brown, Raphael Malveau, Skip McCormick y Tom Mowbray. AntiPatterns repasa los problemas que pueden surgir en la industria tras décadas de arquitecturas centradas en patrones GoF, entre otros factores. Se trata de algo que ha interesado a miembros de la comunidad académica lo suficiente como para hacer publicaciones sobre ello o incluso alguna que otra tesis. Este artículo representa un muy buen resumen de lo que son los patrones y los antipatrones, haciendo hincapié en los malentendidos más habituales.
Para concluir, conviene recordar que cualquier ingeniero (y especialmente el de software) tiene cierta responsabilidad en estar informado y formado sobre el campo en el que trabaja, o se arriesga a perder competitividad. Los patrones GoF son indispensables, pero no exclusivos. Del mismo modo es imposible resolver un problema implementando patrones sin entenderlos y adaptarlos apropiadamente.