Patrones de diseño
Patrones de diseño: Elementos de software orientado a objetos reutilizable (1994) es un libro de ingeniería de software que describe patrones de diseño de software. El libro fue escrito por Erich Gamma, Richard Helm, Ralph Johnson y John Vlissides, con un prólogo de Grady Booch. El libro está dividido en dos partes, con los primeros dos capítulos explorando las capacidades y peligros de la programación orientada a objetos, y los capítulos restantes describen 23 patrones clásicos de diseño de software. El libro incluye ejemplos en C++ y Smalltalk.
Ha sido influyente en el campo de la ingeniería de software y se considera una fuente importante para la teoría y la práctica del diseño orientado a objetos. Se han vendido más de 500.000 copias en inglés y en otros 13 idiomas. A menudo se hace referencia a los autores como la banda de los cuatro (GoF).
Historia
El libro comenzó en una sesión de Birds of a Feather (BoF) en OOPSLA '90, "Towards an Architecture Handbook", dirigida por Bruce Anderson, donde Erich Gamma y Richard Helm se conocieron y descubrieron su interés común. Más tarde se les unieron Ralph Johnson y John Vlissides. La fecha de publicación original del libro fue el 21 de octubre de 1994 con derechos de autor de 1995, por lo que a menudo se cita con el año 1995, a pesar de haber sido publicado en 1994. El libro se puso a disposición del público por primera vez en la reunión de la OOPSLA celebrada en Portland., Oregón, en octubre de 1994. En 2005, ACM SIGPLAN otorgó el Premio al Logro en Lenguajes de Programación de ese año a los autores, en reconocimiento al impacto de su trabajo "en la práctica de programación y el diseño de lenguajes de programación". En marzo de 2012, el libro se encontraba en su edición número 40.
Introducción
El capítulo 1 es una discusión de las técnicas de diseño orientado a objetos, basado en los autores' experiencia, que creen que conduciría a un buen diseño de software orientado a objetos, que incluye:
- "Programa a una interfaz, no a una implementación." (Gang of Four 1995:18)
- Composición sobre la herencia: "Favor 'composición objeta' sobre 'la herencia de clase'". (Gang of Four 1995:20)
Los autores afirman lo siguiente como ventajas de las interfaces sobre la implementación:
- los clientes siguen sin darse cuenta de los tipos específicos de objetos que utilizan, siempre y cuando el objeto se adhiera a la interfaz
- clientes siguen sin darse cuenta de las clases que implementan estos objetos; los clientes sólo saben acerca de la clase abstracta(es) que define la interfaz
El uso de una interfaz también conduce a enlaces dinámicos y polimorfismos, que son características centrales de la programación orientada a objetos.
Los autores se refieren a la herencia como reutilización de caja blanca, con caja blanca que se refiere a la visibilidad, porque las partes internas de las clases principales a menudo son visibles para las subclases. En contraste, los autores se refieren a la composición de objetos (en la que los objetos con interfaces bien definidas son usados dinámicamente en tiempo de ejecución por objetos que obtienen referencias a otros objetos) como reutilización de caja negra porque no es necesario que los detalles internos de los objetos compuestos sean visibles en el código que los usa.
Los autores analizan extensamente la tensión entre la herencia y la encapsulación y afirman que, según su experiencia, los diseñadores abusan de la herencia (Gang of Four 1995:20). El peligro se expresa de la siguiente manera:
- "Porque la herencia expone una subclase a detalles de la implementación de su padre, a menudo se dice que la herencia rompe la encapsulación". (Gang of Four 1995:19)
Advierten que la implementación de una subclase puede estar tan ligada a la implementación de su clase principal que cualquier cambio en la implementación de la clase principal obligará a la subclase a cambiar. Además, afirman que una forma de evitar esto es heredar solo de clases abstractas, pero luego señalan que la reutilización del código es mínima.
El uso de la herencia se recomienda principalmente cuando se agrega a la funcionalidad de los componentes existentes, se reutiliza la mayor parte del código antiguo y se agregan cantidades relativamente pequeñas de código nuevo.
A los autores, 'delegación' es una forma extrema de composición de objetos que siempre se puede usar para reemplazar la herencia. La delegación implica dos objetos: un 'remitente' pasa a sí mismo a un 'delegado' para permitir que el delegado se refiera al remitente. Por lo tanto, el enlace entre dos partes de un sistema se establece solo en tiempo de ejecución, no en tiempo de compilación. El artículo de devolución de llamada tiene más información sobre la delegación.
Los autores también analizan los denominados tipos parametrizados, que también se conocen como genéricos (Ada, Eiffel, Java, C#, VB.NET y Delphi) o plantillas (C++). Estos permiten definir cualquier tipo sin especificar todos los demás tipos que utiliza; los tipos no especificados se proporcionan como 'parámetros' en el punto de uso.
Los autores admiten que la delegación y la parametrización son muy poderosas pero agregan una advertencia:
- "El software dinámico y altamente parametrizado es más difícil de entender y construir que el software estático". (Gang of Four 1995:21)
Los autores distinguen además entre 'Agregación', donde un objeto 'tiene' o 'es parte de' otro objeto (lo que implica que un objeto agregado y su propietario tienen tiempos de vida idénticos) y conocido, donde un objeto simplemente 'sabe de' otro objeto A veces, el conocido se llama 'asociación' o el 'usando' relación. Los objetos conocidos pueden solicitar operaciones entre sí, pero no son responsables entre sí. El conocimiento es una relación más débil que la agregación y sugiere un acoplamiento mucho más flexible entre los objetos, lo que a menudo puede ser deseable para lograr la máxima capacidad de mantenimiento en un diseño.
Los autores emplean el término 'kit de herramientas' donde otros podrían usar hoy 'biblioteca de clases', como en C# o Java. En su lenguaje, los juegos de herramientas son el equivalente orientado a objetos de las bibliotecas de subrutinas, mientras que un 'marco' es un conjunto de clases cooperativas que conforman un diseño reutilizable para una clase específica de software. Afirman que las aplicaciones son difíciles de diseñar, los conjuntos de herramientas son más difíciles y los marcos son los más difíciles de diseñar.
Patrones por tipo
Creativo
Los patrones de creación son los que crean objetos, en lugar de tener que crear instancias de objetos directamente. Esto le da al programa más flexibilidad para decidir qué objetos necesitan ser creados para un caso dado.
- Grupos de fábrica abstractos objetan fábricas que tienen un tema común.
- El constructor construye objetos complejos separando la construcción y la representación.
- El método de fábrica crea objetos sin especificar la clase exacta para crear.
- El prototipo crea objetos clonando un objeto existente.
- Singleton restringe la creación de objetos para una clase a sólo una instancia.
Estructurales
Estos se refieren a la composición de clases y objetos. Usan la herencia para componer interfaces y definen formas de componer objetos para obtener nuevas funcionalidades.
- Adaptador permite que las clases con interfaces incompatibles trabajen juntas envolviendo su propia interfaz alrededor de la de una clase ya existente.
- Bridge decodifica una abstracción de su implementación para que los dos puedan variar independientemente.
- Composite compone objetos cero o más similares para que puedan ser manipulados como un objeto.
- El decorador agrega dinámicamente/supera el comportamiento en un método existente de un objeto.
- Facade proporciona una interfaz simplificada a un gran cuerpo de código.
- Flyweight reduce el costo de crear y manipular un gran número de objetos similares.
- Proxy proporciona un marcador de posición para otro objeto para controlar el acceso, reducir el costo y reducir la complejidad.
Conductual
La mayoría de estos patrones de diseño están relacionados específicamente con la comunicación entre objetos.
- Cadena de los delegados de responsabilidad manda a una cadena de objetos de procesamiento.
- El comando crea objetos que encapsulan acciones y parámetros.
- El intérprete aplica un idioma especializado.
- El Iterador accede a los elementos de un objeto secuencialmente sin exponer su representación subyacente.
- Mediador permite un acoplamiento suelto entre las clases siendo la única clase que tiene conocimiento detallado de sus métodos.
- Memento proporciona la capacidad de restaurar un objeto a su estado anterior (deshacer).
- El observador es un patrón de publicación/subscribe, que permite a varios objetos de observación ver un evento.
- El Estado permite que un objeto altere su comportamiento cuando su estado interno cambia.
- La estrategia permite seleccionar a una familia de algoritmos a tiempo de ejecución.
- El método de plantilla define el esqueleto de un algoritmo como una clase abstracta, permitiendo que sus subclas proporcionen comportamiento concreto.
- El visitante separa un algoritmo de una estructura de objeto moviendo la jerarquía de métodos en un objeto.
Crítica
Las críticas se han dirigido al concepto de patrones de diseño de software en general, ya los patrones de diseño en particular. Una crítica principal de Patrones de diseño es que sus patrones son simplemente soluciones para las características que faltan en C++, reemplazando características abstractas elegantes con patrones concretos extensos, convirtiéndose esencialmente en un "compilador humano". Pablo Graham escribió:
Cuando veo patrones en mis programas, lo considero un signo de problemas. La forma de un programa debe reflejar sólo el problema que necesita resolver. Cualquier otra regularidad en el código es un signo, para mí al menos, que estoy usando abstracciones que no son lo suficientemente poderosas-- a menudo que estoy generando a mano las expansiones de una macro que necesito escribir.
Peter Norvig demuestra que 16 de los 23 patrones en Patrones de diseño son simplificados o eliminados por características de lenguaje en Lisp o Dylan. Hannemann y Kiczales realizaron observaciones relacionadas, quienes implementaron varios de los 23 patrones de diseño usando un lenguaje de programación orientado a aspectos (AspectJ) y demostraron que las dependencias a nivel de código se eliminaron de las implementaciones de 17 de los 23 patrones de diseño y que los patrones de diseño orientados a aspectos la programación podría simplificar las implementaciones de patrones de diseño.
También ha habido críticas humorísticas, como un juicio espectáculo en OOPSLA '99 el 3 de noviembre de 1999, y una parodia del formato, de Jim Coplien, titulada "Kansas City Air Conditioner".
En una entrevista con InformIT en 2009, Erich Gamma afirmó que los autores del libro mantuvieron una discusión en 2005 sobre cómo habrían refactorizado el libro y llegaron a la conclusión de que habrían recategorizado algunos patrones y agregado algunos adicionales, como extensión objeto/interfaz, inyección de dependencia, tipo de objeto y objeto nulo. Gamma quería eliminar el patrón Singleton, pero no hubo consenso entre los autores para hacerlo.
Contenido relacionado
Transporte en Kenia
Hormigón
ATA paralelo