Design Patterns in Go
  • Portada
  • Introducción
  • Publicación
  • Parte I
    • Sobre Go
    • POO en Go
      • Objetos
      • Herencia / Composición
      • S.O.L.I.D
  • Parte II
    • Patrones de Diseño
      • GoF
      • Patrones de Comportamiento
        • Strategy
        • Chain of Responsibility
        • Command
        • Template Method
        • Memento
        • Interpreter
        • Iterator
        • Visitor
        • State
        • Mediator
        • Observer
      • Patrones Creacionales
        • Singleton
        • Builder
        • Factory Method
        • Abstract Factory
        • Prototype
      • Patrones Estructurales
        • Composite
        • Adapter
        • Bridge
        • Proxy
        • Decorator
        • Facade
        • Flyweight
  • Parte III
    • Conclusiones
    • Acerca De
  • Recursos de interés
  • Glosario
Con tecnología de GitBook
En esta página
  • ¿Qué es Gof?
  • ¿Es posible implementar los patrones de diseño en Go?
  • ¿Cómo se clasifican los patrones?
  • Catálogo de patrones
  • Patrones de Clase
  • Patrones de Objeto
  • ¿Cómo se documenta un patrón?
  • Implicancias

¿Te fue útil?

  1. Parte II
  2. Patrones de Diseño

GoF

AnteriorPatrones de DiseñoSiguientePatrones de Comportamiento

Última actualización hace 5 años

¿Te fue útil?

¿Qué es Gof?

En esta publicación se utilizarán los 23 patrones de diseño del libro "Patrones de Diseño: Elementos de software orientado a objetos reutilizable" escrito por Erich Gamma, Richard Helm, Ralph Johnson y John Vlissides. El término GoF proviene de los autores del libro que son conocidos por la comunidad como Gang of Four (La Banda de los Cuatro).

¿Es posible implementar los patrones de diseño en Go?

En el libro "Patrones de Diseño" los autores hacen la siguiente aclaración respecto de los lenguajes utilizados para documentar los 23 patrones: "Aunque los patrones describen diseños orientados a objetos, están basados en soluciones prácticas que han sido implementadas en los lenguajes de programación orientados a objetos más usuales, como Smalltalk y C++, en vez de mediante lenguajes procedimentales (Pascal, C, Ada) u otros lenguajes orientados a objetos más dinámicos (CLOS, Dylan, Self). Nosotros hemos elegido Smalltalk y C++ por una cuestión pragmática: nuestra experiencia diaria ha sido con estos lenguajes, y estos cada vez son más populares". "La elección del lenguaje de programación es importante, ya que influye en el punto de vista. Nuestros patrones presuponen características de Smalltalk y C++, y esa elección determina lo que puede implementarse o no fácilmente. Si hubiéramos supuesto lenguajes procedimentales, tal vez, hubiéramos incluido patrones llamados 'Herencia', 'Encapsulación' y 'Polimorfismo'. De manera similar, algunos de nuestros patrones están incluidos directamente en lenguajes orientados a objetos menos corrientes. CLOS, por ejemplo, tiene multi-métodos que reducen la necesidad de patrones como Visitor. De hecho, hay suficientes diferencias entre Smalltalk y C++ como para que algunos patrones puedan expresarse más fácilmente en un lenguaje que en otro (por ejemplo, el Iterator)"

Es importante remarcar que este libro fue publicado en 1994 - (Java 1 recién se publicó en 1996)

También es importante entender que este trabajo intenta demostrar cómo pueden aplicarse los patrones de diseño en Go, aunque no es necesariamente imperativo su uso ni se lo promueve. Tal como exponen los autores, cada lenguaje tiene sus particularidades y en necesario entender el real problema a resolver, y no intentar adaptar formas de trabajo de un lenguaje a otro, sino entender esas particularidades que hacen diferente a un lenguaje respecto del otro para potenciar sus características.

