Patrones de diseño
Un patrón de diseño es una solución probada y reutilizable a un problema recurrente en el diseño de software orientado a objetos. Los patrones no son código concreto, sino plantillas que describen cómo estructurar clases y objetos para lograr sistemas flexibles, mantenibles y con bajo acoplamiento. La referencia canónica es el libro Design Patterns: Elements of Reusable Object-Oriented Software (1994), escrito por Erich Gamma, Richard Helm, Ralph Johnson y John Vlissides, conocidos como la GoF (Gang of Four). Este catálogo define 23 patrones organizados en tres categorías (y solo tres): de creación, estructurales y de comportamiento. Términos como "de iteracción", "de administración" o "de interacción" no son categorías válidas de la clasificación GoF.
Patrones de creación (creational)
Su objetivo es inicializar y configurar clases y objetos, abstrayendo el proceso de instanciación para que el cliente no dependa de cómo se crean los objetos. Son cinco: Abstract Factory, Builder, Factory Method, Prototype y Singleton. Una afirmación incorrecta sobre ellos es decir que "definen la forma en que los objetos interactúan entre sí": eso corresponde a los patrones de comportamiento, no a los de creación.
| Patrón | Propósito |
|---|---|
| Singleton | Genera clases de las que se puede instanciar un único objeto, garantizando una sola instancia y un punto de acceso global a ella. Se apoya en métodos y atributos privados y estáticos (constructor privado, método estático de acceso). |
| Factory Method | Define una interfaz para crear un objeto, pero deja que sean las subclases quienes decidan qué clase instanciar. Modela la creación de objetos. |
| Abstract Factory | Proporciona una interfaz para crear familias de objetos relacionados sin que el cliente conozca los detalles de instanciación de las clases concretas de las que depende. |
| Prototype | Crea nuevos objetos clonando una instancia prototípica existente. |
| Builder | Separa la construcción de un objeto complejo de su representación. |
Patrones estructurales (structural)
Su propósito es desacoplar la interfaz y la implementación de clases y objetos, componiendo objetos para formar estructuras mayores. Son siete: Adapter, Bridge, Composite, Decorator, Facade, Flyweight y Proxy. Conviene recordar que Adapter NO es un patrón de creación, sino estructural.
| Patrón | Propósito |
|---|---|
| Adapter (Adaptador) | Convierte la interfaz de una clase en otra distinta que esperan los clientes, permitiendo colaborar a clases con interfaces incompatibles. |
| Bridge (Puente) | Desacopla una abstracción de su implementación para que ambas puedan variar o evolucionar de forma independiente. |
| Composite | Combina objetos en estructuras de árbol para representar jerarquías parte-todo, tratando de forma uniforme objetos individuales y composiciones. |
| Decorator | Añade dinámicamente nuevas responsabilidades a un objeto, ofreciendo una alternativa flexible a la herencia para extender la funcionalidad. Es este patrón (y no Composite) el indicado cuando se quieren añadir responsabilidades a objetos concretos de manera dinámica y transparente sin afectar a otros. |
| Proxy | Proporciona un sustituto o representante de otro objeto para controlar el acceso a él, sin exponer su representación interna. |
| Facade | Ofrece una interfaz unificada de alto nivel para un subsistema de interfaces. |
| Flyweight | Comparte objetos para dar soporte eficiente a grandes cantidades de instancias. |
Patrones de comportamiento (behavioral)
Su objetivo es gestionar las interacciones dinámicas entre sociedades de clases y objetos, es decir, cómo se comunican y reparten responsabilidades. Son once: Chain of Responsibility, Command, Interpreter, Iterator, Mediator, Memento, Observer, State, Strategy, Template Method y Visitor.
| Patrón | Propósito |
|---|---|
| Observer (Observador) | Notifica automáticamente a múltiples objetos los cambios de estado de un sujeto, manteniendo un acoplamiento débil. Adecuado cuando un objeto emite un evento que genera alteraciones en otros objetos. |
| Strategy (Estrategia) | Encapsula una familia de algoritmos y los hace intercambiables en tiempo de ejecución. |
| Command (Comando) | Encapsula una solicitud/acción como un objeto, junto con los parámetros que necesita para ejecutarse. Permite pasarla como parámetro, almacenarla o registrarla, parametrizar las peticiones del cliente y, como ventaja destacada, deshacer (undo) operaciones. |
| Mediator (Mediador) | Define un objeto que encapsula cómo interactúan un conjunto de objetos. Promueve un bajo acoplamiento evitando que los objetos se refieran unos a otros explícitamente, y permite variar su interacción de forma independiente. |
| State (Estado) | Permite que un objeto cambie su comportamiento cuando cambia su estado interno, como si cambiara de clase. |
| Chain of Responsibility | Crea una cadena de objetos receptores para tratar una petición, evitando el acoplamiento entre el emisor y el receptor. |
| Memento | Captura y externaliza el estado interno de un objeto para poder restaurarlo después. |
Principio Abierto-Cerrado (OCP)
Enunciado por Bertrand Meyer, el Principio Abierto-Cerrado establece que las entidades de software deben estar abiertas a la extensión pero cerradas a la modificación. Como criterio práctico de diseño, si al introducir un cambio este impacta a varios módulos de la aplicación, es señal de que la aplicación no está bien diseñada. Los patrones de diseño ayudan a cumplir este principio.
Arquitectura Modelo-Vista-Controlador (MVC)
MVC es un patrón arquitectónico que separa la interfaz de usuario de la lógica de negocio subyacente, dividiendo la aplicación en tres componentes:
-
Modelo: gestiona los datos y la lógica de negocio del sistema; es el modelo (no el controlador) quien gestiona todos los accesos a la información con la que opera el sistema (base de datos, API, etc.).
-
Vista: presenta la información al usuario (renderiza el modelo). La vista NO recibe las peticiones ni solicita los datos al modelo; su papel es la presentación.
-
Controlador: recibe las peticiones del usuario, interactúa con el modelo y selecciona la vista a mostrar. Es el punto de entrada que coordina modelo y vista.
Por tanto, es falso afirmar que "el controlador gestiona todos los accesos a la información" (eso es responsabilidad del modelo) o que "la vista recibe las peticiones y solicita los datos al modelo" (eso corresponde al controlador). Esta separación de responsabilidades mejora la organización, el mantenimiento y la escalabilidad del código.
Fuentes
-
Gamma, Helm, Johnson, Vlissides (Gang of Four), Design Patterns: Elements of Reusable Object-Oriented Software, Addison-Wesley, 1994 (catálogo de 23 patrones y su clasificación).
-
Refactoring.Guru — Catálogo de patrones de diseño: https://refactoring.guru/es/design-patterns/catalog
-
Wikipedia — Model–view–controller: https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller
-
Microsoft Learn — Overview of ASP.NET Core MVC: https://learn.microsoft.com/en-us/aspnet/core/mvc/overview
-
MDN Web Docs — MVC (Glossary): https://developer.mozilla.org/en-US/docs/Glossary/MVC