Articulo de referencia

Patrones de diseño

Elements of Reusable {{nobr|Object-Oriented}} Software"},"image":{"wt":"Design Patterns cover.jpg"},"author":{"wt":"{{unbulleted list|[[Erich Gamma]]|[[Richard Helm]]|[[Ralph Jo...

Patrones de diseño: Elementos de software orientado a objetos reutilizable (1994) es unlibro de ingeniería de software que describe patrones de diseño de software . 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: los dos primeros capítulos exploran las capacidades y los inconvenientes de la programación orientada a objetos , y los capítulos restantes describen 23 patrones de diseño de software clásicos . 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. [ 1 ] Tanto los autores como el libro suelen ser conocidos como la Banda de los Cuatro (GoF). [ 2 ] [ 3 ] [ 4 ] [ 5 ]

Historia del desarrollo y la publicación

El libro surgió de una sesión informal en la reunión de OOPSLA de 1990 , titulada "Hacia un manual de arquitectura", donde Erich Gamma y Richard Helm se conocieron y descubrieron su interés común. Posteriormente se les unieron Ralph Johnson y John Vlissides. [ 6 ] El libro se publicó originalmente el 21 de octubre de 1994, con derechos de autor de 1995, y se puso a disposición del público en la reunión de OOPSLA de 1994.

Introducción

El capítulo 1 es una discusión sobre técnicas de diseño orientado a objetos , basadas en la experiencia de los autores, que ellos creen que conducirían a un buen diseño de software orientado a objetos, incluyendo:

Los autores afirman que las interfaces presentan las siguientes ventajas sobre la implementación:

  • Los clientes permanecen sin ser conscientes de los tipos específicos de objetos que utilizan, siempre y cuando el objeto se ajuste a la interfaz.
  • Los clientes siguen sin ser conscientes de las clases que implementan estos objetos; los clientes solo conocen la(s) clase(s) abstracta(s) que definen la interfaz.

El uso de una interfaz también da lugar a la vinculación dinámica y al polimorfismo , que son características fundamentales de la programación orientada a objetos.

Los autores se refieren a la herencia como reutilización de caja blanca , donde "caja blanca" alude a la visibilidad, ya que los detalles internos de las clases padre suelen ser visibles para las subclases . En cambio, se refieren a la composición de objetos (en la que los objetos con interfaces bien definidas se utilizan dinámicamente en tiempo de ejecución mediante 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 utiliza.

Los autores analizan extensamente la tensión entre herencia y encapsulación y afirman que, según su experiencia, los diseñadores abusan de la herencia (Gang of Four 1995:20). El peligro se describe de la siguiente manera:

"Debido a que la herencia expone una subclase a los detalles de la implementación de su clase 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 quedar tan ligada a la de su clase padre que cualquier cambio en esta última obligará a la subclase a modificarse. Además, afirman que una forma de evitar esto es heredar únicamente de clases abstractas; sin embargo, señalan que esto implica una mínima reutilización de código.

Se recomienda utilizar la herencia principalmente al ampliar la funcionalidad de componentes existentes, reutilizando la mayor parte del código antiguo y añadiendo cantidades relativamente pequeñas de código nuevo.

Para los autores, la delegación es una forma extrema de composición de objetos que siempre puede utilizarse para reemplazar la herencia. La delegación implica dos objetos: un emisor se pasa a sí mismo a un delegado para que este último pueda referirse al emisor. De este modo, el vínculo entre dos partes de un sistema se establece únicamente en tiempo de ejecución, no en tiempo de compilación. El artículo sobre devoluciones de llamada ofrece más información sobre la delegación.

Los autores también analizan los denominados tipos parametrizados, también conocidos como genéricos ( Ada , Eiffel , Java , C# , Visual Basic (.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 momento de su uso.

Los autores admiten que la delegación y la parametrización son muy potentes, pero añaden una advertencia:

"El software dinámico y altamente parametrizado es más difícil de entender y desarrollar que el software más estático." (Gang of Four 1995:21)

Los autores distinguen además entre « agregación », donde un objeto «tiene» o «forma parte» de otro (lo que implica que un objeto agregado y su propietario tienen la misma vida útil), y «conocimiento mutuo», donde un objeto simplemente «sabe» de otro. A veces, el conocimiento mutuo se denomina «asociación» o relación de «uso». Los objetos con conocimiento mutuo pueden solicitarse operaciones entre sí, pero no son responsables unos de otros. El conocimiento mutuo es una relación más débil que la agregación y sugiere un acoplamiento mucho más flexible entre objetos, lo cual suele ser deseable para maximizar la mantenibilidad en los diseños.

Los autores emplean el término «kit de herramientas» donde otros usarían hoy «biblioteca de clases», como en C# o Java. En su terminología, los kits de herramientas son el equivalente orientado a objetos de las bibliotecas de subrutinas, mientras que un « marco de trabajo » es un conjunto de clases que cooperan entre sí y conforman un diseño reutilizable para una clase específica de software. Afirman que diseñar aplicaciones es difícil, crear kits de herramientas es aún más difícil, y diseñar marcos de trabajo es lo más difícil.

Patrones por tipo

Creación

Los patrones de creación son aquellos que crean objetos, en lugar de instanciarlos directamente. Esto le brinda al programa mayor flexibilidad para decidir qué objetos deben crearse en un caso determinado.

Estructural

Los patrones estructurales se refieren a la composición de clases y objetos. Utilizan la herencia para componer interfaces y definen formas de componer objetos para obtener nuevas funcionalidades.

  • El adaptador permite que las clases con interfaces incompatibles funcionen juntas, envolviendo su propia interfaz alrededor de la de una clase ya existente.
  • Bridge desacopla una abstracción de su implementación para que ambas puedan variar de forma independiente.
  • La función Composite combina cero o más objetos similares para que puedan manipularse como un solo objeto.
  • El decorador agrega o sobrescribe dinámicamente el comportamiento en un método existente de un objeto.
  • Facade proporciona una interfaz simplificada para un gran volumen de código.
  • Flyweight reduce el coste de crear y manipular un gran número de objetos similares.
  • El proxy proporciona un marcador de posición para otro objeto con el fin de controlar el acceso, reducir costos y disminuir la complejidad.

Conductual

La mayoría de los patrones de diseño de comportamiento se centran específicamente en la comunicación entre objetos.

  • La cadena de responsabilidad delega comandos a una cadena de objetos de procesamiento.
  • El comando crea objetos que encapsulan acciones y parámetros.
  • El intérprete implementa un lenguaje especializado.
  • Un iterador accede a los elementos de un objeto de forma secuencial sin exponer su representación subyacente.
  • Mediator permite un acoplamiento flexible entre clases al ser la única clase que posee un conocimiento detallado de sus métodos.
  • Memento ofrece la posibilidad de restaurar un objeto a su estado anterior (deshacer).
  • El patrón Observer se basa en la publicación y suscripción, lo que permite que varios objetos observadores vean un evento.
  • El estado permite que un objeto altere su comportamiento cuando cambia su estado interno.
  • La estrategia permite seleccionar sobre la marcha, en tiempo de ejecución, uno de los algoritmos de una familia determinada.
  • El método de plantilla define el esqueleto de un algoritmo como una clase abstracta, lo que permite que sus subclases proporcionen un comportamiento concreto.
  • Visitor separa un algoritmo de una estructura de objetos al trasladar la jerarquía de métodos a un único objeto.

Recepción

En 2005, la ACM SIGPLAN otorgó a los autores el Premio al Logro en Lenguajes de Programación de ese año, en reconocimiento al impacto de su trabajo "en la práctica de la programación y el diseño de lenguajes de programación ". [ 7 ]

Las críticas se han dirigido al concepto de patrones de diseño de software en general, y a Design Patterns en particular. Una crítica principal a Design Patterns es que sus patrones son simplemente soluciones alternativas para las características faltantes en C++, reemplazando elegantes características abstractas con patrones concretos extensos, convirtiéndose esencialmente en un "compilador humano". Paul Graham escribió: [ 8 ]

Cuando detecto patrones en mis programas, lo considero una señal de problemas. La estructura de un programa debería reflejar únicamente el problema que necesita resolver. Cualquier otra regularidad en el código es, al menos para mí, una señal de que estoy utilizando abstracciones insuficientes; a menudo, de que estoy generando manualmente las expansiones de alguna macro que necesito escribir.

Peter Norvig demuestra que 16 de los 23 patrones de Design Patterns se simplifican o eliminan mediante características del lenguaje en Lisp o Dylan . [ 9 ] Hannemann y Kiczales realizaron observaciones similares al implementar varios de los 23 patrones de diseño utilizando un lenguaje de programación orientado a aspectos ( AspectJ ) y demostraron que se eliminaron las dependencias a nivel de código de las implementaciones de 17 de los 23 patrones de diseño y que la programación orientada a aspectos podría simplificar las implementaciones de los patrones de diseño. [ 10 ]

En una entrevista con InformIT en 2009, Erich Gamma afirmó que los autores del libro discutieron en 2005 sobre cómo lo habrían refactorizado y concluyeron que habrían recategorizado algunos patrones y añadido otros, como objeto/interfaz de extensión, inyección de dependencias, objeto de tipo y objeto nulo. Gamma quería eliminar el patrón singleton, pero no hubo consenso entre los autores al respecto. [ 11 ]

Véase también

Referencias

  1. Zehoo, Edmund (26 de enero de 2010). Zehoo, Edmund (ed.). Pro ODP .NET para Oracle Database 11g . Apress. pp. 351–371 . doi : 10.1007/978-1-4302-2821-9_13 vía Springer Link. 
  2. Hussain, Shahid; Keung, Jacky; Khan, Arif Ali (2017). "El efecto del uso de patrones de diseño del Grupo de los Cuatro en los atributos de calidad del diseño". 2017 IEEE International Conference on Software Quality, Reliability and Security (QRS) . pp. 263–273 . doi : 10.1109/QRS.2017.37 . ISBN  978-1-5386-0592-9. S2CID 21343926 . 
  3. Hunt, John (26 de enero de 2013). Hunt, John (ed.). Patrones de diseño de Scala: patrones para la reutilización y el diseño prácticos . Springer International Publishing. pp. 135–136 . doi : 10.1007/978-3-319-02192-8_16 vía Springer Link. 
  4. Almadi, Sara HS; Hooshyar, Danial; Ahmad, Rodina Binti (26 de enero de 2021). "Malos olores de los patrones de diseño de la Banda de los Cuatro: una revisión sistemática de la literatura de una década" . Sustainability . 13 (18) 10256. Bibcode : 2021Sust...1310256A . doi : 10.3390/su131810256 .
  5. Monteiro, Miguel Pessoa; Fernandes, João M. (26 de enero de 2004). "Errores de las implementaciones de aspecto J de algunos de los patrones de diseño del grupo de cuatro" . Universidad de Extremadura. ISBN 978-84-688-8889-7 vía repositorio.uminho.pt.
  6. Richard Helm
  7. "Informe anual de SIGPLAN del año fiscal 2005" (PDF) .{{cite web}}: CS1 mantenimiento: estado de la URL ( enlace )
  8. Graham, Paul (2002). La venganza de los nerds . Recuperado el 11 de agosto de 2012 .
  9. Norvig, Peter (1998). Patrones de diseño en lenguajes dinámicos .
  10. Hannemann, Jan; Kiczales, Gregor (4 de noviembre de 2002). "Implementación de patrones de diseño en Java y aspectJ" . ACM SIGPLAN Notices . 37 (11): 161– 173. doi : 10.1145/583854.582436 . Archivado del original el 9 de marzo de 2025 , a través de la Biblioteca Digital de ACM .
  11. Gamma, Erich; Helm, Richard; Johnson, Ralph (22 de octubre de 2009). "Patrones de diseño 15 años después: una entrevista con Erich Gamma, Richard Helm y Ralph Johnson" . InformIT (Entrevista). Entrevistado por Larry O'Brien. Archivado del original el 20 de febrero de 2019. Consultado el 1 de septiembre de 2019 .