A pesar de que parezca desalentador lo anteriormente dicho es importante remarcarlo. Un error muy común cuando aprendemos algo nuevo es querer utilizarlo en cualquier contexto, sin analizar realmente la conveniencia de su uso. Cuando uno aprende un patrón de diseño nuevo se ve tentado a utilizarlo. Los patrones de diseño resuelven problemas conocidos, y solo deben usarse si se está en presencia de un problema apropiado.

Un error que veo muy seguido es la adaptación de un patrón de un lenguaje a otro (como si se tratase de una traducción literal) cuando en realidad no se tienen en cuenta sus características específicas, que hacen a cada lenguaje de programación único, ni el objetivo que intenta resolver el patrón de diseño. Intentaré no caer yo mismo en este error.

En Go pueden aprovecharse algunas de sus características particulares para implementar también otros tipos de patrones distintos a los del libro "Patrones de Diseño" . Por ejemplo hay una gran cantidad de patrones de concurrencia.

¿Cómo se clasifican los patrones?

Los patrones de diseño se organizan en tres familias de acuerdo a su propósito:

  • Creacionales: tienen que ver con el proceso de creación de objetos.

  • Estructurales: tratan con la composición de clases u objetos.

  • Comportamiento: caracterizan el modo en el que las clases y objetos interactúan y se reparten responsabilidades.

Los autores del libro "Patrones de Diseño" , también proponen otro criterio de clasificación denominado ámbito: "especifica si el patrón se aplica principalmente a clases o a objetos. Los patrones de clases se ocupan de relaciones entre las clases y sus subclases. Estas relaciones se establecen a través de la herencia, de modo que son relaciones estáticas - fijadas en tiempo de compilación -. Los patrones de objetos tratan con las relaciones entre objetos, que pueden cambiarse en tiempo de ejecución y son más dinámicas".

Al no existir en Go ni clases, ni objetos, ni herencia, la implementación de los patrones se verán muy diferentes. El desafío de esta publicación es respetar el propósito de cada patrón y su posible implementación en Go basándose en las características particulares del lenguaje.

Catálogo de patrones

Los patrones de diseño se catalogan de la siguiente forma:

Según su Propósito:

  • Creacionales: resuelven problemas relativos a la creación de objetos.

  • Estructurales: resuelven problemas relativos a composición de objetos.

  • Comportamiento: resuelven problemas relativos a la interacción de objetos.

Según su Ámbito:

  • Clases: respecto de las relaciones estáticas entre clases.

  • Objetos: respecto de las relaciones dinámicas entre objetos.

Patrones de Clase

Creación

Estructurales

Comportamiento

Factory Method

Adapter

Interpreter

Template Method

Patrones de Objeto

Creación

Estructurales

Comportamiento

Abstract Factory

Adapter

Chain of Responsibility

Builder

Bridge

Command

Propotype

Composite

Iterator

Singleton

Decorator

Mediator

Facade

Memento

Flyweight

Observer

Proxy

State

Strategy

Visitor

¿Cómo se documenta un patrón?

Sección

Detalle

Nombre del patrón y clasificación

El nombre del patrón transmite su esencia. El nombre es vital porque pasa a formar parte de nuestro vocabulario de diseño. Por ejemplo al decir Singleton todos entenderán de que se habla, sin necesidad de explicar el objetivo y los participantes del patrón

Propósito

Es una frase breve que responde a las siguientes cuestiones: ¿Qué hace este patrón de diseño?, ¿En qué se basa? ¿Cuál es el problema concreto de diseño que resuelve?

También conocido como

Son otros nombres, si existen, por los que también se conoce al patrón

Motivación

Un escenario que ilustra un problema de diseño y cómo las estructuras de clases y objetos del patrón resuelven el problema

Aplicabilidad

¿En qué situaciones se puede aplicar el patrón de diseño? ¿Qué ejemplos hay de malos diseños que el patrón puede resolver? ¿Cómo se puede reconocer dichas situaciones?

Estructura

Una representación gráfica de las clases del patrón

Participantes

Las clases y objetos participantes en el patrón de diseño, junto con sus responsabilidades

Colaboradores

Cómo colaboran los participantes para llevar a cabo sus responsabilidades

Consecuencias

¿Cómo consigue el patrón sus objetivos? ¿Cuáles son las ventajas, desventajas y resultados de usar el patrón?

