{"id":13553001,"url":"https://github.com/alxgcrz/_design-patterns_","last_synced_at":"2025-04-03T04:31:45.152Z","repository":{"id":203288568,"uuid":"359192857","full_name":"alxgcrz/_design-patterns_","owner":"alxgcrz","description":"Apuntes sobre patrones de diseño en el desarrollo de software","archived":false,"fork":false,"pushed_at":"2024-09-18T14:49:43.000Z","size":11002,"stargazers_count":13,"open_issues_count":0,"forks_count":4,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-11-04T00:32:47.594Z","etag":null,"topics":["design-patterns","java","learning"],"latest_commit_sha":null,"homepage":"https://alxgcrz.com/patrones.html","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"cc-by-sa-4.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alxgcrz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-04-18T16:13:03.000Z","updated_at":"2024-09-18T14:49:48.000Z","dependencies_parsed_at":null,"dependency_job_id":"2c239242-39f6-4f6a-988b-24293caaf64d","html_url":"https://github.com/alxgcrz/_design-patterns_","commit_stats":null,"previous_names":["alxgcrz/_design-patterns_"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alxgcrz%2F_design-patterns_","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alxgcrz%2F_design-patterns_/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alxgcrz%2F_design-patterns_/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alxgcrz%2F_design-patterns_/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alxgcrz","download_url":"https://codeload.github.com/alxgcrz/_design-patterns_/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246939195,"owners_count":20857916,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["design-patterns","java","learning"],"created_at":"2024-08-01T12:02:15.286Z","updated_at":"2025-04-03T04:31:40.562Z","avatar_url":"https://github.com/alxgcrz.png","language":"Java","funding_links":[],"categories":["Java"],"sub_categories":[],"readme":"# Patrones de diseño en Java\n\n## Introducción\n\nLos patrones de diseño son **técnicas que permiten resolver problemas comunes en el desarrollo de software** y en otros ámbitos referentes al diseño de interacción o interfaces.\n\nLos patrones de diseño pretenden:\n\n- Proporcionar catálogos de elementos reusables en el diseño de sistemas software.\n- Evitar la reiteración en la búsqueda de soluciones a problemas ya conocidos y solucionados anteriormente.\n- Formalizar un vocabulario común entre diseñadores.\n- Estandarizar el modo en que se realiza el diseño.\n- Facilitar el aprendizaje de las nuevas generaciones de diseñadores condensando conocimiento ya existente.\n\nAsimismo, no pretenden:\n\n- Imponer ciertas alternativas de diseño frente a otras.\n- Eliminar la creatividad inherente al proceso de diseño.\n\nPor tanto no es obligatorio utilizar los patrones. Sólo es aconsejable en el caso de detectar el mismo problema o uno similar para el cual existe un patrón que proporciona una solución probada, siempre teniendo en cuenta que en un caso particular puede no ser aplicable. Abusar o forzar el uso de los patrones puede ser contraproducente.\n\n- \u003chttps://www.geeksforgeeks.org/software-design-patterns/\u003e\n- \u003chttps://www.geeksforgeeks.org/java-design-patterns\u003e\n\n---\n\n## _\"Behavioral Patterns\"_\n\nLos patrones de comportamiento se definen como patrones de diseño de software que ofrecen soluciones respecto a la interacción y responsabilidades entre clases y objetos, así como los algoritmos que encapsulan.\n\nLos patrones de comportamiento son [**_Chain of Responsibility_**](#chain-of-responsibility-pattern), [**_Command_**](#command-pattern), [**_Interpreter_**](#interpreter-pattern), [**_Iterator_**](#iterator-pattern), [**_Mediator_**](#mediator-pattern), [**_Memento_**](#memento-pattern), [**_Observer_**](#observer-pattern), [**_State_**](#state-pattern), [**_Strategy_**](#strategy-pattern), [**_Template Method_**](#template-method-pattern) y [**_Visitor_**](#visitor-pattern).\n\n- \u003chttps://www.baeldung.com/java-behavioral-patterns-jdk\u003e\n\n### _\"Chain of Responsibility Pattern\"_\n\n\u003c!-- markdownlint-disable MD033 --\u003e\n\u003cdiv style=\"text-align: center;\"\u003e\n  \u003cimg src=\".//media//patterns//behavioral//chain-of-responsibility/chain-of-responsibility_header.png\" alt=\"chain-of-responsibility_pattern_intro\" width=\"475\" height=\"auto\"\u003e\n  \u003cp style=\"font-size: 0.75em;\"\u003e\u0026#169; Refactoring Guru\u003c/p\u003e\n\u003c/div\u003e\n\u003c!-- markdownlint-disable MD033 --\u003e\n\n\u003e **_Evite acoplar el remitente de una solicitud a su receptor dándole a más de un objeto la oportunidad de manejar la solicitud. Encadene los objetos receptores y pase la solicitud a lo largo de la cadena hasta que un objeto la maneje._**\n\u003e\n\u003e _-- GoF_\n\n#### Concepto\n\nEste patrón evita acoplar el emisor de una petición a su receptor dando a más de un objeto la posibilidad de responder a una petición. Para ello, se encadenan los receptores y se pasa la petición a través de la cadena hasta que es procesada por algún objeto.\n\n\u003c!-- markdownlint-disable MD033 --\u003e\n\u003cdiv style=\"text-align: center;\"\u003e\n  \u003cimg src=\".//media//patterns//behavioral//chain-of-responsibility/chain-of-responsibility_concept.png\" alt=\"chain-of-responsibility_pattern_concept\" width=\"500\" height=\"auto\"\u003e\n  \u003cp style=\"font-size: 0.75em;\"\u003e\u0026#169; Refactoring Guru\u003c/p\u003e\n\u003c/div\u003e\n\u003c!-- markdownlint-disable MD033 --\u003e\n\nEste patrón puede aplicarse cuando:\n\n- hay más de un objeto que puede manejar una petición, y el manejador no se conoce a priori, sino que debería determinarse automáticamente.\n\n- se quiere enviar una petición a un objeto entre varios sin especificar explícitamente el receptor.\n\n- el conjunto de objetos que pueden tratar una petición debería ser especificado dinámicamente.\n\nCon este patrón se **reduce el acoplamiento**. El patrón libera a un objeto de tener que saber qué otro objeto maneja una petición. Ni el receptor ni el emisor se conocen explícitamente entre ellos, y un objeto de la cadena tampoco tiene que conocer la estructura de ésta. Por lo tanto, simplifica las interconexiones entre objetos. En vez de que los objetos mantengan referencias a todos los posibles receptores, sólo tienen una única referencia a su sucesor.\n\nAdemás, **añade flexibilidad para asignar responsabilidades a objetos**. Se pueden añadir o cambiar responsabilidades entre objetos para tratar una petición modificando la cadena de ejecución en tiempo de ejecución. Esto se puede combinar con la herencia para especializar los manejadores estáticamente.\n\nPor otra parte presenta el inconveniente de **no garantizar la recepción**. Dado que las peticiones no tienen un receptor explícito, no hay garantías de que sean manejadas. La petición puede alcanzar el final de la cadena sin haber sido procesada.\n\n#### Caso práctico\n\nEn este patrón participan:\n\n- **Manejador**: define una interfaz para tratar las peticiones. Opcionalmente, implementa el enlace al sucesor.\n\n- **ManejadorConcreto**: trata las peticiones de las que es responsable; si puede manejar la petición, lo hace; en caso contrario la reenvía a su sucesor.\n\n- **Cliente**: inicializa la petición a un manejador concreto de la cadena.\n\n```java\nabstract class Manejador {\n    Manejador sucesor;\n\n    void setSucesor(Manejador sucesor) {\n        this.sucesor = sucesor;\n    }\n\n    abstract void manejarPeticion(Peticion peticion);\n}\n\nclass ManejadorConcreto1 extends Manejador {\n    @Override\n    public void manejarPeticion(Peticion peticion) {\n        if (peticion.getValue() \u003c 0) {\n            System.out.println(\"Los valores negativos son manejados por \" + getClass().getSimpleName());\n            System.out.println(\"Valores peticion : \" + peticion.getDescripcion() + peticion.getValue());\n        } else {\n            sucesor.manejarPeticion(peticion);\n        }\n    }\n\n}\n\nclass ManejadorConcreto2 extends Manejador {\n    @Override\n    public void manejarPeticion(Peticion peticion) {\n        if (peticion.getValue() \u003e= 0) {\n            System.out.println(\"Los valores mayores que 0 son manejados por \" + getClass().getSimpleName());\n            System.out.println(\"Valores peticion : \" + peticion.getDescripcion() + peticion.getValue());\n        } else {\n            sucesor.manejarPeticion(peticion);\n        }\n    }\n}\n\nclass Peticion {\n    private int value;\n    private String descripcion;\n\n    Peticion(String descripcion, int value) {\n        this.value = value;\n        this.descripcion = descripcion;\n    }\n\n    int getValue() {\n        return value;\n    }\n\n    String getDescripcion() {\n        return descripcion;\n    }\n}\n```\n\n#### Consideraciones\n\nAplicar el patrón cuando se espera que su programa **procese diferentes tipos de solicitudes de varias maneras**, pero los tipos exactos de solicitudes y sus secuencias son desconocidos de antemano. El patrón le permite vincular varios manejadores en una cadena y, al recibir una solicitud, \"preguntar\" a cada manejador si puede procesarlo. De esta manera todos los manejadores tienen la oportunidad de procesar la solicitud.\n\nTambién se debería aplicar cuando sea esencial ejecutar varios manejadores en un orden particular. Como los manejadores de la cadena pueden vincularse en cualquier orden, todas las solicitudes pasarán a través de la cadena exactamente como deben hacerlo.\n\nPor úlimo, cuando el conjunto de manejadores y su orden deban cambiar en el tiempo de ejecución también se debería aplicar este patrón. Si se proporcionan _'setters'_ para un campo de referencia dentro de las clases de manejadores, podrá insertar, eliminar o ordenar los manejadores dinámicamente.\n\n#### Referencias\n\n- \u003chttps://refactoring.guru/es/design-patterns/chain-of-responsibility\u003e\n- \u003chttps://sourcemaking.com/design_patterns/chain_of_responsibility\u003e\n- \u003chttps://www.baeldung.com/chain-of-responsibility-pattern\u003e\n- \u003chttps://www.tutorialspoint.com/design_pattern/chain_of_responsibility_pattern\u003e\n- \u003chttps://www.digitalocean.com/community/tutorials/chain-of-responsibility-design-pattern-in-java\u003e\n- \u003chttps://java-design-patterns.com/es/patterns/chain-of-responsibility/\u003e\n\n---\n\n### _\"Command Pattern\"_\n\n\u003c!-- markdownlint-disable MD033 --\u003e\n\u003cdiv style=\"text-align: center;\"\u003e\n  \u003cimg src=\".//media//patterns//behavioral//command//command_header.png\" alt=\"command_pattern_intro\" width=\"475\" height=\"auto\"\u003e\n  \u003cp style=\"font-size: 0.75em;\"\u003e\u0026#169; Refactoring Guru\u003c/p\u003e\n\u003c/div\u003e\n\u003c!-- markdownlint-disable MD033 --\u003e\n\n#### Concepto\n\n\u003e **_Encapsule una solicitud como un objeto, lo que le permite parametrizar a los clientes con diferentes solicitudes, solicitudes de cola o registro y admite operaciones que no se pueden deshacer._**\n\u003e\n\u003e _-- GoF_\n\nEl **_'Command Pattern'_** permite solicitar una operación a un objeto sin conocer realmente el contenido de esta operación ni el receptor real de la misma. Para ello se encapsula la petición como un objeto, con lo que además facilita la parametrización de los métodos.\n\nEn general, se asocian cuatro términos: **invocador**, **cliente**, **comando** y **receptor**.\n\nEl objeto **cliente** crea y contiene el objeto invocador y los objetos de comando asociados con el receptor. El cliente decide cuál de estos comandos debe ejecutar en un momento determinado, como por ejemplo como respuesta a un botón pulsado en la UI. En ese momento, el cliente pasa el objeto de comando concreto al invocador para ejecutar la acción en el receptor asociada a ese comando.\n\nUn **invocador** solo conoce la interfaz de comandos, pero desconoce totalmente los comandos concretos. El invocador recibe la orden de ejecución y el comando a ejecutar e invoca el método del comando.\n\nUn objeto de **comando** es capaz de llamar a un método particular en el receptor. La lógica de la acción a ejecutar está definida en el método en el **receptor** que es invocado por el **comando**.\n\nEl uso del **_'Command Pattern'_** puede ser productivo en aquellas situaciones y escenarios en las que la relación directa entre el emisor de una orden y el receptor de la misma es insuficiente:\n\n- La invocación directa afecta sólo a emisor y receptor por lo que resulta complicado ampliar dicha relación a otros actores, como por ejemplo barras de progreso, ayuda contextual, etc...\n\n- A veces es necesario un modelo de ejecución transaccional (al igual que en las bases de datos) en las que es necesario que se ejecuten todas las órdenes o si en caso de que alguna falle o no sea posible ejecutar, se deshagan todas las órdenes relacionadas y se mantenga o restaure el estado anterior.\n\n- En las aplicaciones multi-hilo, este patrón es un método sencillo para desacoplar productores y receptores de órdenes, dado que los productores y receptores pueden estar en diferentes hilos.\n\n- En los juegos en red mayormente se necesitan ejecutar órdenes en todos los dispositivos participantes. Este patrón facilita la serialización de las órdenes ya que sólo hay que serializar los objetos que las representan.\n\n- Muchos juegos añaden algún tipo de consola para interactuar directamente con el motor del juego empleando un intérprete de comandos. Mediante este patrón, se pueden sintetizar las órdenes como si hubieran sido producidas por el propio motor, facilitando la prueba y su depuración.\n\n- En el uso de macros también se hace necesario el uso de este patrón.\n\n- En el caso de los asistentes o _'wizards'_ este patrón permite desacoplar el interfaz de usuario de las órdenes ya que una vez configurada la secuencia y tipo de órdenes desde el asistente, cuando el usuario las acepta  es cuando se emite el mensaje y se ejecutan dichas órdenes.\n\n#### Caso práctico\n\n```java\ninterface ICommand {\n    void action();\n}\n\n// Command\nclass Redo implements ICommand {\n    private Receiver receiver;\n\n    public Redo(Receiver recv) {\n        receiver = recv;\n    }\n\n    @Override\n    public void action() {\n        // Invoca la acción en el receptor\n        receiver.performRedo();\n    }\n}\n\n// El receptor contiene la lógica a ejecutar\nclass Receiver {\n    void performUndo() {\n        System.out.println(\"Executing - Undo\");\n    }\n\n    void performRedo() {\n        System.out.println(\"Executing - Redo\");\n    }\n}\n\n// Un invocador sólo conoce la interfaz de comandos\nclass Invoker {\n    public void execute(ICommand cmd) {\n        cmd.action();\n    }\n}\n```\n\n#### Consideraciones\n\nComo se ha comentado, este patrón desacopla el objeto que invoca la operación del objeto que sabe realizarla.\n\nLas órdenes son objetos y por tanto pueden ser manipulados y extendidos como cualquier otro objeto. Además, permite que sean gestionados en colas de objetos o mantener un registro de mensajes.\n\nLas órdenes pueden incluir transacciones para garantizar la consistencia y estado de los objetos. Por tanto, existe la posibilidad de restaurar estados anteriores.\n\nAl usar objetos se facilita el uso de parámetros a la hora de ejecutar las órdenes.\n\nEste patrón es ampliamente utilizado para operaciones de deshacer/rehacer.\n\nUna función de devolución de llamada se puede diseñar con este patrón.\n\n#### Referencias\n\n- \u003chttps://refactoring.guru/es/design-patterns/command\u003e\n- \u003chttps://sourcemaking.com/design_patterns/command\u003e\n- \u003chttps://www.baeldung.com/java-command-pattern\u003e\n- \u003chttps://www.tutorialspoint.com/design_pattern/command_pattern\u003e\n- \u003chttps://www.digitalocean.com/community/tutorials/command-design-pattern\u003e\n- \u003chttps://java-design-patterns.com/es/patterns/command\u003e\n- \u003chttps://www.infoworld.com/article/3667498/how-to-use-the-command-pattern-in-java.html\u003e\n\n---\n\n### _\"Interpreter Pattern\"_\n\n\u003e **_Dado un lenguaje, defina una representación para su gramática junto con un intérprete que use la representación para interpretar oraciones en el lenguaje._**\n\u003e\n\u003e _-- GoF_\n\n#### Concepto\n\nEs un patrón de diseño que, dado un lenguaje, define una representación para su gramática junto con un intérprete del lenguaje.\n\nEl **_'Interpreter Pattern'_** habla de definir un lenguaje de dominio (es decir, la caracterización del problema) como una gramática de lenguaje simple, representar reglas de dominio como oraciones de lenguaje e interpretar estas oraciones para resolver el problema. El patrón usa una clase para representar cada regla gramatical. Dado que las gramáticas suelen tener una estructura jerárquica, una jerarquía de herencia de las clases de reglas se comporta bien.\n\nEl patrón sugiere modelar el dominio con una gramática recursiva. El intérprete se basa en el recorrido recursivo del **_'Composite Pattern'_** para interpretar las \"oraciones\" que se le solicita procesar.\n\nEl patrón sugiere definir una gramática para un lenguaje simple definiendo una jerarquía de clases `Expression` e implementando una operación `interpret()`. Cada regla de la gramática es un 'compuesto' (una regla que hace referencia a otras reglas) o un 'terminal' (un nodo de hoja en una estructura de árbol).\n\nLa sentencia del lenguaje se representa mediante un árbol de sintaxis abstracta (AST) formado por instancias de `Expression`. Las sentencias se interpretan realizando un recorrido del AST e invocando `interpret()`.\n\n#### Referencias\n\n- \u003chttps://sourcemaking.com/design_patterns/interpreter\u003e\n- \u003chttps://www.baeldung.com/java-interpreter-pattern\u003e\n- \u003chttps://www.tutorialspoint.com/design_pattern/interpreter_pattern\u003e\n- \u003chttps://java-design-patterns.com/es/patterns/interpreter/\u003e\n\n---\n\n### _\"Iterator Pattern\"_\n\n\u003c!-- markdownlint-disable MD033 --\u003e\n\u003cdiv style=\"text-align: center;\"\u003e\n  \u003cimg src=\".//media//patterns//behavioral//iterator//iterator_header.png\" alt=\"iterator_pattern_intro\" width=\"475\" height=\"auto\"\u003e\n  \u003cp style=\"font-size: 0.75em;\"\u003e\u0026#169; Refactoring Guru\u003c/p\u003e\n\u003c/div\u003e\n\u003c!-- markdownlint-disable MD033 --\u003e\n\n\u003e **_Proporcionar una forma de acceder a los elementos de un objeto agregado de forma secuencial sin exponer su representación subyacente._**\n\u003e\n\u003e _-- GoF_\n\n#### Concepto\n\nEl **_'Iterator Pattern'_** se utiliza para ofrecer una interfaz de acceso secuencial a una determinada estructura ocultando la representación interna y la forma en que realmente se accede, o lo que es lo mismo, permite realizar recorridos sobre objetos compuestos independientemente de la implementación de éstos.\n\nLa solución que propone este patrón es añadir métodos que permitan recorrer la estructura sin referenciar explícitamente su representación, es decir, sin exponer su representación interna. La responsabilidad del recorrido se traslada a un objeto iterador.\n\nEl problema de introducir este objeto iterador reside en que los clientes necesitan conocer la estructura para crear el iterador apropiado. Esto se soluciona generalizando los distintos iteradores en una abstracción y dotando a las estructuras de datos de un método de fabricación que cree un iterador concreto.\n\nDiferentes iteradores pueden presentar diferentes tipos de recorrido sobre la estructura. No sólo eso, sino que podrían incorporar funcionalidad extra como por ejemplo filtrado de elementos, etc..\n\nEl uso del **_'Iterator Pattern'_** es muy común ya que manejar colecciones de datos es algo muy habitual en el desarrollo de aplicaciones. Listas, pilas y, sobre todo, árboles son ejemplos de estructuras de datos muy presentes en los juegos y se utilizan de forma intensiva.\n\nUna operación muy habitual es recorrer las estructuras para analizar y/o buscar los datos que contienen. Es posible que sea necesario recorrer la estructura de forma secuencial, de dos en dos o, simplemente, de forma aleatoria. Los clientes suelen implementar el método concreto con el que desean recorrer la estructura por lo que puede ser un problema si, por ejemplo, se desea recorrer una misma estructura de datos de varias formas distintas. Conforme aumenta las combinaciones entre los tipos de estructuras y métodos de acceso, el problema se agrava.\n\n#### Caso práctico\n\nLa estructura de datos es la encargada de crear el iterador adecuado para ser accedida a través del método `iterator()`. Una vez que el cliente ha obtenido el iterador, puede utilizar los métodos de acceso que ofrecen tales como `next()` (para obtener el siguiente elemento) o `isDone()` para comprobar si existen más elementos.\n\n```java\nclass RandomData {\n    int[] data;\n\n    RandomData(int length) {\n        data = new int[length];\n        for (int i = 0; i \u003c data.length; i++) {\n            data[i] = new Random().nextInt(500);\n        }\n    }\n\n    IteratorData iterator() {\n        return new IteratorData(this);\n    }\n}\n\n// Iterador que permite recorrer el objeto 'RandomData' sin conocer su implementación exacta\nclass IteratorData {\n    private int[] data;\n    private int pos;\n\n    IteratorData(RandomData randomData) {\n        data = randomData.data;\n        pos = 0;\n    }\n\n    boolean hasNext() {\n        return pos \u003c data.length;\n    }\n\n    Object next() {\n        int valor = data[pos];\n        pos++;\n        return valor;\n    }\n}\n\npublic class Client {\n    public static void main(String[] args) {\n        RandomData vector = new RandomData(5);\n\n        IteratorData iterator = vector.iterator();\n\n        while (iterator.hasNext())\n            System.out.println(iterator.next());\n    }\n}\n```\n\n#### Referencias\n\n- \u003chttps://refactoring.guru/es/design-patterns/iterator\u003e\n- \u003chttps://sourcemaking.com/design_patterns/iterator\u003e\n- \u003chttps://www.baeldung.com/java-iterator\u003e\n- \u003chttps://www.tutorialspoint.com/design_pattern/iterator_pattern\u003e\n- \u003chttps://www.digitalocean.com/community/tutorials/iterator-design-pattern-java\u003e\n- \u003chttps://java-design-patterns.com/es/patterns/iterator\u003e\n- \u003chttps://www.infoworld.com/article/2461744/java-language-iterating-over-collections-in-java-8.html\u003e\n\n---\n\n### _\"Mediator Pattern\"_\n\n\u003c!-- markdownlint-disable MD033 --\u003e\n\u003cdiv style=\"text-align: center;\"\u003e\n  \u003cimg src=\".//media//patterns//behavioral//mediator/mediator_header.png\" alt=\"mediator_pattern_intro\" width=\"475\" height=\"auto\"\u003e\n  \u003cp style=\"font-size: 0.75em;\"\u003e\u0026#169; Refactoring Guru\u003c/p\u003e\n\u003c/div\u003e\n\u003c!-- markdownlint-disable MD033 --\u003e\n\n\u003e **_Defina un objeto que encapsule cómo interactúa un conjunto de objetos. El mediador promueve el acoplamiento débil evitando que los objetos se refieran entre sí explícitamente, y le permite variar su interacción de forma independiente._**\n\u003e\n\u003e _-- GoF_\n\n#### Concepto\n\nNormalmente los programas tienen un gran número de clases. A medida que se agregan más clases a un programa, especialmente durante el mantenimiento y/o refactorización, el problema de la comunicación entre estas clases puede volverse más complejo. Esto hace que el programa sea más difícil de leer y mantener. Además, puede resultar difícil cambiar el programa, ya que cualquier cambio puede afectar al código en otras clases.\n\nDefinir un conjunto de objetos que interactúan accediendo y actualizándose entre ellos de forma directa es inflexible porque acopla estos objetos entre sí y hace imposible cambiar la interacción de forma independiente sin tener que modificarlos. Esto hace que los objetos sean poco reutilizables y difíciles de probar. Los objetos estrechamente acoplados son difíciles de implementar, cambiar, probar y reutilizar porque se refieren y conocen muchos objetos diferentes.\n\nEl **_'Mediator Pattern'_** define **un objeto que encapsula cómo un conjunto de objetos interactúan**. De esta forma los objetos no se comunican de forma directa entre ellos, sino que se comunican mediante el mediador. El mediador busca reducir el acoplamiento evitando que los objetos se relacionen entre ellos de forma explícita y permitiendo cambiar la interacción entre un conjunto de objetos de forma independiente.\n\n#### Caso práctico\n\nLa esencia del **_'Mediator Pattern'_** es **definir un objeto que encapsule cómo interactúa un conjunto de objetos**. Promueve el acoplamiento débil evitando que los objetos se refieran entre sí explícitamente, y permite que su interacción se varíe de forma independiente. Las clases de clientes pueden usar el mediador para enviar mensajes a otros clientes y pueden recibir mensajes de otros clientes a través de un evento en la clase de mediadores.\n\nEn el ejemplo participan:\n\n- _**Mediator**_: Define la interfaz para la comunicación entre objetos de tipo `Colleague`.\n\n- _**ConcreteMediator**_: implementa la interfaz del mediador y coordina la comunicación entre los objetos de tipo `Colleague`. Es consciente de todos los objetos y sus propósitos con respecto a la intercomunicación.\n\n- _**Colleague**_: Define la interfaz para la comunicación con otros objetos `Colleague` a través de su mediador.\n\n- _**ConcreteColleague**_: implementa la interfaz `Colleague` y se comunica con otros objetos a través de su mediador\n\n```java\ninterface Mediator {\n    void send(String message, Colleague colleague);\n}\n\nclass ConcreteMediator implements Mediator {\n    private ArrayList\u003cColleague\u003e colleagues;\n\n    ConcreteMediator() {\n        colleagues = new ArrayList\u003c\u003e();\n    }\n\n    void addColleague(Colleague colleague) {\n        colleagues.add(colleague);\n    }\n\n    public void send(String message, Colleague originator) {\n        for (Colleague colleague : colleagues) {\n            //don't tell ourselves\n            if (colleague != originator) {\n                colleague.receive(message);\n            }\n        }\n    }\n}\n\nabstract class Colleague {\n    private Mediator mediator;\n\n    Colleague(Mediator m) {\n        mediator = m;\n    }\n\n    //send a message via the mediator\n    void send(String message) {\n        mediator.send(message, this);\n    }\n\n    public abstract void receive(String message);\n}\n\nclass ConcreteColleague extends Colleague {\n    ConcreteColleague(Mediator mediator) {\n        super(mediator);\n    }\n\n    public void receive(String message) {\n        System.out.println(\"Colleague Received: \" + message);\n    }\n}\n```\n\n#### Consideraciones\n\nEl **_'Facade Pattern'_** y el **_'Mediator Pattern'_** son muy similares ya que ambos tratan de organizar la colaboración entre un montón de clases estrechamente acopladas.\n\nSin embargo en el **_'Facade Pattern'_** los objetos pueden comunicarse entre sí mientras que en el **_'Mediator Pattern'_** los objetos sólo se comunican con el mediador.\n\n#### Referencias\n\n- \u003chttps://refactoring.guru/es/design-patterns/mediator\u003e\n- \u003chttps://sourcemaking.com/design_patterns/mediator\u003e\n- \u003chttps://www.baeldung.com/java-mediator-pattern\u003e\n- \u003chttps://www.tutorialspoint.com/design_pattern/mediator_pattern\u003e\n- \u003chttps://www.digitalocean.com/community/tutorials/mediator-design-pattern-java\u003e\n- \u003chttps://java-design-patterns.com/es/patterns/mediator/\u003e\n\n---\n\n### _\"Memento Pattern\"_\n\n\u003c!-- markdownlint-disable MD033 --\u003e\n\u003cdiv style=\"text-align: center;\"\u003e\n  \u003cimg src=\".//media//patterns//behavioral//memento/memento_header.png\" alt=\"memento_pattern_intro\" width=\"475\" height=\"auto\"\u003e\n  \u003cp style=\"font-size: 0.75em;\"\u003e\u0026#169; Refactoring Guru\u003c/p\u003e\n\u003c/div\u003e\n\u003c!-- markdownlint-disable MD033 --\u003e\n\n\u003e **_Sin violar la encapsulación, captura y externaliza el estado interno de un objeto para que el objeto pueda restaurarse a este estado más adelante._**\n\u003e\n\u003e _-- GoF_\n\n#### Concepto\n\nEs un patrón de diseño cuya finalidad es almacenar el estado de un objeto (o del sistema completo) en un momento dado de manera que se pueda restaurar en ese punto de manera sencilla. Para ello se mantiene almacenado el estado del objeto para un instante de tiempo en una clase independiente de aquella a la que pertenece el objeto (pero sin romper la encapsulación), de forma que ese recuerdo permita que el objeto sea modificado y pueda volver a su estado anterior.\n\nSe usa este patrón cuando se quiere poder restaurar el sistema desde estados pasados y por otra parte, es usado cuando se desea facilitar el hacer y deshacer de determinadas operaciones, para lo que habrá que guardar los estados anteriores de los objetos sobre los que se opere (o bien recordar los cambios de forma incremental).\n\n#### Caso práctico\n\nEl **_'Memento Pattern'_** define tres roles principales:\n\n- _**Originator**_: El _'originator'_ puede producir instantáneas de su propio estado, así como restaurar su estado a partir de las instantáneas cuando sea necesario.\n\n- _**Caretaker**_: El _'caretaker'_ sabe no solo \"cuándo\" y \"por qué\" capturar el estado del _'originator'_, sino también cuándo debe restaurarse el estado. Puede realizar un seguimiento del historial del _'originator'_ almacenando una pila de _'mementos'_. Cuando el _'originator'_ tiene que retroceder en la historia, el _'caretaker'_ busca el recuerdo más alto de la pila y lo pasa al método de restauración del _'originator'_.\n\n- _**Memento**_: Es un objeto de valor que actúa como una instantánea del estado del _'originator'_. Es una práctica común hacer que el _'memento'_ sea inmutable y pasar los datos solo una vez, a través del constructor.\n\nLa clase `Originator` implementa el método `createMemento()` que crea y devuelve un objeto de tipo `Memento` que almacena el estado interno actual del propio objeto de tipo `Originator` y el método `restore(Memento memento)` que restaura el estado a partir del objeto de tipo `Memento` pasado como argumento.\n\nPara guardar el estado original, la clase `'Caretaker'` invoca el método `'createMemento()'` que creará un objeto de tipo `'Memento'` con el estado actual y lo retornará al invocador que lo custodiará (sin alterar su estado ni acceder a él). Cuando sea necesario restaurar el estado anterior, el objeto `'Caretaker'`  invocará el método `'restore(memento)'` especificando el objeto `'Memento'` que guarda el estado que debe ser restaurado. El objeto _'originator'_ recupera el estado del método `'getState()'` del objeto `'Memento'`.  \n\n```java\n// \"Originator.java\"\nclass Originator {\n    private String state;\n    // The class could also contain additional data that is not part of the\n    // state saved in the memento..\n\n    void set(String state) {\n        this.state = state;\n        System.out.println(\"Originator: Setting state to \" + state);\n    }\n\n    Memento createMemento() {\n        System.out.println(\"Originator: Saving to Memento.\");\n        return new Memento(this.state);\n    }\n\n    void restore(Memento memento) {\n        this.state = memento.getSavedState();\n        System.out.println(\"Originator: State after restoring from Memento: \" + state);\n    }\n\n    static class Memento {\n        private final String state;\n\n        Memento(String stateToSave) {\n            state = stateToSave;\n        }\n\n        // accessible by outer class only\n        private String getSavedState() {\n            return state;\n        }\n    }\n}\n\n// \"Caretaker.java\"\nclass Caretaker {\n    public static void main(String[] args) {\n        List\u003cOriginator.Memento\u003e savedStates = new ArrayList\u003c\u003e();\n\n        Originator originator = new Originator();\n        originator.set(\"State1\");\n        originator.set(\"State2\");\n        savedStates.add(originator.createMemento());\n        originator.set(\"State3\");\n        // We can request multiple mementos, and choose which one to roll back to.\n        savedStates.add(originator.createMemento());\n        originator.set(\"State4\");\n\n        originator.restore(savedStates.get(1));\n    }\n}\n```\n\n#### Consideraciones\n\nEn un escenario real en que puede haber varios puntos de restauración o _'snapshots'_ del estado de un objeto en varias instancias de tiempo se puede emplear una estructura como un `ArrayList` o similares. Un número alto de puntos de restauración o _'snapshots'_ requiere espacio extra de almacenamiento.\n\nEste patrón se utiliza cuando queremos implementar operaciones como _'undo'_ o _'rollback'_.\n\nEste patrón se puede implementar utilizando la serialización, que es bastante común en Java. Si bien no es la única ni la forma más eficiente de hacer instantáneas del estado de un objeto, todavía permite almacenar copias de seguridad del estado mientras protege la estructura del _'originator'_ frente a otros objetos.\n\n#### Referencias\n\n- \u003chttps://refactoring.guru/es/design-patterns/memento\u003e\n- \u003chttps://sourcemaking.com/design_patterns/memento\u003e\n- \u003chttps://www.baeldung.com/java-memento-design-pattern\u003e\n- \u003chttps://www.tutorialspoint.com/design_pattern/memento_pattern\u003e\n- \u003chttps://java-design-patterns.com/es/patterns/memento\u003e\n\n---\n\n### _\"Observer Pattern\"_\n\n\u003c!-- markdownlint-disable MD033 --\u003e\n\u003cdiv style=\"text-align: center;\"\u003e\n  \u003cimg src=\".//media//patterns//behavioral//observer//observer_header.png\" alt=\"observer_pattern_intro\" width=\"475\" height=\"auto\"\u003e\n  \u003cp style=\"font-size: 0.75em;\"\u003e\u0026#169; Refactoring Guru\u003c/p\u003e\n\u003c/div\u003e\n\u003c!-- markdownlint-disable MD033 --\u003e\n\n\u003e **_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._**\n\u003e\n\u003e _-- GoF_\n\n#### Concepto\n\nEl **_'Observer Pattern'_** se utiliza para definir relaciones 1 a _n_ de forma que un objeto pueda notificar y/o actualizar el estado de otros automáticamente.\n\nEste patrón proporciona un diseño con **poco acomplamiento** entre los _observadores_ y el objeto _observado_.\n\nSiguiendo la filosofía de **_publicación/suscripción_**, los objetos observadores se deben registrar en el objeto observado llamado sujeto pasándole una referencia de si mismo. El sujeto mantiene una lista de las referencias de los observadores. Cuando un observador ya no necesita ser notificado simplemente se borra de la lista de observadores.\n\nAdemás, los observadores a su vez están obligados a implementar unos métodos determinados mediante los cuales el sujeto es capaz de notificar a los observadores suscritos los cambios que sufre para que todos ellos tengan constancia.\n\nPor tanto, cuando el evento oportuno suceda, el sujeto recibirá una invocación y será el encargado de \"notificar\" a todos los elementos suscritos a él. Los observadores que reciben la notificación pueden realizar las acciones pertinentes.\n\nPuede pensarse en aplicar este patrón cuando una modificación en el estado de un objeto requiere cambios de otros, y no se desea que se conozca el número de objetos que deben ser cambiados. También cuando queremos que un objeto sea capaz de notificar a otros objetos sin hacer ninguna suposición acerca de los objetos notificados y cuando una abstracción tiene dos aspectos diferentes, que dependen uno del otro; si encapsulamos estos aspectos en objetos separados permitiremos su variación y reutilización de modo independiente.\n\n#### Caso práctico\n\nEl siguiente ejemplo es una situación en que tenemos un único observador y un único sujeto. El patrón se puede adaptar para los casos en que haya uno o varios observadores y uno o varios sujetos.\n\n```java\ninterface ISubject {\n    void register(Observer observer);\n    void unregister(Observer observer);\n    void notifyObservers();\n}\n\nclass Subject implements ISubject {\n    private List\u003cObserver\u003e observerList = new ArrayList\u003c\u003e();\n    private int flag;\n\n    void setFlag(int flag) {\n        this.flag = flag;\n        //flag value changed. So notify observer(s)\n        notifyObservers();\n    }\n\n    @Override\n    public void register(Observer o) {\n        observerList.add(o);\n    }\n\n    @Override\n    public void unregister(Observer o) {\n        observerList.remove(o);\n    }\n\n    @Override\n    public void notifyObservers() {\n        for (Observer observer : observerList) {\n            observer.update();\n        }\n    }\n}\n\nclass Observer {\n    void update() {\n        System.out.println(\"flag value changed in Subject\");\n    }\n}\n```\n\n#### Referencias\n\n- \u003chttps://refactoring.guru/es/design-patterns/observer\u003e\n- \u003chttps://sourcemaking.com/design_patterns/observer\u003e\n- \u003chttps://www.baeldung.com/java-observer-pattern\u003e\n- \u003chttps://www.tutorialspoint.com/design_pattern/observer_pattern\u003e\n- \u003chttps://www.digitalocean.com/community/tutorials/observer-design-pattern-in-java\u003e\n- \u003chttps://java-design-patterns.com/es/patterns/observer\u003e\n- \u003chttps://www.infoworld.com/article/3682139/intro-to-the-observable-design-pattern.html\u003e\n\n---\n\n### _\"State Pattern\"_\n\n\u003c!-- markdownlint-disable MD033 --\u003e\n\u003cdiv style=\"text-align: center;\"\u003e\n  \u003cimg src=\".//media//patterns//behavioral//state/state_header.png\" alt=\"state_pattern_intro\" width=\"475\" height=\"auto\"\u003e\n  \u003cp style=\"font-size: 0.75em;\"\u003e\u0026#169; Refactoring Guru\u003c/p\u003e\n\u003c/div\u003e\n\u003c!-- markdownlint-disable MD033 --\u003e\n\n\u003e **_Permitir que un objeto altere su comportamiento cuando cambia su estado interno. El objeto aparecerá para cambiar su clase._**\n\u003e\n\u003e _-- GoF_\n\n#### Concepto\n\nEl **_'State Pattern'_** permite que un objeto modifique su comportamiento cada vez que cambie su estado interno.\n\nEs muy común que en cualquier aplicación, incluido los videojuegos, existan estructuras que pueden ser modeladas directamente como **un autómata**, es decir, una colección de estados y unas transiciones dependientes de una entrada. En este caso, la entrada pueden ser invocaciones y/o eventos recibidos. También suele recibir el nombre de **máquina de estados**.\n\nPor ejemplo, los estados de un personaje de un videojuego podrían ser: de pie, tumbado, andando y saltando. Dependiendo del estado en el que se encuentre y de la invocación recibida, el siguiente estado será uno u otro. Si por ejemplo, está de pie y recibe la orden de tumbarse, ésta se podrá realizar. Sin embargo, si ya está tumbado no tiene sentido volver a tumbarse, por lo que debe permanecer en ese estado.\n\nEl **_'State Pattern'_** permite encapsular el mecanismo de las transiciones que sufre un objeto a partir de los estímulos externos.\n\n#### Caso práctico\n\nA continuación se muestra un ejemplo de aplicación del mismo. La idea es crear una clase abstracta o interfaz que representa al estado del personaje. En ella se definen las mismas operaciones que puede recibir el personaje con una implementación por defecto. En este caso, la implementación es vacía.\n\nPor cada estado en el que puede encontrarse el personaje, se crea una clase que hereda de la clase abstracta anterior, de forma que en cada una de ellas se implementen los métodos que producen cambio de estado, es decir, contendrán un método por cada posible transición.\n\nPor ejemplo, según el diagrama, en el estado \"de pie\" se puede recibir la orden de caminar, tumbarse y saltar, pero no de levantarse. En caso de recibir esta última, se ejecutará la implementación por defecto, es decir, no hacer nada.\n\nEn definitiva, la idea es que las clases que representan a los estados sean las encargadas de cambiar el estado del personaje, de forma que los cambios de estados quedan encapsulados y delegados al estado correspondiente.\n\n```java\ninterface CharacterState {\n    void walk();\n    void getUp();\n    void getDown();\n    void jump();\n}\n\n// ...\nclass CharacterStanding implements CharacterState {\n    private Character character;\n\n    CharacterStanding(Character character) {\n        this.character = character;\n    }\n\n    @Override\n    public void walk() {\n        System.out.println(\"Transición: De pie -\u003e Andar\");\n        character.setState(new CharacterWalk(character));\n    }\n\n    @Override\n    public void getUp() {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public void getDown() {\n        System.out.println(\"Transición: De pie -\u003e Agachado\");\n        character.setState(new CharacterLying(character));\n    }\n\n    @Override\n    public void jump() {\n        System.out.println(\"Transición: De pie -\u003e Saltando\");\n        character.setState(new CharacterJump(character));\n    }\n}\n\n// ...\nclass CharacterJump implements CharacterState {\n    private Character character;\n\n    CharacterJump(Character character) {\n        this.character = character;\n    }\n\n    @Override\n    public void walk() {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public void getUp() {\n        System.out.println(\"Transición: Saltando -\u003e Quieto\");\n\n        character.setState(new CharacterStanding(character));\n    }\n\n    @Override\n    public void getDown() {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public void jump() {\n        throw new UnsupportedOperationException();\n    }\n}\n\n// ...\nclass Character {\n    private CharacterState currentState;\n\n    Character() {\n        currentState = new CharacterStanding(this);\n    }\n\n    CharacterState getState() {\n        return currentState;\n    }\n\n    void setState(CharacterState currentState) {\n        this.currentState = currentState;\n    }\n\n    public void walk() {\n        currentState.walk();\n    }\n\n    void getUp() {\n        currentState.getUp();\n    }\n\n    void getDown() {\n        currentState.getDown();\n    }\n\n    void jump() {\n        currentState.jump();\n    }\n}\n```\n\n**NOTA**: Para que el ejemplo sea lo más claro posible se ha obviado de forma intencionada la aplicación del **\"Principio de Segregación de Interfaces\"** de los principos S.O.L.I.D. que si se aplicara correctamente se evitaría la obligación de implementar los métodos que lanzan `UnsupportedOperationException`.\n\n#### Consideraciones\n\nEste patrón puede usarse cuando un determinado objeto tiene diferentes estados y también diferentes responsabilidades según el estado en que se encuentre en un determinado instante. También puede utilizarse para simplificar casos en los que se tiene un complicado y extenso código de decisión que depende del estado del objeto.\n\nLos componentes de diseño que se comporten como autómatas son buenos candidatos a ser modelados con el **_'State Pattern'_**.\n\nEs posible que una entrada provoque una situación de error estando en un determinado estado. Para ello es posible utilizar las excepciones para notificar dicho error.\n\nLas clases que representan los estados **no deben mantener un estado intrínseco**, es decir, no se debe hacer uso de variables que dependan de un contexto.\n\nUn sistema con muchos estados o si el número se incrementa significativamente se convierte en un sistema difícil de mantener.\n\n#### Referencias\n\n- \u003chttps://refactoring.guru/es/design-patterns/state\u003e  \n- \u003chttps://sourcemaking.com/design_patterns/state\u003e  \n- \u003chttps://www.baeldung.com/java-state-design-pattern\u003e\n- \u003chttps://www.tutorialspoint.com/design_pattern/state_pattern\u003e\n- \u003chttps://www.digitalocean.com/community/tutorials/state-design-pattern-java\u003e\n- \u003chttps://java-design-patterns.com/es/patterns/state\u003e\n\n---\n\n### _\"Strategy Pattern\"_\n\n\u003c!-- markdownlint-disable MD033 --\u003e\n\u003cdiv style=\"text-align: center;\"\u003e\n  \u003cimg src=\".//media//patterns//behavioral//strategy/strategy_header.png\" alt=\"strategy_pattern_intro\" width=\"475\" height=\"auto\"\u003e\n  \u003cp style=\"font-size: 0.75em;\"\u003e\u0026#169; Refactoring Guru\u003c/p\u003e\n\u003c/div\u003e\n\u003c!-- markdownlint-disable MD033 --\u003e\n\n\u003e **_Defina una familia de algoritmos, encapsule cada uno de ellos y hágalos intercambiables. Este patrón permite que el algoritmo varíe independientemente de cliente a cliente._**\n\u003e\n\u003e _-- GoF_\n\n#### Concepto\n\nEl **_'Strategy Pattern'_** se utiliza para encapsular el funcionamiento de una familia de algoritmos, de forma que se pueda intercambiar su uso sin necesidad de modificar los clientes. Permite disponer de varios métodos para resolver un problema y elegir cuál utilizar en tiempo de ejecución.\n\nEn muchas ocasiones, se suele proporcionar diferentes algoritmos para realizar una misma tarea. Por ejemplo, el nivel de habilidad de un jugador viene determinado por diferentes algoritmos y heurísticas que determinan el grado de dificultad. Utilizando diferentes tipos algoritmos podemos obtener desde jugadores que realizan movimientos aleatorios hasta aquellos que pueden tener cierta inteligencia y que se basan en técnicas de IA.\n\nLo deseable sería poder tener jugadores de ambos tipos y que, desde el punto de vista del cliente, no fueran tipos distintos de jugadores. Simplemente se comportan diferente porque usan distintos algoritmos internamente, pero todos ellos son jugadores.\n\nOtro ejemplo para entender este patrón es el de un protagonista de un videojuego en el cual manejamos a un soldado que puede portar y utilizar varias armas distintas. La clase (o clases) que representan a nuestro soldado no deberían de preocuparse de los detalles de las armas que porta: debería bastar, por ejemplo, con un método de interfaz \"atacar\" que dispare el arma actual y otro método \"recargar\" que inserte munición en ésta (si se diera el caso). En un momento dado, otro método \"cambiarArma\" podrá sustituir el objeto equipado por otro, manteniendo la interfaz intacta.\n\nDa igual que nuestro soldado porte un rifle, una pistola o un fusil: los detalles de cada estrategia estarán encapsulados dentro de cada una de las clases intercambiables que representan las armas. Nuestra clase cliente (el soldado) únicamente debe preocuparse de las acciones comunes a todas ellas: atacar, recargar y cambiar de arma. Éste último método, de hecho, será el encargado de realizar la operación de \"cambio de estrategia\" que forma parte del patrón.\n\n#### Caso práctico\n\nMediante el uso de la herencia, el **_'Strategy Pattern'_** permite encapsular diferentes algoritmos para que los clientes puedan utilizarlos de forma transparente.\n\nLa idea es extraer los métodos que conforman el comportamiento que puede ser intercambiado y encapsularlo en una familia de algoritmos. En este ejemplo, el movimiento del jugador se extrae para formar una jerarquía de diferentes movimientos. Todos ellos implementan el método `move()` que recibe un contexto que incluye toda la información necesaria para llevar a cabo el algoritmo.\n\nPara el cliente todo se produce de forma transparente. Al configurarse cada jugador, ambos son del mismo tipo de cara al cliente aunque ambos se comportarán de forma diferente al invocar al método `doBestMove()`.\n\n```java\n// ...\ninterface Movement {\n    void move();\n}\n\n// ...\nclass IAMovement implements Movement {\n    @Override\n    public void move() {\n        System.out.println(\"IA Movement\");\n    }\n}\n\n// ...\nclass RandomMovement implements Movement {\n    @Override\n    public void move() {\n        System.out.println(\"Random movement\");\n    }\n}\n\n// ...\nclass GamePlayer {\n    private Movement movement;\n\n    void setMovement(Movement movement) {\n        this.movement = movement;\n    }\n\n    void doBestMove() {\n        movement.move();\n    }\n}\n\npublic class Client {\n\n    public static void main(String[] args) {\n        GamePlayer player = new GamePlayer();\n\n        Movement movement = new RandomMovement();\n        player.setMovement(movement);\n\n        player.doBestMove();\n    }\n}\n```\n\n#### Consideraciones\n\nEl **_'Strategy Pattern'_** es una buena alternativa a realizar subclases en las entidades que deben comportarse de forma diferente en función del algoritmo utilizado. Al extraer la heurística a una familia de algoritmos externos, obtenemos los siguientes beneficios:\n\n- Se aumenta la reutilización de dichos algoritmos.\n\n- Se evitan sentencias condicionales para elegir el comportamiento deseado.\n\n- Los clientes pueden elegir diferentes implementaciones para un mismo comportamiento deseado, lo que es útil para depuración y pruebas donde se pueden escoger implementaciones más simples y rápidas.\n\nEste patrón es aconsejable, como ya hemos comentado, en situaciones en los que una misma operación (o conjunto de operaciones) puedan realizarse de formas distintas.\n\nA grosso modo, este patrón realiza una tarea bastante similar al **_'Template Method Pattern'_**. Sin embargo, mientras que el **_'Strategy Pattern'_** se basa en la **composición** y los algoritmos no están obligados a tener partes en común, el **_'Template Method Pattern'_** se basa en la **herencia** y hay pasos en común que permiten extraer una plantilla.\n\n#### Referencias\n\n- \u003chttps://refactoring.guru/es/design-patterns/strategy\u003e\n- \u003chttps://sourcemaking.com/design_patterns/strategy\u003e\n- \u003chttps://www.baeldung.com/java-strategy-pattern\u003e\n- \u003chttps://www.tutorialspoint.com/design_pattern/strategy_pattern\u003e\n- \u003chttps://www.digitalocean.com/community/tutorials/strategy-design-pattern-in-java-example-tutorial\u003e\n- \u003chttps://java-design-patterns.com/es/patterns/strategy\u003e\n\n---\n\n### _\"Template Method Pattern\"_\n\n\u003c!-- markdownlint-disable MD033 --\u003e\n\u003cdiv style=\"text-align: center;\"\u003e\n  \u003cimg src=\".//media//patterns//behavioral//template/template_method_header.png\" alt=\"template_method_pattern_intro\" width=\"475\" height=\"auto\"\u003e\n  \u003cp style=\"font-size: 0.75em;\"\u003e\u0026#169; Refactoring Guru\u003c/p\u003e\n\u003c/div\u003e\n\u003c!-- markdownlint-disable MD033 --\u003e\n\n\u003e **_Define el esqueleto de un algoritmo en una operación, aplazando algunos pasos a las subclases. El método de la plantilla permite subclases redefinir ciertos pasos de un algoritmo sin cambiar la estructura del algoritmo._**\n\u003e\n\u003e _-- GoF_\n\n#### Concepto\n\nEl **_'Template Method Pattern'_** define en una operación el esqueleto de un algoritmo, delegando en las subclases algunos de sus pasos. Esto permite que las subclases redefinan ciertos pasos de un algoritmo sin cambiar su estructura.\n\nEn un buen diseño los algoritmos complejos se dividen en funciones más pequeñas, de forma que si se llama a dichas funciones en un determinado orden se consigue implementar el algoritmo completo. Conforme se diseña cada paso concreto, se suele ir detectando funcionalidad común con otros algoritmos.\n\nPor ejemplo, supongamos que tenemos dos tipos de jugadores de juegos de mesa: ajedrez y damas. En esencia, ambos juegan igual; lo que cambia son las reglas del juego que, obviamente, condiciona su estrategia y su forma de jugar concreta. Sin embargo, en ambos juegos, los jugadores mueven en su turno, esperan al rival y esto se repite hasta que acaba la partida.\n\nEste patrón consiste extraer este comportamiento común en una **clase padre** y definir en **las clases hijas** la funcionalidad concreta.\n\nSi el **_'Command Pattern'_** nos permite encapsular una invocación a un método, el **_'Template Method Pattern'_** establece una forma de encapsular algoritmos. Este patrón se basa en un principio muy sencillo: si un algoritmo puede aplicarse a varios supuestos en los que únicamente cambie un pequeño número de operaciones, la idea será utilizar una clase para modelarlo a través de sus operaciones. Esta clase base se encargará de definir los pasos comunes del algoritmo, mientras que las clases que hereden de ella implementarán los detalles propios de cada caso concreto, es decir, el código específico para cada caso.\n\n#### Caso práctico\n\nPara aplicar este patrón se declara una clase abstracta, que será la plantilla o modelo. Esta clase definirá una serie de funciones y métodos. Aquellas que sean comunes estarán implementadas. Aquellas que dependan de cada caso concreto, se declararán como abstractas, obligando a las clases hijas a implementarlas.\n\nAdemás, cada clase derivada implementará los métodos específicos, acudiendo a la clase base para ejecutar el código común.\n\nLa clase base también se encargará de la lógica del algoritmo, ejecutando los pasos en un orden preestablecido (las clases hijas no deberían poder modificar el algoritmo, únicamente definir la funcionalidad específica que tienen que implementar).\n\nDado que la clase padre es la que se encarga de llamar los métodos de las clases derivadas (los pasos del algoritmo estarán implementado en la clase base), se trata de una aplicación manifiesta del **'Principio de Inversión de Dependencias'**: la clase base no tiene por qué saber nada acerca de sus hijas, pero aún así, se encargará de invocar su funcionalidad cuando sea necesario. El **'Principio de Hollywood'** (“no nos llames, nosotros te llamaremos”) vuelve a entrar en escena.\n\nLa clase `GamePlayer` es la que implementa el método `play()` que es el que invoca a los otros métodos que son implementados por las clases hijas. Este método es el **método plantilla**:\n\n```java\n// \"GamePlayer\"\nabstract class GamePlayer {\n    void play() {\n        if (moveFirst()) {\n            doBestMove();\n        }\n\n        while (!isOver()) {\n            // Movimiento del rival\n            //....\n\n            if (!isOver()) {\n                doBestMove();\n            }\n        }\n    }\n\n    abstract void doBestMove();\n\n    abstract boolean moveFirst();\n\n    abstract boolean isOver();\n}\n\n// \"ChessPlayer.java\"\nclass ChessPlayer extends GamePlayer {\n    private int movements = 0;\n\n    @Override\n    boolean moveFirst() {\n        System.out.println(\"El rival mueve primero\");\n        return false;\n    }\n\n    @Override\n    void doBestMove() {\n        System.out.println(\"Moviendo ficha - Movimiento \" + movements);\n        movements++;\n    }\n\n    // Como convención para el ejemplo, la partida acaba al alcanzar 50 movimientos\n    @Override\n    boolean isOver() {\n        if (movements \u003c 50) {\n            return false;\n        } else {\n            System.out.println(\"Fin de la partida - Alcanzado los \" + movements + \" como máximo\");\n            return true;\n        }\n    }\n}\n\n// \"CheckersPlayer.java\"\nclass CheckersPlayer extends GamePlayer {\n    private int movements = 0;\n\n    @Override\n    void doBestMove() {\n        System.out.println(\"Moviendo ficha - Movimiento \" + movements);\n        movements++;\n    }\n\n    @Override\n    boolean moveFirst() {\n        System.out.println(\"Movemos primero\");\n        return true;\n    }\n\n    // Como convención para el ejemplo, la partida acaba al alcanzar 25 movimientos\n    @Override\n    boolean isOver() {\n        if (movements \u003c 25) {\n            return false;\n        } else {\n            System.out.println(\"Fin de la partida - Alcanzado los \" + movements + \" como máximo\");\n            return true;\n        }\n    }\n}\n```\n\n#### Consideraciones\n\nUtilizando este patrón se suelen obtener estructuras altamente reutilizables. Esta reutilización de código es el objetivo primordial de este patrón. Es por ello que es ampliamente utilizado en bibliotecas de clases.\n\nAdemás, introduce el concepto de operaciones _'hook'_ que, en caso de no estar implementadas en las clases hijas, tienen una implementación por defecto. Las clases hijas pueden sobreescribirlas para añadir su propia funcionalidad.\n\nHay que minimizar el número de métodos abstractos (métodos sin cuerpo). De lo contrario, cada una de las subclases debe sobreescribirlos y el proceso global perderá la efectividad de este patrón de diseño.\n\n#### Referencias\n\n- \u003chttps://refactoring.guru/es/design-patterns/template-method\u003e\n- \u003chttps://sourcemaking.com/design_patterns/template_method\u003e\n- \u003chttps://www.baeldung.com/java-template-method-pattern\u003e\n- \u003chttps://www.tutorialspoint.com/design_pattern/template_pattern\u003e\n- \u003chttps://www.digitalocean.com/community/tutorials/template-method-design-pattern-in-java\u003e\n- \u003chttps://java-design-patterns.com/es/patterns/template-method/\u003e\n\n---\n\n### _\"Visitor Pattern\"_\n\n\u003c!-- markdownlint-disable MD033 --\u003e\n\u003cdiv style=\"text-align: center;\"\u003e\n  \u003cimg src=\".//media//patterns//behavioral//visitor/visitor_header.png\" alt=\"visitor_pattern_intro\" width=\"475\" height=\"auto\"\u003e\n  \u003cp style=\"font-size: 0.75em;\"\u003e\u0026#169; Refactoring Guru\u003c/p\u003e\n\u003c/div\u003e\n\u003c!-- markdownlint-disable MD033 --\u003e\n\n\u003e **_Representa una operación a realizar en los elementos de una estructura de objeto. Este patrón le permite definir una nueva operación sin cambiar las clases de los elementos sobre los que opera._**\n\u003e\n\u003e _-- GoF_\n\nEl **_'Visitor Pattern'_** proporciona un mecanismo para realizar diferentes operaciones sobre una jerarquía de objetos de forma que añadir nuevas operaciones no haga necesario cambiar las clases de los objetos sobre los que se realizan las operaciones.\n\n#### Concepto\n\nEn el diseño de un programa, normalmente se obtienen jerarquías de objetos a través de herencia o utilizando el **_'Composite Pattern'_**. Considerando una jerarquía de objetos que sea más o menos estable, es muy probable que necesitemos realizar operaciones sobre dicha jerarquía. Sin embargo, puede ser que cada objeto deba ser tratado de una forma diferente en función de su tipo. Por lo tanto la complejidad general aumentará según el número de objetos y de operaciones aplicables.\n\nEn el **_'Visitor Pattern'_** se distinguen dos participantes:\n\n- **Visitables**: son los elementos de la estructura de objetos que aceptan a un determinado visitante y que le proporcionan toda la información a éste para realizar una determinada operación. Definen una operación `accept(v:Visitor)` que toma un visitante como argumento.\n\n- **Visitantes:** jerarquía de objetos que realizan una operación determinada sobre dichos elementos.\n\nCada visitante concreto realiza una operación sobre la estructura de objetos. Es posible que al visitante no le interesen todos los objetos y, por lo tanto, la implementación de alguno de sus métodos sea vacía.\n\nSin embargo, lo importante de este patrón es que se pueden añadir nuevos tipos de visitantes concretos y, por lo tanto, realizar nuevas operaciones sobre la estructura sin la necesidad de modificar nada en la propia estructura. Por tanto se seguiría el **Principio 'Open/Closed'** (abierto a la extensión, cerrado a la modificación).\n\n#### Caso práctico\n\n```java\ninterface Element {\n    void accept(Visitor visitor);\n}\n\nclass ElementA implements Element {\n    @Override\n    public void accept(Visitor visitor) {\n        visitor.visitElementA(this);\n    }\n}\n\nclass ElementB implements Element {\n    @Override\n    public void accept(Visitor visitor) {\n        visitor.visitElementB(this);\n    }\n}\n\ninterface Visitor {\n    void visitElementA(Element element);\n    void visitElementB(Element element);\n}\n\nclass ConcreteVisitor1 implements Visitor {\n    @Override\n    public void visitElementA(Element element) {\n        System.out.println(\"Visitando \" + element.toString());\n    }\n    @Override\n    public void visitElementB(Element element) {\n        throw new UnsupportedOperationException();\n    }\n}\n\nclass ConcreteVisitor2 implements Visitor {\n    @Override\n    public void visitElementA(Element element) {\n        throw new UnsupportedOperationException();\n    }\n    @Override\n    public void visitElementB(Element element) {\n        System.out.println(\"Visitando \" + element.toString());\n    }\n}\n```\n\n#### Consideraciones\n\nEl **_'Visitor Pattern'_** es muy conveniente para recorrer estructuras arbóreas y realizar operaciones en base a los datos almacenados.\n\nLa forma en que se recorra la estructura influirá notablemente en el rendimiento del análisis de la estructura. Se puede hacer uso del **_'Iterator Pattern'_** para decidir cómo escoger el siguiente elemento.\n\nUno de los problemas de este patrón es que no es recomendable si la estructura  de objetos cambia frecuentemente o es necesario añadir nuevos tipos de objetos de forma habitual. Cada nuevo objeto que sea susceptible de ser visitado puede provocar grandes cambios en la jerarquía de los visitantes.\n\n#### Referencias\n\n- \u003chttps://refactoring.guru/es/design-patterns/visitor\u003e\n- \u003chttps://sourcemaking.com/design_patterns/visitor\u003e\n- \u003chttps://www.baeldung.com/java-visitor-pattern\u003e\n- \u003chttps://www.tutorialspoint.com/design_pattern/visitor_pattern\u003e\n- \u003chttps://www.digitalocean.com/community/tutorials/visitor-design-pattern-java\u003e\n- \u003chttps://java-design-patterns.com/es/patterns/visitor\u003e\n\n---\n\n## _Creational Patterns_\n\nLos patrones de creación corresponden a patrones de diseño de software que solucionan problemas de creación de instancias. Nos ayudan a encapsular y abstraer dicha creación.\n\nLos patrones creacionales son [**_Abstract Factory_**](#abstract-factory-pattern), [**_Builder_**](#builder-pattern), [**_Factory Method_**](#factory-method-pattern), [**_Prototype_**](#prototype-pattern) y [**_Singleton_**](#singleton-pattern).\n\n- \u003chttps://www.baeldung.com/creational-design-patterns\u003e\n- \u003chttps://www.baeldung.com/java-creational-design-patterns\u003e\n\n### _\"Abstract Factory Pattern\"_\n\n\u003c!-- markdownlint-disable MD033 --\u003e\n\u003cdiv style=\"text-align: center;\"\u003e\n  \u003cimg src=\".//media//patterns//creational//abstract-factory/abstract-factory_header.png\" alt=\"abstract-factory_pattern_intro\" width=\"475\" height=\"auto\"\u003e\n  \u003cp style=\"font-size: 0.75em;\"\u003e\u0026#169; Refactoring Guru\u003c/p\u003e\n\u003c/div\u003e\n\u003c!-- markdownlint-disable MD033 --\u003e\n\n\u003e **_Proporciona una interfaz para crear familias de objetos relacionados o dependientes sin especificar sus clases concretas._**\n\u003e\n\u003e _-- GoF_\n\nEl **_'Abstract Factory Pattern'_** permite crear diferentes tipos o familias de instancias, aislando al cliente sobre como se debe crear cada una de ellas.\n\n#### Concepto\n\nEl **_'Abstract Factory Pattern'_** recomienda crear las siguientes entidades:\n\n- **Factoría abstracta** que defina una interfaz para que los clientes puedan crear los distintos tipos de objetos.\n\n- **Factorías concretas** que realmente crean las instancias finales y que son hijas de la factoría abstracta.\n\nEl patrón **_'Abstract Factory'_** puede ser aplicable cuando:\n\n- el sistema de creación de instancias debe aislarse.\n\n- es necesaria la creación de varias instancias de objetos para tener el sistema configurado.\n\n- cuando la creación de instancias implican la imposición de restricciones u otras particularidades propias de los objetos que se construyen.\n\n- los objetos que deben construirse en las factorías no cambian excesivamente en el tiempo.\n\nAñadir nuevos tipos implica cambiar todas las factorías. Por ello, se recomienda aplicar este patrón sobre diseños con un cierto grado de estabilidad.\n\nUn ejemplo de uso de este patrón podría ser las interfaces gráficas o UI. Las bibliotecas para crear interfaces gráficas suelen utilizar este patrón. Cada familia aplica a un SO distinto.\n\nAsí pues, el usuario declara un elemento como podría ser un _Button_ pero de forma más interna lo que está creando es un _WindowsButton_ o un _LinuxButton_ según el SO, siendo transparente para el cliente o usuario.\n\nOtro ejemplo podría ser la jerarquía de objetos existentes en cualquier juego.\n\n\u003c!-- markdownlint-disable MD033 --\u003e\n\u003cdiv style=\"text-align: center;\"\u003e\n  \u003cimg src=\".//media//patterns//creational//abstract-factory/abstract-factory_01.png\" alt=\"abstract-factory_pattern_example\" width=\"550\" height=\"auto\"\u003e\n\u003c/div\u003e\n\u003c!-- markdownlint-disable MD033 --\u003e\n\nEn ella, se muestra jerarquías de clases que modelan los diferentes tipos de personajes de un juego y algunas de sus armas. Para construir cada tipo de personaje es necesario saber cómo construirlo y con qué otro tipo de objetos tiene relación. Por ejemplo, restricciones del tipo \"la gente del pueblo no puede llevar armas\" o \"los arqueros sólo pueden puede tener un arco\", es conocimiento específico de la clase que se está construyendo.\n\n#### Caso práctico\n\nEn primer lugar se define una factoría abstracta que será la que utilice el cliente `Game` para crear los diferentes objetos. La clase `SoldierFactory` es una factoría que sólo define métodos abstractos y que serán implementados por sus clases hijas.\n\nLas clases hijas son factorías concretas de cada tipo de raza, como por ejemplo `ManFactory` y `OrcFactory`. Estas factorías son las encargadas de crear las instancias concretas de objetos de tipo `Archer` y/o `Rider` para cada una de las razas.\n\nEl **_'Abstract Factory Pattern'_** es de ayuda en este tipo de situaciones en las que es necesario crear diferentes tipos de objetos utilizando una jerarquía de componentes. Dada la complejidad que puede llegar a tener la creación de una instancia es deseable aislar la forma en que se construye cada clase de objeto.\n\n```java\n// Jerarquía de tipos\nabstract class Soldier {\n    String name;\n    int life;\n\n    abstract int shotsPerSecond();\n}\n\nclass Rider extends Soldier {\n    Rider(String name, int life) {\n        this.name = name;\n        this.life = life;\n    }\n\n    @Override\n    public int shotsPerSecond() {\n        return 5;\n    }\n}\n\nclass Archer extends Soldier {\n    Archer(String name, int life) {\n        this.name = name;\n        this.life = life;\n    }\n\n    @Override\n    public int shotsPerSecond() {\n        return 2;\n    }\n}\n\n// Factoría abstracta\ninterface SoldierFactory {\n    Archer makeArcher();\n    Rider makeRider();\n}\n\n// Factoría concreta\nclass OrcFactory implements SoldierFactory {\n    @Override\n    public Archer makeArcher() {\n        return new Archer(\"Orc Archer\", 200);\n    }\n    @Override\n    public Rider makeRider() {\n        return new Rider(\"Orc Rider\", 250);\n    }\n}\n\n// Factoría concreta\nclass ManFactory implements SoldierFactory {\n    @Override\n    public Archer makeArcher() {\n        return new Archer(\"Man Archer\", 100);\n    }\n\n    @Override\n    public Rider makeRider() {\n        return new Rider(\"Man Rider\", 150);\n    }\n}\n```\n\n#### Consideraciones\n\nEste patrón se utiliza cuando a nuestro sistema no le importa cómo se crearán o compondrán sus productos o cuando necesitamos tratar con varias _\"fábricas\"_ o _\"factorías\"_.\n\nEste patrón separa las clases concretas y facilita el intercambio de productos. También puede mejorar la fiabilidad entre los productos. Pero, al mismo tiempo, debemos reconocer el hecho de que crear un nuevo producto es difícil con este patrón (porque necesitamos extender la interfaz y, como resultado, se requerirán cambios en todas las subclases que ya implementaron la interfaz).\n\n#### Referencias\n\n- \u003chttps://refactoring.guru/es/design-patterns/abstract-factory\u003e\n- \u003chttps://sourcemaking.com/design_patterns/abstract_factory\u003e\n- \u003chttps://www.baeldung.com/java-abstract-factory-pattern\u003e\n- \u003chttps://www.tutorialspoint.com/design_pattern/abstract_factory_pattern\u003e\n- \u003chttps://www.digitalocean.com/community/tutorials/abstract-factory-design-pattern-in-java\u003e\n- \u003chttps://java-design-patterns.com/es/patterns/abstract-factory/\u003e\n\n---\n\n### _\"Builder Pattern\"_\n\n\u003c!-- markdownlint-disable MD033 --\u003e\n\u003cdiv style=\"text-align: center;\"\u003e\n  \u003cimg src=\".//media//patterns//creational//builder/builder_header.png\" alt=\"builder_pattern_intro\" width=\"475\" height=\"auto\"\u003e\n  \u003cp style=\"font-size: 0.75em;\"\u003e\u0026#169; Refactoring Guru\u003c/p\u003e\n\u003c/div\u003e\n\u003c!-- markdownlint-disable MD033 --\u003e\n\n\u003e **_Separa la construcción de un objeto complejo de su representación para que los mismos procesos de construcción puedan crear diferentes representaciones._**\n\u003e\n\u003e _-- GoF_\n\n#### Concepto\n\nEl **_'Builder Pattern'_**  es útil para crear **objetos complejos que tienen varias partes**. El mecanismo de creación de un objeto debe ser independiente de estas partes ya que al proceso de construcción no le importa como se ensamblan estas piezas. El mismo proceso de construcción debe permitirnos crear diferentes representaciones de los objetos.\n\nCrear y ensamblar las partes de un objeto complejo directamente dentro de una clase es inflexible. Se compromete a la clase a crear una representación particular del objeto complejo y hace que sea imposible cambiar la representación más tarde de forma independiente de la clase sin tener que cambiarla.\n\nVentajas de utilizar este patrón:\n\n- Reduce el acoplamiento.\n\n- Permite variar la representación interna de un producto.\n\n- Encapsula el código para la construcción y la representación.\n\n- Proporciona control sobre los pasos del proceso de construcción.\n\nDesventajas del patrón:\n\n- Requiere crear un constructor concreto para cada tipo diferente de producto.\n\n- Requiere que las clases del constructor sean mutables.\n\n- No se garantiza la inicialización de los datos de los miembros de la clase.\n\n- La inyección de dependencia puede ser menos compatible.\n\n#### Caso práctico\n\nEntidades que intervienen:\n\n- _**Builder**_: Interfaz abstracta para crear objetos (producto).\n\n- _**ConcreteBuilder**_: Proporciona implementación para _'Builder'_. Es un objeto capaz de construir otros objetos. Construye y ensambla partes para construir los objetos.\n\n- _**Product**_: el objeto complejo que se construye.\n\n- _**Director**_: invoca el objeto _'Builder'_ para la construcción del producto.\n\n```java\ninterface Builder {\n    Product build();\n    ConcreteBuilder setName(String name);\n    ConcreteBuilder setColor(String color);\n}\n\nclass ConcreteBuilder implements Builder {\n    private Product product;\n\n    ConcreteBuilder() {\n        product = new Product();\n    }\n\n    @Override\n    public Product build() {\n        Product product = new Product();\n        product.setColor(this.product.getColor());\n        product.setName(this.product.getName());\n        return product;\n    }\n\n    @Override\n    public ConcreteBuilder setColor(final String color) {\n        product.setColor(color);\n        return this;\n    }\n\n    @Override\n    public ConcreteBuilder setName(final String name) {\n        product.setName(name);\n        return this;\n    }\n}\n\nclass Product {\n    // ...\n}\n\npublic class Director {\n\n    private Builder builder;\n\n    private Director(final Builder builder) {\n        this.builder = builder;\n    }\n\n    public static void main(final String ... arguments) {\n        final Builder builder = new ConcreteBuilder();\n        final Director director = new Director(builder);\n        System.out.println(director.construct());\n    }\n\n    private Product construct() {\n        return builder.setName(\"ProductA\")\n                .setColor(\"Red\")\n                .build();\n    }\n}\n```\n\n#### Referencias\n\n- \u003chttps://refactoring.guru/es/design-patterns/builder\u003e\n- \u003chttps://sourcemaking.com/design_patterns/builder\u003e\n- \u003chttps://www.baeldung.com/java-builder-pattern\u003e\n- \u003chttps://www.baeldung.com/java-builder-pattern-inheritance\u003e\n- \u003chttps://www.tutorialspoint.com/design_pattern/builder_pattern\u003e\n- \u003chttps://www.digitalocean.com/community/tutorials/builder-design-pattern-in-java\u003e\n- \u003chttps://java-design-patterns.com/es/patterns/builder/\u003e\n\n---\n\n### _\"Factory Method Pattern\"_\n\n\u003c!-- markdownlint-disable MD033 --\u003e\n\u003cdiv style=\"text-align: center;\"\u003e\n  \u003cimg src=\".//media//patterns//creational//factory-method/factory-method_header.png\" alt=\"factory-method_pattern_intro\" width=\"475\" height=\"auto\"\u003e\n  \u003cp style=\"font-size: 0.75em;\"\u003e\u0026#169; Refactoring Guru\u003c/p\u003e\n\u003c/div\u003e\n\u003c!-- markdownlint-disable MD033 --\u003e\n\n\u003e **_Defina una interfaz para crear un objeto, pero deje que las subclases decidan qué clase instanciar. Este patrón permite que una clase difiera la creación de instancias a subclases._**\n\u003e\n\u003e _-- GoF_\n\n#### Concepto\n\nEl **_'Factory Method Pattern'_** centraliza en una clase constructora la **creación de objetos de un subtipo de un tipo determinado**, ocultando al usuario la diversidad de casos particulares que se pueden preveer en la elección del subtipo.\n\nAl igual que ocurre con el **_'Abstract Factory Pattern'_** el problema que se pretende resolver es la creación de diferentes instancias de objetos abstrayendo la forma en que realmente se crean.\n\nEn el **_'Factory Method Pattern'_** se utiliza una clase constructora abstracta con métodos definidos y otro(s) abstracto(s) dedicado(s) a la construcción de objetos de un subtipo de un tipo determinado. Es una simplificación del **_'Abstract Factory Pattern'_** en la que la clase abstracta tiene métodos concretos.\n\nA diferencia del **_'Abstract Factory Pattern'_** no es necesario tener una factoría o una jerarquía de factorías para la creación de objetos. Permite diseños más adaptados a la realidad.\n\n#### Caso práctico\n\nLas clases principales del ejemplo son el **creador** y el **producto**. El creador necesita crear instancias de productos, pero el tipo concreto de producto no debe ser forzado en las subclases del creador porque las posibles subclases del creador deber poder especificar subclases del producto a utilizar.\n\nLa solución para esto es hacer un método abstracto (el método de la fábrica) que se define en el creador. Este método abstracto se define para que devuelva un producto. Las subclases del creador pueden sobreescribir este método para devolver subclases apropiadas del producto.\n\n```java\ninterface Product {\n    void operacion();\n}\n\nclass ConcreteProductA implements Product {\n    @Override\n    public void operacion() {\n        System.out.println(\"ConcreteProductA\");\n    }\n}\n\nclass ConcreteProductB implements Product {\n    @Override\n    public void operacion() {\n        System.out.println(\"ConcreteProductB\");\n    }\n}\n\nabstract class Creator {\n    abstract Product factoryMethod();\n}\n\nclass ConcreteCreatorA extends Creator {\n    @Override\n    Product factoryMethod() {\n        return new ConcreteProductA();\n    }\n}\n\nclass ConcreteCreatorB extends Creator {\n    @Override\n    Product factoryMethod() {\n        return new ConcreteProductB();\n    }\n}\n```\n\n#### Consideraciones\n\nEste patrón es útil cuando las clases delegan las responsabilidades de la creación de objetos a sus subclases.\n\nEste patrón también es útil cuando se implementan jerarquías de clases paralelas (cuando algunas de las responsabilidades cambian de una clase a otra) y cuando es posible crear un sistema con acoplamiento débil.\n\n#### Referencias\n\n- \u003chttps://refactoring.guru/es/design-patterns/factory-method\u003e\n- \u003chttps://sourcemaking.com/design_patterns/factory_factory\u003e\n- \u003chttps://www.baeldung.com/java-factory-pattern\u003e\n- \u003chttps://www.tutorialspoint.com/design_pattern/factory_pattern\u003e\n- \u003chttps://www.digitalocean.com/community/tutorials/factory-design-pattern-in-java\u003e\n- \u003chttps://java-design-patterns.com/es/patterns/factory/\u003e\n\n---\n\n### _\"Prototype Pattern\"_\n\n\u003c!-- markdownlint-disable MD033 --\u003e\n\u003cdiv style=\"text-align: center;\"\u003e\n  \u003cimg src=\".//media//patterns//creational//prototype/prototype_header.png\" alt=\"prototype_pattern_intro\" width=\"475\" height=\"auto\"\u003e\n  \u003cp style=\"font-size: 0.75em;\"\u003e\u0026#169; Refactoring Guru\u003c/p\u003e\n\u003c/div\u003e\n\u003c!-- markdownlint-disable MD033 --\u003e\n\n\u003e **_Especifique los tipos de objetos para crear utilizando una instancia prototípica y cree nuevos objetos copiando este prototipo._**\n\u003e\n\u003e _-- GoF_\n\n#### Concepto\n\nEl **_'Prototype Pattern'_** proporciona abstracción a la hora de crear diferentes objetos en un contexto donde se desconoce cúantos y cuáles deben ser creados a priori. La idea principal es que los objetos deben poder clonarse o copiarse en tiempo de ejecución. Por tanto, este patrón tiene como finalidad crear nuevos objetos duplicándolos, clonando una instancia creada previamente. Dado que crear una nueva instancia normalmente suele ser una operación costosa, este patrón ayuda a lidiar con ese problema.\n\nLos **_'Factory Method Pattern'_** y **_'Abstract Factory Pattern'_** tiene el problema de que se basan en la herencia e implementación de métodos abstractos por subclases para definir cómo se construye cada producto concreto. Para sistemas donde el número de productos concretos puede ser elevado o indeterminado esto puede ser un problema.\n\nLa clase de los objetos que servirán de prototipo para la copia deberán incluir en su interfaz la manera de solicitar esa copia, que será desarrollada luego por las clases concretas de prototipos.\n\nEste patrón se utiliza en casos como:\n\n- Evitar las subclases de un objeto creador como hace el patrón **_'Abstract Factory'_**\n\n- Evitar el costo inherente a la creación de un objeto nuevo mediante el operador `new` cuando esto es demasiado costoso para la aplicación.\n\n- La decisión del tipo de objeto necesario se decide en tiempo de ejecución en función de determinados parámetros, configuraciones o condiciones en un momento dado.\n\nEste patrón, dicho de otro modo, propone la creación de distintas variantes de objetos que la aplicación necesite en el momento y contexto adecuados. Toda la lógica necesaria para la decisión sobre el tipo de objetos que usará la aplicación es su ejecución se hace independiente, de manera que el código que utiliza estos objetos solicitará una copia del objeto que necesite. En este contexto, una copia significa otra instancia del objeto. El único requisito que debe cumplir este objeto es suministrar la funcionalidad de clonarse.\n\n#### Caso práctico\n\nPara implementar este patrón se declara una clase base abstracta que tiene un método `clone()`. Cualquier clase que necesite un constructor deriva de la clase abstracta e implementa el método `clone()`.\n\nEl cliente, en vez de escribir código que hace uso del generador `new` sobre una clase específica, llama al método `clone()` de la clase prototipo, o llama a un método factoría con un parámetro que especifíca la clase deseada, o invoca el método `clone()` de la clase de alguna otra forma.\n\nPor ejemplo, es posible usar un **gestor de prototipos** que permita cargar y descargar los prototipos disponibles en tiempo de ejecución.\n\nAunque en un principio este patrón parece que entra en conflicto con **_'Abstract Factory'_** es posible utilizar ambas aproximaciones en una **_'Prototype Abstract Factory'_** de forma que la factoría se configura con los prototipos concretos que puede crear y ésta sólo invoca al método `clone()`.\n\n```java\ninterface Producto {\n    Producto copy();\n}\n\nclass ProductoA implements Producto {\n    private String name = \"ProductoA\";\n\n    @Override\n    public Producto copy() {\n        return new ProductoA();\n    }\n\n    @Override\n    public String toString() {\n        return name;\n    }\n}\n\n// Factoría que crea y copia los objetos\nclass FactoriaPrototipo {\n    private Producto productoA;\n\n    FactoriaPrototipo() {\n        productoA = new ProductoA();\n    }\n\n    Producto create() {\n        return productoA.copy();\n    }\n}\n```\n\n#### Consideraciones\n\nEste patrón es útil para implementar _\"plugins\"_ o cuando se cargan en tiempo de ejecución liberías dinámicas, cuando el sistema no se preocupa por el mecanismo de creación de los productos o cuando necesitamos instanciar clases en tiempo de ejecución.\n\nUna de las ventajas de este patrón es que ayuda a crear nuevas instancias con un coste bajo.\n\nPor el contrario, una de las desventajas es que cada subclase tiene que implementar el mecanismo de clonación. Implementar el mecanismo de clonación puede ser un desafío si los objetos en consideración no admiten la copia o si hay algún tipo de referencia circular.\n\n#### Referencias\n\n- \u003chttps://refactoring.guru/es/design-patterns/prototype\u003e\n- \u003chttps://sourcemaking.com/design_patterns/prototype\u003e\n- \u003chttps://www.baeldung.com/java-pattern-prototype\u003e\n- \u003chttps://www.tutorialspoint.com/design_pattern/prototype_pattern\u003e\n- \u003chttps://www.digitalocean.com/community/tutorials/prototype-design-pattern-in-java\u003e\n- \u003chttps://java-design-patterns.com/es/patterns/prototype/\u003e\n\n---\n\n### _\"Singleton Pattern\"_\n\n\u003c!-- markdownlint-disable MD033 --\u003e\n\u003cdiv style=\"text-align: center;\"\u003e\n  \u003cimg src=\".//media//patterns//creational//singleton/singleton_header.png\" alt=\"singleton_pattern_intro\" width=\"475\" height=\"auto\"\u003e\n  \u003cp style=\"font-size: 0.75em;\"\u003e\u0026#169; Refactoring Guru\u003c/p\u003e\n\u003c/div\u003e\n\u003c!-- markdownlint-disable MD033 --\u003e\n\n\u003e **_Asegúrese de que una clase solo tenga una instancia y proporcione un punto de acceso global a ella._**\n\u003e\n\u003e _-- GoF_\n\n#### Concepto\n\nEl **_'Singleton Pattern'_** garantiza la existencia de una única instancia para una clase y la creación de un mecanismo de acceso global a dicha instancia. Restringe la instanciación de una clase o valor de un tipo a un solo objeto.\n\nEn Java, los objetos normalmente se crean con el operador `new`. Sin embargo, es posible que en un determinado momento sea necesario que sólo exista una instancia de una clase concreta (prevención de errores, seguridad, creación costosa, etc..).\n\nPara garantizar que sólo existe una instancia de una clase es necesario que los clientes no puedan acceder directamente al constructor. Por ello, cuando se aplica el **_'Singleton Pattern'_** el constructor es, por lo menos, `protected` o `private`. A cambio se debe proporcionar un único punto controlado por el cual se pide la instancia única.\n\nLa instrumentación del patrón puede ser delicada en programas con múltiples hilos de ejecución. Si dos hilos de ejecución intentan crear la instancia al mismo tiempo y esta no existe todavía, sólo uno de ellos debe lograr crear el objeto.\n\nEl **_'Singleton Pattern'_** puede ser utilizado para modelar:\n\n- Gestores de acceso a base de datos, sistemas de ficheros, _render_ de gráficos, etc..\n\n- Estructuras que representan la configuración del programa para que sea accesible por todos los elementos en  cualquier instante.\n\n#### Caso práctico\n\nEl **_'Singleton Pattern'_** provee una única instancia global gracias a que:\n\n- La propia clase es responsable de crear la única instancia.\n\n- Permite el acceso global a dicha instancia mediante un método de clase.\n\n- Declara el contructor de clase como privado para que no sea instanciable directamente.\n\nEn este ejemplo, primero hemos hecho que el constructor sea privado, de modo que no podemos crear instancias de manera normal. Además, al proporcionar un constructor privado, evitamos que el compilador genere un constructor por defecto. Cuando intentamos crear una instancia de la clase, estamos comprobando si ya tenemos una copia disponible. Si no tenemos una copia de ese tipo, la crearemos; de lo contrario, simplemente reutilizaremos la copia existente.\n\nLa inicialización de la instancia se denomina _'lazy initialization'_ ya que la instancia no se crea hasta que el método `getINSTANCE()` se invoca.\n\n```java\npublic class Singleton {\n    private static Singleton instance = null;\n\n    // Constructor privado\n    private Singleton() {}\n\n    // Lazy initialization\n    public static Singleton getInstance() {\n        if (instance == null) {\n            instance = new Singleton();\n        }\n        return instance;\n    }\n}\n\n// Modo 'Lazy Initialization'\npublic class Singleton {\n    private static Singleton instance = null;\n\n    // Constructor privado\n    private SingletonSyncronized() {}\n\n    // Creador sincronizado para protegerse de posibles problemas multi-hilo\n    private static synchronized void createInstance() {\n        if (instance == null) {\n            instance = new Singleton();\n        }\n    }\n\n    public static Singleton getInstance() {\n        if (instance == null) {\n            createInstance();\n        }\n        return instance;\n    }\n}\n\n// Modo 'Early Initialization'\npublic class Singleton {\n\n    // Early initialization\n    private static Singleton instance = new Singleton();\n\n    private Singleton() {}\n\n    public static Singleton getInstance() {\n        return instance;\n    }\n}\n```\n\n#### Consideraciones\n\nEl **_'Singleton Pattern'_** es un caso particular de un patrón de diseño más general llamado **_'Object Pool'_**, que permite crear **n instancias de objetos de forma controlada**.\n\n#### Referencias\n\n- \u003chttps://refactoring.guru/es/design-patterns/singleton\u003e\n- \u003chttps://sourcemaking.com/design_patterns/singleton\u003e\n- \u003chttps://www.baeldung.com/java-singleton\u003e\n- \u003chttps://www.tutorialspoint.com/design_pattern/singleton_pattern\u003e\n- \u003chttps://www.digitalocean.com/community/tutorials/java-singleton-design-pattern-best-practices-examples\u003e\n- \u003chttps://java-design-patterns.com/es/patterns/singleton/\u003e\n\n---\n\n## _Structural Patterns_\n\nLos patrones estructurales son los patrones de diseño de software que solucionan problemas de composición (agregación) de clases y objetos.\n\nLos patrones estructurales son [**_Adapter_**](#adapter-pattern), [**_Bridge_**](#bridge-pattern), [**_Composite_**](#composite-pattern), [**_Decorator_**](#decorator-pattern), [**_Facade_**](#facade-pattern), [**_Flyweight_**](#flyweight-pattern) y [**_Proxy_**](#proxy-pattern).\n\n- \u003chttps://www.baeldung.com/java-core-structural-patterns\u003e\n\n### _\"Adapter Pattern\"_\n\n\u003c!-- markdownlint-disable MD033 --\u003e\n\u003cdiv style=\"text-align: center;\"\u003e\n  \u003cimg src=\".//media//patterns//structural//adapter/adapter_header.png\" alt=\"adapter_pattern_intro\" width=\"475\" height=\"auto\"\u003e\n  \u003cp style=\"font-size: 0.75em;\"\u003e\u0026#169; Refactoring Guru\u003c/p\u003e\n\u003c/div\u003e\n\u003c!-- markdownlint-disable MD033 --\u003e\n\n\u003e **_Convierte la interfaz de una clase en otra interfaz que los clientes esperan. Este patrón permite que las clases trabajen juntas que de otra manera no podrían hacerlo debido a interfaces incompatibles._**\n\u003e\n\u003e _-- GoF_\n\n#### Concepto\n\nEl **_'Adapter Pattern'_**, también conocido como **_'wrapper'_** (envoltorio), se utiliza para proporcionar una interfaz que, por un lado, cumpla con las demandas de los clientes y, por otra, haga compatible otra interfaz que, a priori, no lo es. Dicho de otra forma, se utiliza para **transformar una interfaz en otra**, de tal modo que una clase que no pudiera utilizar la primera, haga uso de ella a través de la segunda.\n\nConforme avanza la construcción de una aplicación, el diseño de las interfaces que ofrecen los componentes pueden no ser las adecuadas o, al menos, las esperadas por los usuarios de los mismos.\n\nUna solución rápida podría ser adaptar dichas interfaces a las necesidades de la aplicación. Sin embargo, esto no siempre es posible debido a que no se pueda modificar el código porque sea un requisito funcional, sea una biblioteca de terceros, etc...\n\nUsando el **_'Adapter Pattern'_** es posible crear una nueva interfaz de acceso a un determinado objeto, por lo que proporciona un mecanismo de **adaptación** entre las demandas del objeto cliente y el objeto servidor que proporciona la funcionalidad.\n\n#### Caso práctico\n\nEl cliente no utiliza el sistema adaptado, si no que hace uso del _adaptador_. Este es el que transforma la invocación a `method()` en `otherMethod()`.\n\nEs posible que el adaptador también incluya nueva funcionalidad relacionada con la adaptación como por ejemplo:\n\n- Comprobación de la corrección de los parámetros.\n\n- Transformación de los parámetros para ser compatibles con el sistema adaptado.\n\n```java\ninterface Target {\n    String method();\n}\n\nclass Adapter implements Target {\n    @Override\n    public String method() {\n        OtherSystem otherSystem = new OtherSystem();\n        return otherSystem.otherMethod();\n    }\n}\n\nclass OtherSystem {\n    String otherMethod() {\n        return OtherSystem.class.getSimpleName();\n    }\n}\n\npublic class Client {\n    public static void main(String[] args) {\n        Target target = new patterns.structural.adapter.example.Adapter();\n        System.out.println(\"Método adaptado: \" + target.method());\n    }\n}\n```\n\n#### Consideraciones\n\nTener sistemas muy reutilizables puede hacer que las interfaces no puedan ser compatibles con una interfaz en común. En ese caso el **_'Adapter Pattern'_** es una buena solución.\n\nAdemás, un mismo adaptador puede usarse en varios sistemas.\n\nEste patrón se parece al **_'Decorator Pattern'_**. Sin embargo, difieren en que la finalidad de éste es proporcionar una interfaz completa del objeto adaptador, mientras que el decorador pueden centrarse en una sola parte.\n\n#### Referencias\n\n- \u003chttps://refactoring.guru/es/design-patterns/adapter\u003e\n- \u003chttps://sourcemaking.com/design_patterns/adapter\u003e\n- \u003chttps://www.baeldung.com/java-adapter-pattern\u003e\n- \u003chttps://www.tutorialspoint.com/design_pattern/adapter_pattern\u003e\n- \u003chttps://www.digitalocean.com/community/tutorials/adapter-design-pattern-java\u003e\n- \u003chttps://java-design-patterns.com/es/patterns/adapter/\u003e\n\n---\n\n### _\"Bridge Pattern\"_\n\n\u003c!-- markdownlint-disable MD033 --\u003e\n\u003cdiv style=\"text-align: center;\"\u003e\n  \u003cimg src=\".//media//patterns//structural//bridge/bridge_header.png\" alt=\"bridge_pattern_intro\" width=\"475\" height=\"auto\"\u003e\n  \u003cp style=\"font-size: 0.75em;\"\u003e\u0026#169; Refactoring Guru\u003c/p\u003e\n\u003c/div\u003e\n\u003c!-- markdownlint-disable MD033 --\u003e\n\n\u003e **_Desacoplar una abstracción de su implementación para que ambos puedan variar independientemente._**\n\u003e\n\u003e _-- GoF_\n\n#### Concepto\n\nEste patrón es una técnica usada en programación para **desacoplar una abstracción de su implementación**, de manera que ambas puedan ser modificadas independientemente sin necesidad de alterar por ello la otra. Esto es, se desacopla una abstracción de su implementación para que puedan variar independientemente.\n\nDigamos que tenemos la clase `Shape` con un par de subclases: `Circle` y `Square`. Si incorporamos el color a la jerarquía de clases debemos combinar las subclases con el nuevo requisito creando subclases como `BlueCircle` o `RedSquare`. Si en un futuro es necesario incorporar una nueva forma o un nuevo color, deberemos combinar esta nueva subclase o color con las formas o colores ya existentes, aumentando exponencialmente el número de subclases.\n\n\u003c!-- markdownlint-disable MD033 --\u003e\n\u003cdiv style=\"text-align: center;\"\u003e\n  \u003cimg src=\".//media//patterns//structural//bridge/bridge_concept_01.png\" alt=\"bridge_pattern_concept\" width=\"475\" height=\"auto\"\u003e\n  \u003cp style=\"font-size: 0.75em;\"\u003e\u0026#169; Refactoring Guru\u003c/p\u003e\n\u003c/div\u003e\n\u003c!-- markdownlint-disable MD033 --\u003e\n\nEste problema ocurre porque estamos tratando de extender las clases de formas en dos dimensiones independientes: por forma y por color. Ese es un problema muy común con la herencia de clases.\n\nEl **_'Bridge Pattern'_** intenta resolver este problema cambiando de herencia a composición. Lo que esto significa es que extrae una de las dimensiones en una jerarquía de clases separada, de modo que las clases originales hagan referencia a un objeto de la nueva jerarquía, en lugar de tener todos sus estados y comportamientos dentro de una clase.\n\n\u003c!-- markdownlint-disable MD033 --\u003e\n\u003cdiv style=\"text-align: center;\"\u003e\n  \u003cimg src=\".//media//patterns//structural//bridge/bridge_concept_02.png\" alt=\"bridge_pattern_concept\" width=\"475\" height=\"auto\"\u003e\n  \u003cp style=\"font-size: 0.75em;\"\u003e\u0026#169; Refactoring Guru\u003c/p\u003e\n\u003c/div\u003e\n\u003c!-- markdownlint-disable MD033 --\u003e\n\nEn la definición de **GoF** se introducen los conceptos de _\"abstración\"_ e _\"implementación\"_. La abstracción y la implementación se pueden representar a través de una interfaz o una clase abstracta, pero la abstracción contiene una referencia a su implementador. Normalmente, un hijo de una abstracción se llama una _'refined abstraction'_ y un hijo de una implementación se llama _'concrete implementation'_.\n\n- _**Abstraction**_ define una interfaz abstracta. Mantiene una referencia a un objeto de tipo _'Implementor'_.\n\n- _**RefinedAbstraction**_ extiende la interfaz definida por _'Abstraction'_.\n\n- _**Implementor**_ define la interfaz para la implementación de clases. Esta interfaz no se tiene que corresponder exactamente con la interfaz de _'Abstraction'_; de hecho, las dos interfaces pueden ser bastante diferente. Típicamente la interfaz _'Implementor'_ provee sólo operaciones primitivas, y _'Abstraction'_ define operaciones de alto nivel basadas en estas primitivas.\n\n- _**ConcreteImplementor**_ implementa la interfaz de Implementor y define su implementación concreta.\n\nEste patrón mejora la extensibilidad ya que permite que se puedan extender las jerarquías de clases de forma independientemente, sin afectarse entre sí.\n\nEsto se debe a que se desacopla la interfaz de la implementación. Una implementación no es limitada permanentemente a una interfaz. La implementación de una abstracción puede ser configurada en tiempo de ejecución. Además le es posible a un objeto cambiar su implementación en tiempo de ejecución.\n\nDesacoplando _'Abstraction'_ e _'Implementor'_ también elimina las dependencias sobre la implementación en tiempo de compilación. Cambiar una clase de implementación no requiere recompilar la clase _'Abstraction'_ ni sus clientes. Es más, este desacoplamiento fomenta las capas, que pueden conducir a un sistema mejor estructurado. La parte de alto nivel de un sistema sólo tiene que conocer _'Abstraction'_ e _'Implementor'_.\n\n#### Caso práctico\n\n1. Identificar las dimensiones independientes en tus clases. Estos conceptos independientes podrían ser: abstracción/plataforma, dominio/infraestructura, front-end/back-end o interfaz/implementación.\n\n1. Ver qué operaciones necesita el cliente y definirlas en la clase de abstracción base.\n\n1. Determinar las operaciones disponibles en todas las plataformas. Declare los que necesita la abstracción en la interfaz de implementación general.\n\n1. Para todas las plataformas en su dominio, cree clases de implementación concretas, pero asegúrese de que todas sigan la interfaz de implementación.\n\n1. Dentro de la clase de abstracción, agregue un campo de referencia para el tipo de implementación. La abstracción delega la mayor parte del trabajo al objeto de implementación al que se hace referencia en ese campo.\n\n1. Si tiene varias variantes de lógica de alto nivel, cree abstracciones refinadas para cada variante extendiendo la clase de abstracción base.\n\n1. El código del cliente debe pasar un objeto de implementación al constructor de la abstracción para asociar uno con el otro. Después de eso, el cliente puede olvidarse de la implementación y trabajar solo con el objeto de abstracción.\n\n```java\ninterface Abstraction {\n    void operation();\n}\n\ninterface Implementor {\n    void operation();\n}\n\nclass RefinedAbstraction implements Abstraction {\n    private Implementor implementor;\n\n    RefinedAbstraction(Implementor implementor) {\n        this.implementor = implementor;\n    }\n\n    public void operation() {\n        implementor.operation();\n    }\n}\n\nclass ImplementorA implements Implementor {\n    @Override\n    public void operation() {\n        // ...\n    }\n}\n\nclass ImplementorB implements Implementor {\n    @Override\n    public void operation() {\n        // ...\n    }\n}\n```\n\n#### Consideraciones\n\nUtilice el **_'Bridge Pattern'_** cuando desee dividir y organizar una clase monolítica que tenga varias variantes de alguna funcionalidad (por ejemplo, si la clase puede trabajar con varios servidores de bases de datos). Este patrón le permite dividir la clase monolítica en varias jerarquías de clase. Después de esto, puede cambiar las clases en cada jerarquía independientemente de las clases en las otras. Este enfoque simplifica el mantenimiento del código y minimiza el riesgo de romper el código existente.\n\nUse el patrón cuando necesite extender una clase en varias dimensiones ortogonales (independientes). El patrón sugiere que extraiga una jerarquía de clases separada para cada una de las dimensiones. La clase original delega el trabajo relacionado a los objetos que pertenecen a esas jerarquías en lugar de hacer todo por sí solo\n\nTambién cuando se necesite poder cambiar de implementación en tiempo de ejecución. Aunque es opcional, este patrón permite reemplazar el objeto de implementación dentro de la abstracción. Es tan fácil como asignar un nuevo valor a un campo.\n\nEl uso de este patrón tiene ciertas ventajas:\n\nEl código del cliente funciona con abstracciones de alto nivel y no está expuesto a los detalles de la plataforma.\n\nLa desventaja de este patrón es que puede hacer que el código sea más complicado aplicando el patrón a una clase altamente cohesiva.\n\n#### Referencias\n\n- \u003chttps://refactoring.guru/es/design-patterns/bridge\u003e\n- \u003chttps://sourcemaking.com/design_patterns/bridge\u003e\n- \u003chttps://www.baeldung.com/java-bridge-pattern\u003e\n- \u003chttps://www.tutorialspoint.com/design_pattern/bridge_pattern\u003e\n- \u003chttps://www.digitalocean.com/community/tutorials/bridge-design-pattern-java\u003e\n- \u003chttps://java-design-patterns.com/es/patterns/bridge/\u003e\n\n---\n\n### _\"Composite Pattern\"_\n\n\u003c!-- markdownlint-disable MD033 --\u003e\n\u003cdiv style=\"text-align: center;\"\u003e\n  \u003cimg src=\".//media//patterns//structural//composite/composite_header.png\" alt=\"composite_pattern_intro\" width=\"475\" height=\"auto\"\u003e\n  \u003cp style=\"font-size: 0.75em;\"\u003e\u0026#169; Refactoring Guru\u003c/p\u003e\n\u003c/div\u003e\n\u003c!-- markdownlint-disable MD033 --\u003e\n\n\u003e **_Componer objetos en estructuras de árbol para representar jerarquías parciales. Este patrón permite a los clientes tratar objetos individuales y composiciones de objetos de manera uniforme._**\n\u003e\n\u003e _-- GoF_\n\n#### Concepto\n\nEl **_'Composite Pattern'_** sirve para construir objetos complejos a partir de otros más simples y similares entre sí gracias a la composición recursiva y a una estructura en forma de árbol.\n\nEsto simplifica el tratamiento de los objetos creados ya que al poseer todos ellos una interfaz común, se tratan todos de la misma manera. Un cliente puede tratar un objeto compuesto como si fuera un solo objeto.\n\nUna buena manera de identificar la situación en que se puede aplicar este patrón es cuando tengo \"un X y tiene varios objetos X\".\n\n#### Caso práctico\n\nPara ilustrar el problema supóngase un juego de estrategia en el que los jugadores pueden recoger objetos o items, los cuales tienen una serie de propiedades como \"precio\", \"descripción\", etc. Cada item, a su vez, puede contener otros items. Por ejemplo, un bolso de cuero puede contener una pequeña caja de madera que, a su vez, contiene un pequeño reloj dorado, etc..\n\n\u003c!-- markdownlint-disable MD033 --\u003e\n\u003cdiv style=\"text-align: center;\"\u003e\n  \u003cimg src=\".//media//patterns//structural//composite/composite_diagram.png\" alt=\"composite_pattern_diagram\" width=\"475\" height=\"auto\"\u003e\n\u003c/div\u003e\n\u003c!-- markdownlint-disable MD033 --\u003e\n\nEn definitiva, el **_'Composite Pattern'_** habla sobre cómo diseñar estructuras recursivas donde la composición homogénea de objetos recuerda a una estructura arbórea.\n\nNaturalmente, los objetos compuestos suelen ofrecer también operaciones para añadir, eliminar y actualizar.\n\n```java\nclass Item {\n    void value() {\n        // ...\n    }\n\n    void description() {\n        // ...\n    }\n}\n\nclass Clock extends Item {\n    @Override\n    void value() {\n        super.value();\n    }\n\n    @Override\n    void description() {\n        super.description();\n    }\n}\n\nclass Bag extends Item {\n    private List\u003cItem\u003e bag = new ArrayList\u003c\u003e();\n\n    void addItem(Item item) {\n        bag.add(item);\n    }\n\n    boolean removeItem(Item item) {\n        return bag.contains(item) \u0026\u0026 bag.remove(item);\n    }\n}\n```\n\n#### Consideraciones\n\nLos clientes pueden añadir nuevos tipos de componentes fácilmente.\n\n#### Referencias\n\n- \u003chttps://refactoring.guru/es/design-patterns/composite\u003e\n- \u003chttps://sourcemaking.com/design_patterns/composite\u003e\n- \u003chttps://www.baeldung.com/java-composite-pattern\u003e\n- \u003chttps://www.tutorialspoint.com/design_pattern/composite_pattern\u003e\n- \u003chttps://www.digitalocean.com/community/tutorials/composite-design-pattern-in-java\u003e\n- \u003chttps://java-design-patterns.com/es/patterns/composite/\u003e\n\n---\n\n### _\"Decorator Pattern\"_\n\n\u003c!-- markdownlint-disable MD033 --\u003e\n\u003cdiv style=\"text-align: center;\"\u003e\n  \u003cimg src=\".//media//patterns//structural//decorator/decorator_header.png\" alt=\"decorator_pattern_intro\" width=\"475\" height=\"auto\"\u003e\n  \u003cp style=\"font-size: 0.75em;\"\u003e\u0026#169; Refactoring Guru\u003c/p\u003e\n\u003c/div\u003e\n\u003c!-- markdownlint-disable MD033 --\u003e\n\n\u003e **_Asignar responsabilidades adicionales a un objeto de forma dinámica. Los decoradores ofrecen una alternativa flexible a la subclasificación para ampliar la funcionalidad._**\n\u003e\n\u003e _-- GoF_\n\n#### Concepto\n\nEl **_'Decorator Pattern'_** sirve para **añadir y/o modificar la responsabilidad, funcionalidad o propiedades de un objeto en tiempo de ejecución**. Permite organizar el diseño de forma que la incorporación de nueva funcionalidad en tiempo de ejecución sea transparente desde el punto de vista del usuario de la **clase decorada**.\n\nEste patrón permite tener una jerarquía de clases compuestas, formando una estructura más dinámica y flexible que la herencia estática. Al utilizar este patrón, se pueden añadir y eliminar responsabilidades en tiempo de ejecución. Además, evita la utilización de la herencia con muchas clases y también, la herencia múltiple (si fuera posible en el lenguaje utilizado).\n\n#### Caso práctico\n\nSupongamos que el personaje de un videojuego porta un arma que utiliza para eliminar a sus enemigos. Dicha arma, por ser de un tipo determinado, tiene una serie de propiedades como podrían ser \"radio de acción\", \"número de balas\", etc.. Sin embargo, es posible que el personaje incorpore elementos al arma que pueden cambiar estas propiedades como un silenciador o un cargador extra.\n\n\u003c!-- markdownlint-disable MD033 --\u003e\n\u003cdiv style=\"text-align: center;\"\u003e\n  \u003cimg src=\".//media//patterns//structural//decorator/decorator_diagram.png\" alt=\"decorator_pattern_diagram\" width=\"475\" height=\"auto\"\u003e\n\u003c/div\u003e\n\u003c!-- markdownlint-disable MD033 --\u003e\n\nBásicamente, los diferentes tipos de armas de fuego implementan una clase abstracta llamada `Firearm`. Una de sus subclases es `FirearmDecorator` que a su vez es la superclase de todos los componentes que _\"decoran\"_ a un objeto `Firearm`. Nótese que este decorador implementa la interfaz propuesta por `Firearm` y está compuesto por un objeto _'gun'_, el cual decora.\n\n```java\nclass Firearm {\n    private static final int MAX_BULLETS = 5;\n    private static final float GENERIC_NOISE = 150.0f;\n\n    float noise() {\n        return GENERIC_NOISE;\n    }\n\n    int bullets() {\n        return MAX_BULLETS;\n    }\n}\n\nclass Rifle extends Firearm {\n    @Override\n    float noise() {\n        return super.noise();\n    }\n\n    @Override\n    int bullets() {\n        return super.bullets();\n    }\n}\n\nclass FirearmDecorator extends Firearm {\n    private Firearm gun;\n\n    FirearmDecorator(Firearm gun) {\n        this.gun = gun;\n    }\n\n    @Override\n    float noise() {\n        return gun.noise();\n    }\n\n    @Override\n    int bullets() {\n        return gun.bullets();\n    }\n}\n\nclass Silencer extends FirearmDecorator {\n    Silencer(Firearm gun) {\n        super(gun);\n    }\n\n    @Override\n    float noise() {\n        return super.noise() - 55;\n    }\n\n    @Override\n    int bullets() {\n        return super.bullets();\n    }\n}\n\nclass Magazine extends FirearmDecorator {\n    Magazine(Firearm gun) {\n        super(gun);\n    }\n\n    @Override\n    float noise() {\n        return super.noise();\n    }\n\n    @Override\n    int bullets() {\n        return super.bullets() + 5;\n    }\n}\n```\n\n#### Consideraciones\n\nEl **_'Decorator Pattern'_** está más centrado en la extensión de la funcionalidad que en la composición de objetos para la generación de una jerarquía como ocurre con el **_'Composite Pattern'_**.\n\nNormalmente, sólo existe una objeto decorado y no un vector de objetos (aunque también es posible).\n\nEste patrón puede generar gran cantidad de objetos pequeños y parecidos que dificulta su identificación.\n\nEste patrón se diferencia de la simple herencia en que podemos añadir o quitar responsabilidades simplemente adjuntando o quitando decoradores. Pero únicamente con la herencia, necesitamos crear una nueva clase para nuevas responsabilidad","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falxgcrz%2F_design-patterns_","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falxgcrz%2F_design-patterns_","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falxgcrz%2F_design-patterns_/lists"}