Hola.
De nuevo ha pasado bastante tiempo desde la última entrada. Intentaremos coger el ritmo de nuevo con una serie de entradas dirigidas a los patrones de diseño. En esta primera entrada se comentará qué es un patrón de diseño y para qué pueden usarse. Además, se añadirán enlaces a las futuras entradas de cada patrón para una navegación más sencilla. ¡Comenzamos!
¿Qué es un patrón de diseño?
Esta es la primera pregunta que debemos hacernos y quizás la más importante. Para saber usar una herramienta lo mejor es saber qué es y para qué sirve antes incluso de pensar en posibles utilidades de la misma. Al final los patrones de diseño no son más que otra herramienta más que tenemos a nuestra disposición a la hora de enfrentarnos a un problema.
Pues bien, un patrón de diseño es una solución a un tipo de problema conocido y que es frecuente. A veces, en la programación orientada a objetos, nos enfrentamos a problemas que en su forma más básica ya han sido resueltos por otros programadores. ¿No sería genial usar esa solución que está probada en nuestro beneficio? La idea, al final, es reutilizar ese "código" para resolver nuestro problema. Ahorra tiempo y esfuerzo. Así de sencillo.
¿Qué patrón de diseño usar?
Claro, para saber si existe un patrón de diseño que soluciona un problema concreto, lo primero que se debe hacer es comprender la descripción de dicho problema y compararla con los patrones que conozcas. Eso obliga a saber, al menos, la utilidad de cada uno de los patrones de diseño existentes. Con esto en mente, solo resta ver qué patrones (o patrones) se acercan más al problema propuesto.
Tras seleccionar el patrón, el siguiente paso es renombrar cada una de las partes de este al caso concreto que se está tratando. Se debe tener en cuenta que la estructura del problema puede no coincidir exactamente con la del patrón. A veces existen diferentes restricciones de la aplicación que el patrón genérico no posee. Es posible modificarla estructura y las relaciones entre los objetos todo lo necesario. Un patrón es una guía, no una regla.
¿Cómo se organizan los patrones de diseño?
Los diferentes patrones de diseño se pueden organizar en tres categorías en función de su uso: construcción, composición y comportamiento.
- Construcción: Tienen como objetivo organizar la creación de objetos
- Estructuración: Su propósito es facilitar la organización de la jerarquía de clases y las relaciones entre ellas
- Comportamiento: Permiten organizar las interacciones y repartir el procesamiento entre los distintos objetos
Esta primera organización, nos ayudará pre-filtrar los patrones en función del propósito de nuestro caso.
Catálogo de patrones de diseño
Existen un total de 23 patrones de diseño organizados en las tres categorías antes indicadas. A continuación se indica una pequeña descripción para cada uno de los patrones que indica su posible utilidad.
Construcción
- Abstract Factory: tiene como objetivo la creación de objetos reagrupados en
familias sin tener que conocer las clases concretas destinadas a la creación de
estos objetos.
- Builder: permite separar la construcción de objetos complejos de su
implementación de modo que un cliente pueda crear estos objetos complejos con
implementaciones diferentes.
- Factory Method: presenta un método abstracto para la
creación de un objeto reportando a las subclases la creación efectiva de la instancia.
- Prototype: permite crear nuevos objetos por duplicación de objetos existentes
llamados prototipos que disponen de la capacidad de ser clonados.
- Singleton: permite asegurar que de una clase existe una única
instancia y proporciona un método único que la devuelve.
Estructuración
- Adapter: tiene como objetivo convertir la interfaz de una clase existente en la
interfaz esperada por los clientes también existentes para que puedan trabajar de
forma conjunta.
- Bridge: tiene como objetivo separar los aspectos conceptuales de una jerarquía
de clases de su implementación.
- Composite: proporciona un marco de diseño de una composición de objetos con
una profundidad de composición variable, basando el diseño en un árbol.
- Decorator: permite agregar dinámicamente funcionalidades suplementarias a un
objeto.
- Facade: tiene como objetivo reagrupar las interfaces de un conjunto de objetos
en una interfaz unificada que resulte más fácil de utilizar.
- Flyweight: facilita la compartición de un conjunto importante de objetos con
granularidad muy fina.
- Proxy: construye un objeto que se substituye por otro objeto y que controla su
acceso.
Comportamiento
- Chain of responsibility: crea una cadena de objetos tal que si un objeto de la
cadena no puede responder a una petición, la pueda transmitir a sus sucesores
hasta que uno de ellos responda.
- Command: tiene como objetivo transformar una consulta en un objeto,
facilitando operaciones como la anulación, la actualización de consultas y su
seguimiento.
- Interpreter: proporciona un marco para dar una representación mediante
objetos de la gramática de un lenguaje con el objetivo de evaluar,
interpretándolas, expresiones escritas en este lenguaje.
- Iterator: proporciona un acceso secuencial a una colección de objetos sin que
los clientes se preocupen de la implementación de esta colección.
- Mediator: construye un objeto cuya vocación es la gestión y el control de las
interacciones en el seno de un conjunto de objetos sin que estos elementos se
conozcan mutuamente.
- Memento: salvaguarda y restaura el estado de un objeto.
- Observer: construye una dependencia entre un sujeto y sus observadores de
modo que cada modificación del sujeto sea notificada a los observadores para
que puedan actualizar su estado.
- State: permite a un objeto adaptar su comportamiento en función de su estado
interno.
- Strategy: adapta el comportamiento y los algoritmos de un objeto en función de
una necesidad concreta sin por ello cargar las interacciones con los clientes de
este objeto.
- Template Method: permite reportar en las subclases ciertas etapas de una de las
operaciones de un objeto, estando éstas descritas en las subclases.
- Visitor: construye una operación a realizar en los elementos de un conjunto de
objetos. Es posible agregar nuevas operaciones sin modificar las clases de estos
objetos.
Muchas gracias por leerme,
Lázarus Surazal.