Implementación

¿Cuáles son las dificultades, trucos o técnicas que deberíamos tener en cuenta a la hora de aplicar el patrón? ¿Hay cuestiones específicas del lenguaje?

Código de ejemplo

Fragmentos de código que muestran cómo se puede implementar el patrón

Usos conocidos

Ejemplos del patrón en sistemas reales

Patrones relacionados

¿Qué patrones de diseño están estrechamente relacionados con este? ¿Cuáles son las principales diferencias? ¿Con qué otros patrones debería usarse?

En esta publicación utilizaremos la misma estructura pero con las siguientes observaciones:

  • Se unificará la motivación junto con el código de ejemplo.

  • Se analizarán adicionalmente, solo si corresponden, las alternativas de implementación desde el punto de vista de la concurrencia que caracteriza al lenguaje Go.

  • Se utilizarán códigos de ejemplo en el lenguaje Go.

  • Se utilizará UML en reemplazo de OMT.

Paradójicamente se utilizarán diagramas de clases de UML cuando en Go no existen clases. Sin embargo, al ser UML una de las notaciones más extendidas, considero que la traducción de las clases a tipos de datos de Go no presentará dificultades adicionales al lector.

Implicancias

Extracto de "Patrones de Diseño" - Tabla 1.1 - Patrones de diseño -

Extracto de "Patrones de Diseño" - Tabla 1.1 - Patrones de diseño -

Los autores del libro "Patrones de Diseño" utilizan la siguiente plantilla para especificar un Patrón.

Se reemplazarán los escenarios por ejemplos más simples ya que los del libro están basados en un caso de estudio complejo (creación de un editor de texto) y no pueden ser ejecutados para el aprendizaje del lector. Los escenarios serán triviales y muy simples, la idea es orientar al lector en cómo se implementa el patrón de diseño y no en como resolver un problema puntual. Se utilizarán escenarios de alguno de los siguientes recursos de interés: , , , .

Se omitirá las secciones aplicabilidad, colaboradores, consecuencias, usos conocidos y patrones relacionados ya que no es el objetivo de esta publicación el explicar cada patrón de diseño. Se insta al lector a referirse al libro original para mayor información - .

En las explicaciones de cada patrón de diseño del libro "Patrones de Diseño" utilizan constantemente las palabras objeto y clase. Parte de la comunidad asume que en Go la palabra objeto es válida ya que se interpreta que es sinónimo de un tipo de dato con comportamiento. Sin embargo, a fines de esta publicación cuando se requiera hablar de un objeto utilizaré la frase "variable" (considero que se ajusta más al lenguaje). Para la palabra clase no existe una terminología comparable, por lo que utilizaré simplemente la frase "tipo de dato" o la palabra "tipo". En cuanto a la palabra método, si bien es válida en Go dado que en definitiva los métodos son funciones que reciben un argumento receptor, también utilizaré la frase "comportamiento de un tipo".

Dado que el libro original "Patrones de Diseño" utiliza OMT en lugar de UML, se hará el mayor esfuerzo en respetar la estructura original de cada patrón dado que cada lenguaje permite implementaciones levemente distintas basándose en sus características particulares. Dicho esto se han observado pequeñas alteraciones/concesiones en implementaciones donde se reemplazan clases abstractas por interfaces y viceversa. Este tema es justamente una de las principales diferencias que pueden encontrarse en las implementaciones de un patrón de diseño GoF en Go, por lo que será dificultoso al lector diferenciar si una clase abstracta fue implementada como interface por a) una necesidad exclusiva dada las limitaciones del lenguaje Go en sus características orientadas a objetos; o b) simplemente por una concesión válida entre los desarrolladores de otros lenguajes. Lo invito en esos caso a buscar implementaciones de código en otros lenguajes como Java o C#.

Atención: Esta publicación se encuentra abandonada. Puede acceder a la versión vigente en

[29]
[29]
[29]
[29]
[29]
[29]
[29]
[8]
[40]
[41]
[42]
[29]
[29]
[29]
https://leanpub.com/designpatternsingo