En el mundo del desarrollo de software, los patrones de diseño se clasifican en tres categorías principales: creacionales, estructurales y de comportamiento. Cada una de estas categorías aborda diferentes aspectos del diseño de software y proporciona soluciones específicas a problemas comunes. A continuación, exploraremos cada una de estas categorías en detalle.
- Patrones Creacionales
Los patrones creacionales se centran en la forma en que se crean los objetos. Estos patrones ayudan a hacer que el sistema sea independiente de cómo se crean, componen y representan los objetos. Los patrones creacionales más comunes son:
- Singleton: Garantiza que una clase tenga una única instancia y proporciona un punto de acceso global a ella.
- 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, permitiendo que el mismo proceso de construcción cree diferentes representaciones.
- Prototype: Permite crear nuevos objetos copiando una instancia existente, conocida como prototipo.
Ejemplo de Singleton en Java
public class Singleton { private static Singleton instance; private Singleton() { // Constructor privado para evitar instanciación externa } public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
- Patrones Estructurales
Los patrones estructurales se ocupan de la composición de clases y objetos para formar estructuras más grandes. Estos patrones ayudan a garantizar que si una parte de un sistema cambia, el impacto en otras partes sea mínimo. Los patrones estructurales más comunes son:
- Adapter: Permite que clases con interfaces incompatibles trabajen juntas.
- Bridge: Desacopla una abstracción de su implementación para que ambas puedan variar independientemente.
- Composite: Permite tratar a los objetos individuales y a las composiciones de objetos de manera uniforme.
- Decorator: Añade responsabilidades adicionales a un objeto de manera dinámica.
- Facade: Proporciona una interfaz simplificada a un conjunto de interfaces en un subsistema.
- Flyweight: Utiliza el almacenamiento compartido para soportar eficientemente un gran número de objetos de grano fino.
- Proxy: Proporciona un sustituto o marcador de posición para otro objeto para controlar el acceso a él.
Ejemplo de Adapter en Java
// Interfaz objetivo public interface Target { void request(); } // Clase existente que necesita ser adaptada public class Adaptee { public void specificRequest() { System.out.println("Llamada específica"); } } // Adaptador que hace que Adaptee sea compatible con Target public class Adapter implements Target { private Adaptee adaptee; public Adapter(Adaptee adaptee) { this.adaptee = adaptee; } @Override public void request() { adaptee.specificRequest(); } }
- Patrones de Comportamiento
Los patrones de comportamiento se centran en la interacción y responsabilidad entre los objetos. Estos patrones ayudan a definir cómo los objetos se comunican entre sí. Los patrones de comportamiento más comunes son:
- Chain of Responsibility: Permite que varios objetos manejen una solicitud, pasando la solicitud a lo largo de una cadena de manejadores.
- Command: Encapsula una solicitud como un objeto, permitiendo parametrizar a los clientes con diferentes solicitudes, colas o registros de solicitudes.
- Interpreter: Dada un lenguaje, define una representación para su gramática junto con 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 violar 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 para que cuando un objeto cambie de estado, todos sus dependientes sean 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 una operación, diferiendo algunos pasos a las subclases.
- Visitor: Representa una operación que se va a realizar en los elementos de una estructura de objetos.
Ejemplo de Observer en Java
import java.util.ArrayList; import java.util.List; // Interfaz de observador interface Observer { void update(String message); } // Clase sujeto class Subject { private List<Observer> observers = new ArrayList<>(); public void addObserver(Observer observer) { observers.add(observer); } public void removeObserver(Observer observer) { observers.remove(observer); } public void notifyObservers(String message) { for (Observer observer : observers) { observer.update(message); } } } // Implementación de un observador class ConcreteObserver implements Observer { private String name; public ConcreteObserver(String name) { this.name = name; } @Override public void update(String message) { System.out.println(name + " recibió el mensaje: " + message); } } // Uso del patrón Observer public class ObserverPatternDemo { public static void main(String[] args) { Subject subject = new Subject(); Observer observer1 = new ConcreteObserver("Observador 1"); Observer observer2 = new ConcreteObserver("Observador 2"); subject.addObserver(observer1); subject.addObserver(observer2); subject.notifyObservers("Hola Observadores!"); } }
Conclusión
En esta sección, hemos explorado las tres categorías principales de patrones de diseño: creacionales, estructurales y de comportamiento. Cada categoría aborda diferentes aspectos del diseño de software y proporciona soluciones específicas a problemas comunes. Comprender estas categorías y los patrones individuales dentro de ellas es fundamental para aplicar patrones de diseño de manera efectiva en el desarrollo de software. En los próximos módulos, profundizaremos en cada uno de estos patrones con ejemplos prácticos y ejercicios para reforzar el aprendizaje.
Curso de Patrones de Diseño de Software
Módulo 1: Introducción a los Patrones de Diseño
- ¿Qué son los Patrones de Diseño?
- Historia y Origen de los Patrones de Diseño
- Clasificación de los Patrones de Diseño
- Ventajas y Desventajas de Usar Patrones de Diseño
Módulo 2: Patrones Creacionales
- Introducción a los Patrones Creacionales
- Singleton
- Factory Method
- Abstract Factory
- Builder
- Prototype
Módulo 3: Patrones Estructurales
Módulo 4: Patrones de Comportamiento
- Introducción a los Patrones de Comportamiento
- Chain of Responsibility
- Command
- Interpreter
- Iterator
- Mediator
- Memento
- Observer
- State
- Strategy
- Template Method
- Visitor
Módulo 5: Aplicación de Patrones de Diseño
- Cómo Seleccionar el Patrón Adecuado
- Ejemplos Prácticos de Uso de Patrones
- Patrones de Diseño en Proyectos Reales
- Refactorización Usando Patrones de Diseño
Módulo 6: Patrones de Diseño Avanzados
- Patrones de Diseño en Arquitecturas Modernas
- Patrones de Diseño en Microservicios
- Patrones de Diseño en Sistemas Distribuidos
- Patrones de Diseño en Desarrollo Ágil