Los patrones de diseño de Gang of Four (GoF) se categorizan en tres grupos principales, cada uno dirigido a un conjunto específico de desafíos dentro del diseño de software. Aquí te presento una tabla en Markdown que resume estas categorías, los patrones incluidos en cada una, y una breve descripción de lo que cada patrón busca resolver:
Los patrones de diseño se clasifican generalmente en tres categorías principales:
- Creacionales: Proporcionan mecanismos para crear objetos, aumentando la flexibilidad y la reusabilidad del código.
- Estructurales: Introducen formas de componer objetos y clases en estructuras más grandes, manteniendo la flexibilidad y eficiencia de la estructura.
- Comportamiento: Se centran en la comunicación eficiente y la asignación de responsabilidades entre objetos.
Categoría | Patrón | Descripción |
---|---|---|
Creacionales | Factory Method | Define una interfaz para crear un objeto, pero deja que las subclases decidan qué clase instanciar. |
Abstract Factory | Proporciona una interfaz para crear familias de objetos relacionados o dependientes sin especificar sus clases concretas. | |
Builder | Separa la construcción de un objeto complejo de su representación, de modo que el mismo proceso de construcción puede crear diferentes representaciones. | |
Prototype | Crea objetos basándose en un prototipo de objeto a través de clonación. | |
Singleton | Asegura que una clase tenga solo una instancia y proporciona un punto de acceso global a ella. | |
Estructurales | Adapter (o Wrapper) | Permite que interfaces incompatibles colaboren. |
Bridge | Desacopla una abstracción de su implementación, de modo que las dos puedan variar independientemente. | |
Composite | Compone objetos en estructuras de árbol para representar jerarquías de parte-todo. | |
Decorator | Añade responsabilidades adicionales a un objeto de manera dinámica. | |
Facade | Proporciona una interfaz unificada a un conjunto de interfaces en un subsistema. | |
Flyweight | Minimiza el uso de la memoria o los costos computacionales compartiendo tanto como sea posible con objetos similares. | |
Proxy | Proporciona un sustituto o marcador de posición para otro objeto para controlar el acceso a este. | |
Comportamiento | Chain of Responsibility | Pasa la solicitud a lo largo de una cadena de manejadores potenciales hasta que uno de ellos maneja la solicitud. |
Command | Encapsula una solicitud como un objeto, permitiendo así parametrizar a los clientes con colas, solicitudes y operaciones. | |
Interpreter | Define una representación gramatical para un lenguaje y un intérprete que usa la representación para interpretar oraciones en el lenguaje. | |
Iterator | Proporciona una forma de acceder secuencialmente a los elementos de un objeto agregado sin exponer su representación subyacente. | |
Mediator | Define un objeto que encapsula cómo un conjunto de objetos interactúa. | |
Memento | Sin afectar la encapsulación, captura y externaliza el estado interno de un objeto para que el objeto pueda ser restaurado a este estado más tarde. | |
Observer | Define una dependencia de uno a muchos entre objetos de modo que cuando un objeto cambia de estado, todos sus dependientes son notificados y actualizados automáticamente. | |
State | Permite a un objeto alterar su comportamiento cuando su estado interno cambia. | |
Strategy | Define una familia de algoritmos, encapsula cada uno y los hace intercambiables. | |
Template Method | Define el esqueleto de un algoritmo en la superclase pero permite que las subclases sobrescriban pasos específicos del algoritmo sin cambiar su estructura. | |
Visitor | Representa una operación que se va a realizar en los elementos de una estructura de objetos. Permite definir una nueva operación sin cambiar los clases de los elementos sobre los que opera. |
Para ilustrar el patrón de diseño Factory Method con un ejemplo sencillo, consideremos una aplicación que necesita generar diferentes tipos de documentos. Tenemos una clase abstracta DocumentCreator que declara el método createDocument(), y varias clases concretas que implementan este método para instanciar diferentes tipos de documentos, como Resume y Report.
Aquí tienes un diagrama de clase del patrón Factory Method aplicado a este escenario, utilizando la sintaxis de Mermaid:
classDiagram
class DocumentCreator {
<<abstract>>
+createDocument() Document
}
class ResumeCreator {
+createDocument() Document
}
class ReportCreator {
+createDocument() Document
}
class Document {
<<abstract>>
+type: string
+open()
+save()
}
class Resume extends Document {
+type = "Resume"
+open()
+save()
}
class Report extends Document {
+type = "Report"
+open()
+save()
}
DocumentCreator <|-- ResumeCreator
DocumentCreator <|-- ReportCreator
Document <|-- Resume
Document <|-- Report
DocumentCreator --> Document : Creates
-
DocumentCreator: Es una clase abstracta con el método abstracto
createDocument()
. Actúa como el "creador" en el patrón Factory Method. No sabe de antemano qué clase concreta de documento necesitará crear. -
ResumeCreator y ReportCreator: Son clases concretas que heredan de
DocumentCreator
. Cada una implementa el métodocreateDocument()
para instanciar un tipo específico deDocument
(Resume
oReport
, respectivamente). -
Document: Es una clase abstracta que define la interfaz de los objetos que serán creados. En este caso, tiene propiedades y métodos comunes para los documentos, como
type
,open()
, ysave()
. -
Resume y Report: Son clases concretas que extienden la clase
Document
, representando tipos específicos de documentos. Cada una sobrescribe los métodos según sus necesidades.
Este ejemplo ilustra cómo el patrón Factory Method permite flexibilidad en la creación de objetos. Dependiendo de la instancia de DocumentCreator
utilizada (ResumeCreator
o ReportCreator
), el método createDocument()
produce diferentes tipos de objetos Document
, permitiendo que el código cliente trabaje con una interfaz común sin preocuparse por los detalles de creación de los objetos concretos.
Imagina que estás construyendo un software para gestionar vehículos en diferentes regiones, donde cada región tiene su propia versión de coches y bicicletas. Utilizamos el patrón Abstract Factory para abstraer la creación de estos vehículos según la región.
La estructura básica del patrón Abstract Factory incluye las siguientes partes:
AbstractFactory: Declara un conjunto de métodos para crear cada uno de los objetos abstractos. ConcreteFactory: Implementa los métodos de creación para producir objetos concretos. AbstractProduct: Declara una interfaz para un tipo de objeto de producto. ConcreteProduct: Implementa la interfaz AbstractProduct para crear un producto específico. Aquí tienes el diagrama de clases representando este ejemplo:
classDiagram
class AbstractFactory {
<<interface>>
+createCar() Car
+createBike() Bike
}
class AmericanFactory {
+createCar() Car
+createBike() Bike
}
class EuropeanFactory {
+createCar() Car
+createBike() Bike
}
class Car {
<<interface>>
+type()
}
class AmericanCar {
+type()
}
class EuropeanCar {
+type()
}
class Bike {
<<interface>>
+type()
}
class AmericanBike {
+type()
}
class EuropeanBike {
+type()
}
AbstractFactory <|-- AmericanFactory
AbstractFactory <|-- EuropeanFactory
Car <|-- AmericanCar
Car <|-- EuropeanCar
Bike <|-- AmericanBike
Bike <|-- EuropeanBike
AmericanFactory -- AmericanCar : creates >
AmericanFactory -- AmericanBike : creates >
EuropeanFactory -- EuropeanCar : creates >
EuropeanFactory -- EuropeanBike : creates >
Explicación del ejemplo:
- AbstractFactory: Una interfaz
AbstractFactory
que define dos métodos:createCar
ycreateBike
, para crear objetos de tipoCar
yBike
. - ConcreteFactory:
AmericanFactory
yEuropeanFactory
son las fábricas concretas que implementan la interfazAbstractFactory
para crear objetosCar
yBike
específicos de América y Europa, respectivamente. - AbstractProduct: Las interfaces
Car
yBike
actúan como productos abstractos con métodos comotype
que serán implementados por los productos concretos. - ConcreteProduct:
AmericanCar
,EuropeanCar
,AmericanBike
, yEuropeanBike
son los productos concretos que implementan las interfaces de productos abstractos.
El patrón de diseño Builder se utiliza para permitir la creación de una variedad de objetos complejos a partir de un objeto fuente. El patrón de diseño Builder encapsula la construcción de un producto y permite que se construya paso a paso. Esto es particularmente útil cuando un objeto necesita ser creado con muchas opciones posibles y no todas son requeridas.
Ejemplo Sencillo: Construyendo una Pizza Imagina que estás construyendo un sistema para una pizzería que permite a los clientes personalizar sus pedidos de pizza. Cada pizza puede tener diferentes ingredientes, tipo de masa, tamaño, y condimentos. Usar el patrón Builder nos permite abstraer el proceso de construcción de una pizza en pasos, facilitando la adición de variaciones sin complicar el código del cliente.
classDiagram
class PizzaBuilder {
-dough: String
-sauce: String
-topping: String
+setDough(dough: String): void
+setSauce(sauce: String): void
+setTopping(topping: String): void
+build(): Pizza
}
class HawaiianPizzaBuilder {
+setDough()
+setSauce()
+setTopping()
}
class SpicyPizzaBuilder {
+setDough()
+setSauce()
+setTopping()
}
class Pizza {
-dough: String
-sauce: String
-topping: String
}
PizzaBuilder <|-- HawaiianPizzaBuilder
PizzaBuilder <|-- SpicyPizzaBuilder
PizzaBuilder --> Pizza : builds
-
PizzaBuilder: Esta es la clase abstracta o interfaz que define todos los pasos necesarios para construir una pizza. Los métodos
setDough
,setSauce
, ysetTopping
son usados para especificar los ingredientes, y el métodobuild
finaliza la construcción y devuelve el producto final. -
HawaiianPizzaBuilder y SpicyPizzaBuilder: Estas clases concretas implementan los pasos definidos por
PizzaBuilder
para construir variantes específicas de pizzas, como la pizza hawaiana y la pizza picante, respectivamente. -
Pizza: Esta es la clase de producto que se construye utilizando el patrón Builder. Contiene propiedades como
dough
,sauce
, ytopping
, que se configuran a través del proceso de construcción.
DIAGRAMA DE CLASE
CSharp
En el lenguaje C#, existen diversos patrones de diseño estructural que son fundamentales para el desarrollo de software. Estos patrones incluyen: