+
+
+
\ No newline at end of file
diff --git a/examen-sesiones/ejercicio1/header.php b/examen-sesiones/ejercicio1/header.php
new file mode 100644
index 00000000..ca452ae5
--- /dev/null
+++ b/examen-sesiones/ejercicio1/header.php
@@ -0,0 +1,18 @@
+
+
+
\ No newline at end of file
diff --git "a/practicas/patrones de dise\303\261o/componentes/nav.php" "b/practicas/patrones de dise\303\261o/componentes/nav.php"
new file mode 100644
index 00000000..8134228d
--- /dev/null
+++ "b/practicas/patrones de dise\303\261o/componentes/nav.php"
@@ -0,0 +1,22 @@
+
\ No newline at end of file
diff --git "a/practicas/patrones de dise\303\261o/index.php" "b/practicas/patrones de dise\303\261o/index.php"
new file mode 100644
index 00000000..44e759d5
--- /dev/null
+++ "b/practicas/patrones de dise\303\261o/index.php"
@@ -0,0 +1,73 @@
+
+
+
+
+
+ Patrones de Diseño
+
+
+
+
+
+
Patrones de Diseño
+
Los patrones de diseño (design patterns) son soluciones habituales a problemas comunes en el diseño de software.
+ Cada patrón es como un plano que se puede personalizar para resolver un problema de diseño particular de tu código.
+
+
+
+
+
+
Patrones Creacionales
+
Estos patrones proporcionan mecanismos para la creación de objetos que aumentan la flexibilidad y reutilización del código.
+
+
+
+
diff --git "a/practicas/patrones de dise\303\261o/patrones/comportamiento-Chain.php" "b/practicas/patrones de dise\303\261o/patrones/comportamiento-Chain.php"
new file mode 100644
index 00000000..3721d120
--- /dev/null
+++ "b/practicas/patrones de dise\303\261o/patrones/comportamiento-Chain.php"
@@ -0,0 +1,188 @@
+
+
+
+
+
+
+
+ Patrón Chain of Responsibility
+
+
+
+
+
+
+
Patrón Chain of Responsibility
+
+
+
Propósito
+
El patrón Chain of Responsibility permite pasar una solicitud a lo largo de una cadena de manejadores. Cada manejador decide si procesa la solicitud o la pasa al siguiente de la cadena.
+
+
+
+
Problema
+
Supongamos que tienes un sistema de pedidos en línea y necesitas verificar varias cosas, como la autenticación del usuario y la validación de datos, pero no quieres que todo el código se vuelva complejo y difícil de gestionar.
+
+
+
+
Solución
+
Con Chain of Responsibility, puedes organizar las verificaciones en diferentes manejadores, y cada uno decide si puede manejar la solicitud o si la pasa al siguiente manejador en la cadena.
+
+
+
+
Analogía en el mundo real
+
Es como cuando llamas al soporte técnico. Primero hablas con un contestador automático, luego con un operador y, finalmente, con un ingeniero. Cada uno maneja la solicitud y si no puede, la pasa al siguiente nivel.
+
+
+
+
Estructura
+
+
Interfaz Manejadora: Define un método para procesar solicitudes.
+
Manejadores Concretos: Implementan la lógica para procesar una solicitud específica.
+
Cliente: Puede componer la cadena de manejadores según sea necesario.
+
+
+
+
+
Pseudocódigo
+
+
+// Interfaz de manejo
+interface Handler {
+ method handleRequest(request)
+}
+
+// Manejador concreto que verifica la autenticación
+class AuthenticationHandler implements Handler {
+ method handleRequest(request) {
+ if (request.isAuthenticated()) {
+ nextHandler.handleRequest(request)
+ } else {
+ reject(request)
+ }
+ }
+}
+
+// Manejador concreto que valida los datos
+class ValidationHandler implements Handler {
+ method handleRequest(request) {
+ if (request.isValid()) {
+ nextHandler.handleRequest(request)
+ } else {
+ reject(request)
+ }
+ }
+}
+
+// Cliente que configura la cadena de manejadores
+class RequestProcessor {
+ private field handlerChain: Handler
+
+ constructor RequestProcessor(handlerChain: Handler) {
+ this.handlerChain = handlerChain
+ }
+
+ method process(request) {
+ handlerChain.handleRequest(request)
+ }
+}
+
+// La aplicación utiliza la cadena de responsabilidad
+class Application {
+ method init() {
+ authHandler = new AuthenticationHandler()
+ validationHandler = new ValidationHandler()
+ authHandler.setNext(validationHandler)
+ processor = new RequestProcessor(authHandler)
+ processor.process(request)
+ }
+}
+
+
+
+
+
+
Aplicabilidad
+
+
Cuando tienes una serie de verificaciones que se deben realizar de manera secuencial, pero no sabes de antemano el orden o las verificaciones que se van a hacer.
+
Cuando quieres separar responsabilidades en diferentes clases y hacer que sean fáciles de extender.
+
+
+
+
+
Cómo implementarlo
+
+
Crea una interfaz manejadora que defina el método común para manejar solicitudes.
+
Crea los manejadores concretos con la lógica específica para manejar las solicitudes.
+
Configura la cadena de manejadores según sea necesario, pasando las solicitudes a través de ellos.
+
+
+
+
+
Pros y Contras
+
+
Pros: Hace el código más flexible y modular, permite agregar nuevos manejadores sin romper el código cliente.
+
Contras: Algunas solicitudes pueden no ser procesadas si no hay manejadores adecuados.
+
+
+
+
+
Relaciones con otros patrones
+
+
Command: Ambos patrones permiten mover solicitudes entre objetos, pero Chain of Responsibility pasa la solicitud a través de una cadena de manejadores.
+
Mediator: Mientras que el patrón Mediator centraliza la comunicación, Chain of Responsibility permite que los manejadores trabajen de manera independiente.
+
Observer: Ambos patrones permiten que objetos reaccionen a eventos, pero Chain of Responsibility pasa las solicitudes en lugar de reaccionar a cambios de estado.
+
+
+
+
+
+
+
+
diff --git "a/practicas/patrones de dise\303\261o/patrones/comportamiento-Command.php" "b/practicas/patrones de dise\303\261o/patrones/comportamiento-Command.php"
new file mode 100644
index 00000000..f10f5313
--- /dev/null
+++ "b/practicas/patrones de dise\303\261o/patrones/comportamiento-Command.php"
@@ -0,0 +1,208 @@
+
+
+
+
+
+
+
+ Patrón Command
+
+
+
+
+
+
+
Patrón Command
+
+
+
Propósito
+
El patrón Command convierte una solicitud en un objeto autónomo, lo que permite parametrizar los objetos con solicitudes, retrasar la ejecución de una solicitud y manejar las solicitudes de forma más flexible.
+
+
+
+
Problema
+
Supón que tienes una interfaz de usuario con múltiples botones y cada botón realiza una acción diferente. En lugar de tener que escribir el código de cada acción en cada parte del sistema, quieres encapsularlas de manera que sea más fácil manejarlas y extenderlas.
+
+
+
+
Solución
+
El patrón Command te permite encapsular las solicitudes de los usuarios como objetos, permitiendo pasar estas solicitudes como parámetros, almacenarlas, deshacerlas o ejecutar múltiples acciones en secuencia de manera flexible.
+
+
+
+
Analogía en el mundo real
+
Es como si tuvieras un asistente personal que, cuando le das una orden, esta se convierte en una tarea que él puede ejecutar más tarde, o incluso delegar a otra persona si es necesario.
+
+
+
+
Estructura
+
+
Comando: Define una interfaz para ejecutar una operación.
+
Comando Concreto: Implementa la interfaz de comando y define la acción específica a ejecutar.
+
Invocador: Pide al comando ejecutar una solicitud.
+
Receptor: Realiza la acción asociada con el comando.
+
+
+
+
+
Pseudocódigo
+
+
+// Interfaz de comando
+interface Command {
+ method execute()
+}
+
+// Comando concreto que realiza una acción específica
+class LightOnCommand implements Command {
+ private field light: Light
+
+ constructor LightOnCommand(light: Light) {
+ this.light = light
+ }
+
+ method execute() {
+ light.turnOn()
+ }
+}
+
+class LightOffCommand implements Command {
+ private field light: Light
+
+ constructor LightOffCommand(light: Light) {
+ this.light = light
+ }
+
+ method execute() {
+ light.turnOff()
+ }
+}
+
+// Receptor que conoce cómo ejecutar las acciones reales
+class Light {
+ method turnOn() {
+ print("La luz está encendida.")
+ }
+
+ method turnOff() {
+ print("La luz está apagada.")
+ }
+}
+
+// Invocador que solicita al comando ejecutar la acción
+class RemoteControl {
+ private field command: Command
+
+ method setCommand(command: Command) {
+ this.command = command
+ }
+
+ method pressButton() {
+ command.execute()
+ }
+}
+
+// Cliente que configura los comandos
+class Application {
+ method init() {
+ light = new Light()
+ lightOn = new LightOnCommand(light)
+ lightOff = new LightOffCommand(light)
+
+ remote = new RemoteControl()
+ remote.setCommand(lightOn)
+ remote.pressButton() // La luz está encendida.
+ remote.setCommand(lightOff)
+ remote.pressButton() // La luz está apagada.
+ }
+}
+
+
+
+
+
+
Aplicabilidad
+
+
Cuando necesitas invocar operaciones en diferentes objetos de manera desacoplada.
+
Cuando deseas permitir la desactivación, ejecución o ejecución repetida de comandos.
+
Cuando el sistema debe manejar un conjunto de operaciones pero no quieres que el invocador dependa de los detalles de ejecución de esas operaciones.
+
+
+
+
+
Cómo implementarlo
+
+
Crea una interfaz común para los comandos que defina el método `execute`.
+
Crea los comandos concretos que implementan la interfaz y realizan las acciones específicas.
+
Configura un invocador que reciba y ejecute los comandos, permitiendo cambiar dinámicamente las acciones a realizar.
+
+
+
+
+
Pros y Contras
+
+
Pros: Desacopla los invocadores de las acciones específicas, permite deshacer acciones, y es fácil agregar nuevas acciones sin modificar el invocador.
+
Contras: El sistema puede volverse complejo cuando hay muchos comandos, especialmente si no se organiza adecuadamente.
+
+
+
+
+
Relaciones con otros patrones
+
+
Chain of Responsibility: Ambos patrones permiten que una solicitud sea manejada por varios objetos, pero en Command, el objeto que recibe la solicitud es explícitamente invocado, mientras que en Chain of Responsibility se pasa a lo largo de una cadena de objetos.
+
Strategy: Ambos patrones permiten cambiar el comportamiento de un objeto en tiempo de ejecución. Sin embargo, Strategy enfoca en cambiar el algoritmo, mientras que Command se enfoca en encapsular la solicitud como objeto.
+
Observer: Ambos patrones pueden involucrar la ejecución de acciones en respuesta a eventos, pero Command encapsula una acción, mientras que Observer se enfoca en notificar a los observadores.
+
+
+
+
+
+
+
+
diff --git "a/practicas/patrones de dise\303\261o/patrones/comportamiento-Iterator.php" "b/practicas/patrones de dise\303\261o/patrones/comportamiento-Iterator.php"
new file mode 100644
index 00000000..9955e771
--- /dev/null
+++ "b/practicas/patrones de dise\303\261o/patrones/comportamiento-Iterator.php"
@@ -0,0 +1,217 @@
+
+
+
+
+
+
+
+ Patrón Iterator
+
+
+
+
+
+
+
Patrón Iterator
+
+
+
Propósito
+
Iterator es un patrón de diseño de comportamiento que te permite recorrer elementos de una colección sin exponer su representación subyacente (lista, pila, árbol, etc.).
+
+
+
+
Problema
+
Las colecciones son de los tipos de datos más utilizados en programación. Sin embargo, una colección tan solo es un contenedor para un grupo de objetos.
+
Varios tipos de colecciones almacenan sus elementos de maneras distintas (listas, pilas, árboles, grafos, etc.). Necesitas una forma de recorrer cada elemento de la colección sin tener que acceder directamente a ellos de manera repetitiva. Diferentes estructuras pueden requerir diferentes algoritmos de recorrido, lo que complica el código cliente.
+
+
+
+
Solución
+
La idea central del patrón Iterator es extraer el comportamiento de recorrido de una colección y colocarlo en un objeto independiente llamado iterador. Los iteradores implementan varios algoritmos de recorrido, y múltiples iteradores pueden recorrer la misma colección de forma independiente.
+
Este patrón asegura que el cliente no dependa de la estructura interna de la colección y pueda usar un algoritmo de recorrido sin preocuparse por su implementación.
+
+
+
+
Analogía en el mundo real
+
Es como cuando visitas Roma: puedes hacerlo siguiendo un mapa, utilizando una aplicación móvil o contratando a un guía turístico. Cada una de estas opciones actúa como un iterador sobre las distintas atracciones de la ciudad.
+
+
+
+
Estructura
+
+
Interfaz Iteradora: Declara las operaciones necesarias para recorrer una colección, como obtener el siguiente elemento o verificar si hay más elementos.
+
Iteradores Concretos: Implementan algoritmos específicos para recorrer la colección.
+
Interfaz Colección: Declara un método para obtener iteradores compatibles con la colección.
+
Colecciones Concretas: Implementan la interfaz Colección y retornan instancias de iteradores concretos.
+
Cliente: Trabaja con colecciones e iteradores a través de sus interfaces, sin acoplarse a clases específicas.
+
+
+
+
+
Pseudocódigo
+
+
+// La interfaz de colección debe declarar un método fábrica para
+// producir iteradores.
+interface SocialNetwork is
+ method createFriendsIterator(profileId): ProfileIterator
+ method createCoworkersIterator(profileId): ProfileIterator
+
+// Facebook implementa la interfaz SocialNetwork
+class Facebook implements SocialNetwork is
+ method createFriendsIterator(profileId) is
+ return new FacebookIterator(this, profileId, "friends")
+ method createCoworkersIterator(profileId) is
+ return new FacebookIterator(this, profileId, "coworkers")
+
+// La interfaz común a todos los iteradores.
+interface ProfileIterator is
+ method getNext(): Profile
+ method hasMore(): bool
+
+// Clase iteradora concreta
+class FacebookIterator implements ProfileIterator is
+ private field facebook: Facebook
+ private field profileId, type: string
+ private field currentPosition
+ private field cache: array of Profile
+
+ constructor FacebookIterator(facebook, profileId, type) is
+ this.facebook = facebook
+ this.profileId = profileId
+ this.type = type
+
+ private method lazyInit() is
+ if (cache == null)
+ cache = facebook.socialGraphRequest(profileId, type)
+
+ method getNext() is
+ if (hasMore())
+ result = cache[currentPosition]
+ currentPosition++
+ return result
+
+ method hasMore() is
+ lazyInit()
+ return currentPosition < cache.length
+
+// Clase cliente que utiliza el iterador
+class SocialSpammer is
+ method send(iterator: ProfileIterator, message: string) is
+ while (iterator.hasMore())
+ profile = iterator.getNext()
+ System.sendEmail(profile.getEmail(), message)
+
+// Configuración de la aplicación
+class Application is
+ field network: SocialNetwork
+ field spammer: SocialSpammer
+
+ method config() is
+ if working with Facebook
+ this.network = new Facebook()
+ if working with LinkedIn
+ this.network = new LinkedIn()
+ this.spammer = new SocialSpammer()
+
+ method sendSpamToFriends(profile) is
+ iterator = network.createFriendsIterator(profile.getId())
+ spammer.send(iterator, "Very important message")
+
+ method sendSpamToCoworkers(profile) is
+ iterator = network.createCoworkersIterator(profile.getId())
+ spammer.send(iterator, "Very important message")
+
+
+
+
+
+
Aplicabilidad
+
+
Cuando tu colección tiene una estructura de datos compleja, pero quieres ocultar esa complejidad a los clientes.
+
Para evitar que el código cliente dependa de detalles específicos de la implementación de la colección.
+
Para reducir la duplicación del código de recorrido en tu aplicación.
+
Cuando necesitas recorrer diferentes tipos de colecciones o cuando no conoces las estructuras de datos de antemano.
+
+
+
+
+
Cómo implementarlo
+
+
Declara la interfaz iteradora, que debe incluir al menos un método para obtener el siguiente elemento.
+
Declara la interfaz de colección con métodos para obtener iteradores.
+
Implementa iteradores concretos para las colecciones que quieras recorrer.
+
Implementa la interfaz de colección en las clases de colección y vincula la colección con los iteradores.
+
Utiliza los iteradores en lugar de recorrer directamente la colección en el código cliente.
+
+
+
+
+
Pros y Contras
+
+
Pros: Ayuda a mantener el principio de responsabilidad única y el principio de abierto/cerrado. Permite recorrer la misma colección en paralelo y retrazar la iteración si es necesario.
+
Contras: Puede resultar excesivo si se trabaja solo con colecciones simples. En algunas colecciones especializadas, el uso de un iterador puede ser menos eficiente que recorrer los elementos directamente.
+
+
+
+
+
Relaciones con otros patrones
+
+
Composite: Puedes utilizar Iteradores para recorrer árboles Composite.
+
Factory Method: Puedes usar el patrón Factory Method junto con Iterator para permitir que las subclases de la colección devuelvan distintos tipos de iteradores.
+
Memento: Puedes usar Memento junto con Iterator para capturar el estado de la iteración y reanudarla si fuera necesario.
+
Visitor: Puedes utilizar Visitor junto con Iterator para recorrer estructuras de datos complejas y ejecutar operaciones sobre sus elementos.
+
+
+
+
+
+
+
+
diff --git "a/practicas/patrones de dise\303\261o/patrones/comportamiento-Mediator.php" "b/practicas/patrones de dise\303\261o/patrones/comportamiento-Mediator.php"
new file mode 100644
index 00000000..d2951125
--- /dev/null
+++ "b/practicas/patrones de dise\303\261o/patrones/comportamiento-Mediator.php"
@@ -0,0 +1,165 @@
+
+
+
+
+
+
+
+ Patrón Mediator
+
+
+
+
+
+
+
Patrón Mediator
+
+
+
Propósito
+
Mediator es un patrón de diseño de comportamiento que te permite reducir las dependencias caóticas entre objetos. El patrón restringe las comunicaciones directas entre los objetos, forzándolos a colaborar únicamente a través de un objeto mediador.
+
+
+
+
Problema
+
Las relaciones entre los elementos de la interfaz de usuario pueden volverse caóticas cuando la aplicación crece. Los elementos pueden tener muchas relaciones entre ellos, lo que hace que el código sea difícil de mantener y reutilizar.
+
Por ejemplo, en un formulario, si varios campos dependen unos de otros (por ejemplo, un campo de texto que solo aparece si se marca una casilla), se generan dependencias mutuas que complican la reutilización de estos componentes.
+
+
+
+
Solución
+
El patrón Mediator sugiere que los componentes de una interfaz no se comuniquen directamente entre sí, sino que lo hagan a través de un objeto mediador. De este modo, los componentes dependen únicamente del mediador y no de los demás componentes, lo que facilita la reutilización y el mantenimiento del código.
+
+
+
+
Analogía en el mundo real
+
Es como la torre de control del tráfico aéreo: los aviones no se comunican directamente entre sí, sino que lo hacen a través de la torre de control, que regula el tráfico y garantiza que los aviones aterrizan de manera ordenada y segura.
+
+
+
+
Estructura
+
+
Interfaz Mediadora: Declara un método de notificación que los componentes pueden usar para enviar mensajes al mediador.
+
Mediadores Concretos: Implementan la lógica específica de los componentes que gestionan, redirigiendo las comunicaciones entre ellos.
+
Componentes: Los objetos que interactúan a través del mediador, enviando notificaciones sin conocerse entre sí.
+
+
+
+
+
Pseudocódigo
+
+
+// La interfaz mediadora declara un método utilizado por los
+// componentes para notificar al mediador sobre varios eventos.
+interface Mediator is
+ method notify(sender: Component, event: string)
+
+// La clase concreta mediadora. Gestiona las relaciones entre los componentes.
+class AuthenticationDialog implements Mediator is
+ private field loginButton, registrationButton: Button
+ private field loginFields, registrationFields: Textbox
+
+ method notify(sender, event) is
+ if (sender == loginButton && event == "click")
+ // Procesa la lógica de inicio de sesión
+ if (sender == registrationButton && event == "click")
+ // Procesa la lógica de registro
+
+// Los componentes se comunican con el mediador sin conocer a otros componentes
+class Button extends Component is
+ method click() is
+ dialog.notify(this, "click")
+
+class Textbox extends Component is
+ method keypress() is
+ dialog.notify(this, "keypress")
+
+
+
+
+
+
Aplicabilidad
+
+
Cuando las clases están fuertemente acopladas y necesitas hacerlas más independientes.
+
Cuando las relaciones entre los componentes son demasiado complejas y necesitas gestionarlas de forma centralizada.
+
Cuando desees reutilizar componentes sin que dependan de otros específicos.
+
+
+
+
+
Cómo implementarlo
+
+
Identifica las clases que se beneficiarían de ser menos dependientes entre sí.
+
Declara la interfaz mediadora con un método para recibir notificaciones de los componentes.
+
Implementa el mediador que gestione las interacciones entre los componentes.
+
Modifica los componentes para que se comuniquen solo con el mediador y no entre ellos directamente.
+
+
+
+
+
Pros y Contras
+
+
Pros: Mejora la mantenibilidad y reutilización del código. Reduce el acoplamiento entre componentes.
+
Contras: Puede hacer que el mediador se convierta en un objeto todopoderoso, lo que puede ser difícil de mantener si no se gestiona adecuadamente.
+
+
+
+
+
Relaciones con otros patrones
+
+
Observer: Ambos patrones manejan la comunicación entre objetos, pero Mediator centraliza el flujo de mensajes, mientras que Observer lo distribuye.
+
Command: Puedes combinar Mediator con Command para delegar las acciones a objetos comando que se gestionan desde el mediador.
+
Strategy: El patrón Mediator puede coordinar las diferentes estrategias aplicadas por los componentes.
+
+
+
+
+
+
+
+
diff --git "a/practicas/patrones de dise\303\261o/patrones/comportamiento-Memento.php" "b/practicas/patrones de dise\303\261o/patrones/comportamiento-Memento.php"
new file mode 100644
index 00000000..c773384f
--- /dev/null
+++ "b/practicas/patrones de dise\303\261o/patrones/comportamiento-Memento.php"
@@ -0,0 +1,188 @@
+
+
+
+
+
+
+
+ Patrón Memento
+
+
+
+
+
+
+
Patrón Memento
+
+
+
Propósito
+
Memento es un patrón de diseño de comportamiento que permite guardar y restaurar el estado de un objeto sin exponer su implementación interna. Este patrón es útil cuando se necesita la capacidad de deshacer acciones o restaurar el estado anterior de un objeto.
+
+
+
+
Problema
+
Cuando se tiene un objeto cuyo estado cambia a lo largo del tiempo, puede ser necesario restaurar el estado previo de ese objeto sin exponer su implementación interna. Sin embargo, el objeto no debe ser responsable de gestionar su propio estado guardado.
+
+
+
+
Solución
+
El patrón Memento propone utilizar tres componentes: el objeto originador, que mantiene el estado que puede cambiar; el memento, que guarda el estado del originador; y el cuidador de memento, que almacena los mementos y se encarga de restaurar el estado cuando sea necesario.
+
+
+
+
Analogía en el mundo real
+
Es similar a un libro de notas en el que vas escribiendo. Si te equivocas, puedes hacer una copia de seguridad (memento) antes de escribir. Si algo va mal, puedes restaurar tu copia de seguridad y seguir desde allí sin perder todo tu progreso.
+
+
+
+
Estructura
+
+
Originador: El objeto cuyo estado se guarda. Tiene un método para crear un memento con su estado actual.
+
Memento: Representa el estado del originador. Está diseñado para ser inmutable y no debe cambiar después de su creación.
+
Cuidador de Memento: Almacena los mementos y se encarga de restaurar el estado del originador cuando lo necesite.
+
+
+
+
+
Pseudocódigo
+
+
+// El Originador mantiene el estado actual y puede crear un memento.
+class Originador {
+ private state: string;
+
+ // Establece el estado
+ method setState(state: string) {
+ this.state = state;
+ }
+
+ // Crea un memento que guarda el estado actual
+ method createMemento(): Memento {
+ return new Memento(this.state);
+ }
+
+ // Restaura el estado desde un memento
+ method restoreMemento(memento: Memento) {
+ this.state = memento.getState();
+ }
+}
+
+// El Memento guarda el estado de un Originador
+class Memento {
+ private state: string;
+
+ constructor(state: string) {
+ this.state = state;
+ }
+
+ // Devuelve el estado guardado
+ method getState(): string {
+ return this.state;
+ }
+}
+
+// El Cuidador de Memento guarda y recupera el estado del Originador
+class Caretaker {
+ private mementos: Array = [];
+
+ // Guarda un memento
+ method saveMemento(memento: Memento) {
+ this.mementos.push(memento);
+ }
+
+ // Recupera un memento
+ method getMemento(index: number): Memento {
+ return this.mementos[index];
+ }
+}
+
+
+
+
+
+
Aplicabilidad
+
+
Cuando se necesita un mecanismo para deshacer cambios en un objeto sin exponer su implementación interna.
+
Cuando se desea preservar el estado de un objeto de manera que se pueda restaurar más tarde.
+
Cuando es necesario gestionar múltiples estados previos de un objeto sin que cada uno de esos estados dependa directamente del otro.
+
+
+
+
+
Cómo implementarlo
+
+
Crea un objeto originador que mantenga el estado que puede cambiar.
+
Define un memento que almacene ese estado de forma inmutable.
+
Implementa un cuidador de memento que almacene los mementos y pueda restaurar el estado anterior cuando sea necesario.
+
Asegúrate de que el originador no exponga su estado, permitiendo su restauración únicamente a través del memento.
+
+
+
+
+
Pros y Contras
+
+
Pros: Facilita el deshacer acciones y mantener la integridad del estado de los objetos. Se puede acceder al estado anterior sin exponer la implementación interna.
+
Contras: Puede generar un gran número de objetos memento, lo que podría generar un uso elevado de memoria. Además, la gestión de mementos puede complicarse si no se organiza adecuadamente.
+
+
+
+
+
Relaciones con otros patrones
+
+
Command: Puede combinarse con el patrón Command para permitir deshacer o rehacer comandos ejecutados.
+
State: El patrón Memento puede ser útil cuando se desea guardar los diferentes estados en los que un objeto puede estar, mientras que el patrón State define cómo se comportan esos estados.
+
Observer: En ciertos casos, el patrón Memento puede usarse junto con Observer para notificar cambios en el estado de los objetos observados.
+
+
+
+
+
+
+
+
diff --git "a/practicas/patrones de dise\303\261o/patrones/comportamiento-Observer.php" "b/practicas/patrones de dise\303\261o/patrones/comportamiento-Observer.php"
new file mode 100644
index 00000000..05361a0a
--- /dev/null
+++ "b/practicas/patrones de dise\303\261o/patrones/comportamiento-Observer.php"
@@ -0,0 +1,196 @@
+
+
+
+
+
+
+
+ Patrón Observer
+
+
+
+
+
+
+
Patrón Observer
+
+
+
Propósito
+
El patrón **Observer** es un patrón de diseño de comportamiento que te permite definir un mecanismo de suscripción para notificar a varios objetos sobre cualquier evento que le suceda al objeto que están observando, sin necesidad de que esos objetos estén directamente acoplados entre sí.
+
+
+
+
Problema
+
Imagina que tienes dos tipos de objetos: un objeto **Cliente** y un objeto **Tienda**. El cliente está interesado en una marca particular de producto (por ejemplo, un nuevo modelo de iPhone). En lugar de ir a la tienda a diario para ver si el producto está disponible, el cliente prefiere recibir notificaciones sobre su disponibilidad. La tienda, por su parte, podría enviar correos a todos los clientes, pero esto sería ineficiente si muchos clientes no están interesados en ese producto en particular.
+
+
+
+
Solución
+
El patrón Observer sugiere crear un mecanismo de suscripción en el objeto **notificador** (en este caso, la tienda), permitiendo que los objetos suscriptores (clientes) se registren para recibir notificaciones cuando haya actualizaciones o eventos que les interesen. Así, la tienda solo notificará a los clientes interesados sin enviar correos masivos.
+
+
+
+
Analogía en el mundo real
+
Un ejemplo sencillo de la vida real es el sistema de suscripción a revistas o periódicos. Si te suscribes, ya no tienes que ir a la tienda a buscar el último número, sino que el notificador (revista o periódico) te envía los nuevos números directamente a tu buzón. Los suscriptores se pueden dar de baja o cambiar de revista en cualquier momento.
+
+
+
+
Estructura
+
+
Notificador (Publisher): El objeto que genera eventos y mantiene una lista de suscriptores a los que notificará sobre estos eventos.
+
Suscriptor (Subscriber): El objeto que se suscribe al notificador para recibir notificaciones sobre ciertos eventos.
+
Interfaz de Suscripción: El notificador y suscriptores se comunican a través de una interfaz común que permite la actualización de los suscriptores cuando ocurre un evento.
+
+
+
+
+
Pseudocódigo
+
+
+// Clase base de EventManager para manejar suscripciones y notificaciones
+class EventManager is
+ private field listeners: hash map of event types and listeners
+
+ method subscribe(eventType, listener) is
+ listeners.add(eventType, listener)
+
+ method unsubscribe(eventType, listener) is
+ listeners.remove(eventType, listener)
+
+ method notify(eventType, data) is
+ foreach (listener in listeners.of(eventType)) do
+ listener.update(data)
+
+// Notificador concreto que notifica a los suscriptores sobre eventos
+class Editor is
+ public field events: EventManager
+ private field file: File
+
+ constructor Editor() is
+ events = new EventManager()
+
+ method openFile(path) is
+ this.file = new File(path)
+ events.notify("open", file.name)
+
+ method saveFile() is
+ file.write()
+ events.notify("save", file.name)
+
+// Interfaz para los suscriptores
+interface EventListener is
+ method update(filename)
+
+// Suscriptores concretos que responden a las actualizaciones
+class LoggingListener implements EventListener is
+ private field log: File
+ private field message: string
+
+ constructor LoggingListener(log_filename, message) is
+ this.log = new File(log_filename)
+ this.message = message
+
+ method update(filename) is
+ log.write(replace('%s',filename,message))
+
+class EmailAlertsListener implements EventListener is
+ private field email: string
+ private field message: string
+
+ constructor EmailAlertsListener(email, message) is
+ this.email = email
+ this.message = message
+
+ method update(filename) is
+ system.email(email, replace('%s',filename,message))
+
+
+
+
+
+
Aplicabilidad
+
+
Cuando un objeto (el notificador) cambia su estado y se requiere que varios otros objetos (suscriptores) se actualicen, pero no se conoce de antemano cuántos suscriptores habrá.
+
Cuando los suscriptores deben poder registrarse o cancelarse dinámicamente durante el tiempo de ejecución.
+
Cuando se desea evitar el acoplamiento directo entre los objetos que interactúan, permitiendo que se comuniquen a través de eventos.
+
+
+
+
+
Cómo implementarlo
+
+
Crea una interfaz **EventListener** que declare el método `update()` que todos los suscriptores deben implementar.
+
Define un **EventManager** que maneje las suscripciones, desuscripciones y notificaciones de eventos.
+
Implementa un **notificador** que mantenga la lista de suscriptores y notifique a todos cuando ocurra un evento relevante.
+
Los **suscriptores** deben implementar la interfaz **EventListener** y reaccionar a las actualizaciones que les envíe el notificador.
+
+
+
+
+
Pros y Contras
+
+
Pros: Alta flexibilidad y bajo acoplamiento entre los objetos. Nuevos suscriptores pueden añadirse sin modificar la clase del notificador.
+
Contras: Los suscriptores pueden ser notificados en un orden no determinado. Puede haber una sobrecarga si el número de suscriptores es muy grande.
+
+
+
+
+
Relaciones con otros patrones
+
+
Chain of Responsibility: Ambos patrones permiten la comunicación entre objetos, pero **Chain of Responsibility** pasa una solicitud a través de una cadena de objetos, mientras que **Observer** mantiene una lista de suscriptores que reciben notificaciones de eventos.
+
Command: En **Command**, el emisor de una solicitud está acoplado a su receptor, mientras que en **Observer**, los suscriptores pueden registrarse dinámicamente para recibir notificaciones sin acoplarse al notificador.
+
Mediator: **Mediator** centraliza la comunicación entre objetos, mientras que en **Observer** los objetos se comunican directamente con los suscriptores.
+
+
+
+
+
+
+
+
diff --git "a/practicas/patrones de dise\303\261o/patrones/comportamiento-State.php" "b/practicas/patrones de dise\303\261o/patrones/comportamiento-State.php"
new file mode 100644
index 00000000..ee87293d
--- /dev/null
+++ "b/practicas/patrones de dise\303\261o/patrones/comportamiento-State.php"
@@ -0,0 +1,252 @@
+
+
+
+
+
+
+
+
+ Patrón State
+
+
+
+
+
+
+
+
Patrón State
+
+
+
Propósito
+
El **Patrón State** permite que un objeto cambie su comportamiento dependiendo de su estado interno, eliminando grandes estructuras condicionales (`if` o `switch`). Cada estado se encapsula en una clase separada, lo que hace que el código sea más flexible y fácil de mantener.
+
+
+
+
Problema
+
Cuando un objeto tiene múltiples estados y su comportamiento cambia según el estado actual, el uso de estructuras condicionales (`if` o `switch`) puede hacer que el código sea difícil de leer, mantener y escalar.
+ Un ejemplo común es un **reproductor de música**, que puede estar en **modo pausado, reproduciendo o bloqueado**, y cada estado tiene reglas específicas sobre cómo responder a eventos.
+
+
+
+
Solución
+
El patrón **State** sugiere encapsular cada estado en su propia clase y delegar el comportamiento al estado actual.
+ El objeto principal (el **contexto**) mantiene una referencia al estado actual y delega el trabajo a esa instancia.
+
+
+
+
Estructura
+
+
Contexto: Mantiene una referencia a un objeto de estado y delega en él su comportamiento.
+
Estado: Interfaz que define los métodos comunes a todos los estados.
+
Estados Concretos: Clases que implementan la interfaz de estado y definen el comportamiento específico.
+
+
+
+
+
Ejemplo en Código
+
+
+// Interfaz común para los estados
+interface Estado {
+ void clickPlay();
+ void clickLock();
+ void clickNext();
+ void clickPrevious();
+}
+
+// Estado: Bloqueado
+class EstadoBloqueado implements Estado {
+ private Reproductor reproductor;
+
+ public EstadoBloqueado(Reproductor reproductor) {
+ this.reproductor = reproductor;
+ }
+
+ @Override
+ public void clickPlay() {
+ // No hace nada
+ }
+
+ @Override
+ public void clickLock() {
+ reproductor.cambiarEstado(new EstadoListo(reproductor));
+ }
+
+ @Override
+ public void clickNext() {}
+ @Override
+ public void clickPrevious() {}
+}
+
+// Estado: Listo para reproducir
+class EstadoListo implements Estado {
+ private Reproductor reproductor;
+
+ public EstadoListo(Reproductor reproductor) {
+ this.reproductor = reproductor;
+ }
+
+ @Override
+ public void clickPlay() {
+ reproductor.cambiarEstado(new EstadoReproduciendo(reproductor));
+ System.out.println("Reproduciendo...");
+ }
+
+ @Override
+ public void clickLock() {
+ reproductor.cambiarEstado(new EstadoBloqueado(reproductor));
+ }
+
+ @Override
+ public void clickNext() {
+ System.out.println("Siguiente canción...");
+ }
+
+ @Override
+ public void clickPrevious() {
+ System.out.println("Canción anterior...");
+ }
+}
+
+// Estado: Reproduciendo
+class EstadoReproduciendo implements Estado {
+ private Reproductor reproductor;
+
+ public EstadoReproduciendo(Reproductor reproductor) {
+ this.reproductor = reproductor;
+ }
+
+ @Override
+ public void clickPlay() {
+ reproductor.cambiarEstado(new EstadoListo(reproductor));
+ System.out.println("Pausado...");
+ }
+
+ @Override
+ public void clickLock() {
+ reproductor.cambiarEstado(new EstadoBloqueado(reproductor));
+ }
+
+ @Override
+ public void clickNext() {
+ System.out.println("Avanzando...");
+ }
+
+ @Override
+ public void clickPrevious() {
+ System.out.println("Retrocediendo...");
+ }
+}
+
+// Contexto: Reproductor de Música
+class Reproductor {
+ private Estado estadoActual;
+
+ public Reproductor() {
+ this.estadoActual = new EstadoListo(this);
+ }
+
+ public void cambiarEstado(Estado nuevoEstado) {
+ this.estadoActual = nuevoEstado;
+ }
+
+ public void clickPlay() { estadoActual.clickPlay(); }
+ public void clickLock() { estadoActual.clickLock(); }
+ public void clickNext() { estadoActual.clickNext(); }
+ public void clickPrevious() { estadoActual.clickPrevious(); }
+}
+
+// Uso del patrón
+public class Main {
+ public static void main(String[] args) {
+ Reproductor reproductor = new Reproductor();
+
+ reproductor.clickPlay(); // Reproduciendo...
+ reproductor.clickNext(); // Siguiente canción...
+ reproductor.clickLock(); // Bloqueado
+ reproductor.clickPlay(); // No hace nada (bloqueado)
+ }
+}
+
+
+
+
+
+
Aplicabilidad
+
+
Cuando un objeto tiene múltiples estados con diferentes comportamientos.
+
Cuando se quiere eliminar los grandes bloques de `if` o `switch`.
+
Cuando los estados pueden cambiar dinámicamente en tiempo de ejecución.
+
+
+
+
+
Pros y Contras
+
+
Pros: Separa la lógica de cada estado en clases individuales, mejorando la mantenibilidad.
+
Pros: Facilita la adición de nuevos estados sin modificar el código existente.
+
Contras: Puede aumentar la complejidad si hay pocos estados o cambios poco frecuentes.
+
+
+
+
+
Relaciones con otros patrones
+
+
Strategy: Ambos encapsulan comportamientos en clases separadas, pero **State** cambia dinámicamente entre ellos.
+
Flyweight: Puede usarse junto con **State** para compartir estados entre múltiples objetos.
+
Command: Mientras **Command** encapsula una acción como objeto, **State** encapsula un comportamiento.
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git "a/practicas/patrones de dise\303\261o/patrones/comportamiento-Strategy.php" "b/practicas/patrones de dise\303\261o/patrones/comportamiento-Strategy.php"
new file mode 100644
index 00000000..6504dce0
--- /dev/null
+++ "b/practicas/patrones de dise\303\261o/patrones/comportamiento-Strategy.php"
@@ -0,0 +1,199 @@
+
+
+
+
+
+
+
+
+ Patrón Strategy
+
+
+
+
+
+
+
+
Patrón Strategy
+
+
+
Propósito
+
El patrón **Strategy** es un patrón de diseño de comportamiento que permite definir una familia de algoritmos, encapsularlos en clases separadas y hacer que sus objetos sean intercambiables dinámicamente.
+
+
+
+
Problema
+
Imagina que desarrollas una aplicación de navegación que ayuda a los usuarios a planificar rutas. Inicialmente, solo se generaban rutas en coche, pero más tarde se añadieron rutas a pie y en transporte público.
+
El código de la aplicación creció de forma descontrolada, volviéndose difícil de mantener. Cada nuevo algoritmo aumentaba la complejidad y afectaba otras partes del código, dificultando el trabajo en equipo.
+
+
+
+
Solución
+
El patrón Strategy propone extraer los algoritmos de enrutamiento y colocarlos en clases separadas, llamadas estrategias. La clase principal de navegación (contexto) delega el cálculo de rutas a la estrategia seleccionada.
+
Esto permite agregar nuevas estrategias sin modificar el código existente, mejorando la flexibilidad y mantenibilidad del sistema.
+
+
+
+
Analogía en el mundo real
+
Si necesitas llegar al aeropuerto, puedes elegir entre distintas estrategias de transporte: taxi, autobús o bicicleta. Dependiendo de tus necesidades (tiempo, costo), seleccionas la mejor opción.
+
+
+
+
Estructura
+
+
Contexto: Mantiene una referencia a una estrategia y la utiliza para realizar una tarea.
+
Interfaz de Estrategia: Declara un método común para todas las estrategias.
+
Estrategias Concretas: Implementan diferentes variantes del algoritmo.
+
Cliente: Configura el contexto con una estrategia específica.
+
+
+
+
+
Pseudocódigo
+
+
+// Interfaz común para todas las estrategias
+interface Strategy is
+ method execute(a, b)
+
+// Estrategias concretas con diferentes implementaciones
+class ConcreteStrategyAdd implements Strategy is
+ method execute(a, b) is
+ return a + b
+
+class ConcreteStrategySubtract implements Strategy is
+ method execute(a, b) is
+ return a - b
+
+class ConcreteStrategyMultiply implements Strategy is
+ method execute(a, b) is
+ return a * b
+
+// Clase Contexto que usa una estrategia específica
+class Context is
+ private strategy: Strategy
+
+ method setStrategy(Strategy strategy) is
+ this.strategy = strategy
+
+ method executeStrategy(int a, int b) is
+ return strategy.execute(a, b)
+
+// Código cliente que selecciona y usa una estrategia
+class ExampleApplication is
+ method main() is
+ Create context object.
+
+ Read first number.
+ Read last number.
+ Read the desired action from user input.
+
+ if (action == addition) then
+ context.setStrategy(new ConcreteStrategyAdd())
+
+ if (action == subtraction) then
+ context.setStrategy(new ConcreteStrategySubtract())
+
+ if (action == multiplication) then
+ context.setStrategy(new ConcreteStrategyMultiply())
+
+ result = context.executeStrategy(First number, Second number)
+
+ Print result.
+
+
+
+
+
+
Aplicabilidad
+
+
Cuando necesitas cambiar dinámicamente el comportamiento de un objeto en tiempo de ejecución.
+
Si tienes muchas clases similares que solo se diferencian en su comportamiento.
+
Cuando quieres aislar la lógica de negocio de los detalles de implementación de los algoritmos.
+
Cuando un gran condicional gestiona múltiples variantes de un algoritmo.
+
+
+
+
+
Cómo implementarlo
+
+
Identifica los algoritmos que pueden cambiar y extrae cada uno en su propia clase.
+
Define una interfaz común para todas las estrategias.
+
Crea una clase de contexto que use la estrategia seleccionada.
+
Permite que los clientes configuren la estrategia del contexto dinámicamente.
+
+
+
+
+
Pros y Contras
+
+
Pros: Permite intercambiar algoritmos en tiempo de ejecución.
+
Pros: Aísla los detalles de implementación del código que los usa.
+
Pros: Reduce la duplicación de código al eliminar estructuras condicionales grandes.
+
Contras: Puede aumentar la complejidad si hay pocas estrategias y no cambian con frecuencia.
+
Contras: Los clientes deben conocer las diferencias entre estrategias para elegir la correcta.
+
+
+
+
+
Relaciones con otros patrones
+
+
State: Similar a Strategy, pero las estrategias pueden cambiarse automáticamente según el estado del contexto.
+
Command: Permite parametrizar un objeto con una acción, pero tiene un propósito distinto al de Strategy.
+
Template Method: Usa herencia para definir partes de un algoritmo, mientras que Strategy usa composición.
+
Decorator: Cambia la "piel" de un objeto, mientras que Strategy cambia su "interior".
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git "a/practicas/patrones de dise\303\261o/patrones/comportamiento-TemplateMethod.php" "b/practicas/patrones de dise\303\261o/patrones/comportamiento-TemplateMethod.php"
new file mode 100644
index 00000000..108b51b8
--- /dev/null
+++ "b/practicas/patrones de dise\303\261o/patrones/comportamiento-TemplateMethod.php"
@@ -0,0 +1,178 @@
+
+
+
+
+
+
+
+
+ Patrón Template Method
+
+
+
+
+
+
+
+
Patrón Template Method
+
+
+
Propósito
+
El patrón **Template Method** es un patrón de diseño de comportamiento que define la estructura de un algoritmo en una clase base, permitiendo que las subclases sobrescriban ciertos pasos sin cambiar su estructura general.
+
+
+
+
Problema
+
Cuando varias clases comparten un algoritmo similar pero con ligeras diferencias, se genera duplicación de código. Template Method permite evitar esto al estructurar el algoritmo en pasos personalizables.
+
+
+
+
Solución
+
El patrón Template Method propone dividir un algoritmo en una serie de pasos dentro de un **método plantilla** en una clase base. Las subclases deben implementar los pasos abstractos y pueden sobrescribir los opcionales si es necesario.
+
+
+
+
Analogía en el mundo real
+
Un ejemplo real es la construcción de viviendas en masa. Todas las casas siguen un mismo esquema base, pero los clientes pueden modificar ciertos aspectos como el color de las paredes o el tipo de ventanas.
+
+
+
+
Estructura
+
+
Método plantilla: Define la estructura del algoritmo en la clase base.
+
Pasos abstractos: Deben ser implementados por las subclases.
+
Pasos opcionales: Tienen una implementación por defecto pero pueden ser sobrescritos.
+
Ganchos (Hooks): Métodos opcionales que permiten modificar el comportamiento sin alterar la estructura del algoritmo.
+
+
+
+
+
Pseudocódigo
+
+
+class GameAI is
+ method turn() is
+ collectResources()
+ buildStructures()
+ buildUnits()
+ attack()
+
+ method collectResources() is
+ foreach (s in this.builtStructures) do
+ s.collect()
+
+ abstract method buildStructures()
+ abstract method buildUnits()
+
+ method attack() is
+ enemy = closestEnemy()
+ if (enemy == null)
+ sendScouts(map.center)
+ else
+ sendWarriors(enemy.position)
+
+ abstract method sendScouts(position)
+ abstract method sendWarriors(position)
+
+class OrcsAI extends GameAI is
+ method buildStructures() is
+ // Construcción específica de los orcos
+
+ method buildUnits() is
+ // Creación de unidades específicas de los orcos
+
+ method sendScouts(position) is
+ // Exploradores orcos
+
+ method sendWarriors(position) is
+ // Guerreros orcos
+
+
+
+
+
+
Aplicabilidad
+
+
Cuando tienes muchas clases con algoritmos casi idénticos, pero con algunas diferencias mínimas.
+
Cuando quieres permitir a los clientes extender únicamente partes particulares de un algoritmo sin cambiar su estructura.
+
+
+
+
+
Cómo implementarlo
+
+
Identificar los pasos comunes en varias clases.
+
Crear una clase base con un **método plantilla** que llame a los distintos pasos en orden.
+
Declarar los pasos abstractos en la clase base y permitir que las subclases los implementen.
+
Agregar ganchos (hooks) opcionales si es necesario.
+
+
+
+
+
Pros y Contras
+
+
Pros: Reduce la duplicación de código y facilita la extensión de algoritmos complejos.
+
Contras: Puede volverse difícil de mantener si tiene demasiados pasos y puede limitar la flexibilidad en comparación con otros patrones como Strategy.
+
+
+
+
+
Relaciones con otros patrones
+
+
Factory Method: Es una especialización de Template Method.
+
Strategy: Se basa en la composición y permite cambiar comportamientos en tiempo de ejecución, mientras que Template Method usa herencia y es estático.
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git "a/practicas/patrones de dise\303\261o/patrones/comportamiento-Visitor.php" "b/practicas/patrones de dise\303\261o/patrones/comportamiento-Visitor.php"
new file mode 100644
index 00000000..8f094981
--- /dev/null
+++ "b/practicas/patrones de dise\303\261o/patrones/comportamiento-Visitor.php"
@@ -0,0 +1,184 @@
+
+
+
+
+
+
+
+
+ Patrón Visitor
+
+
+
+
+
+
+
+
Patrón Visitor
+
+
+
Propósito
+
El patrón **Visitor** es un patrón de diseño de comportamiento que permite separar algoritmos de los objetos sobre los que operan, facilitando la adición de nuevas operaciones sin modificar las clases de los objetos.
+
+
+
+
Problema
+
Imagina un sistema con clases de nodos representados en un grafo (por ejemplo, ciudades, industrias, etc.). Si quieres agregar nuevas funcionalidades como la exportación a XML o el cálculo de impuestos, modificar las clases existentes puede ser riesgoso y difícil de mantener. Cada vez que agregas una nueva operación, corres el riesgo de romper algo en el sistema.
+
+
+
+
Solución
+
El patrón Visitor propone crear un objeto visitante que implemente las nuevas operaciones. Este visitante recorre las instancias de las clases y realiza la operación sobre ellas, sin necesidad de modificar las clases de los nodos. De esta forma, puedes añadir nuevas funcionalidades sin alterar el código existente.
+
+
+
+
Analogía en el mundo real
+
Una analogía en el mundo real sería el proceso de inspección de vehículos. Un inspector puede aplicar diferentes pruebas (como la prueba de emisiones o la revisión de frenos) sin tener que cambiar la estructura de un coche. El coche (objeto) sigue siendo el mismo, pero se le aplican diferentes pruebas (operaciones) a través de un inspector (visitor).
+
+
+
+
Estructura
+
+
Elemento: El objeto que será visitado. Define un método `accept` que recibe un visitante.
+
Visitante: Define las operaciones que se realizarán sobre los elementos. Debe implementar un método para cada tipo de elemento concreto.
+
Elementos concretos: Implementan el método `accept`, que llama al método correspondiente del visitante.
+
+
+
+
+
Pseudocódigo
+
+
+// Visitante que realiza diferentes operaciones sobre los elementos
+class Visitor {
+ method visit(ElementA element) {
+ // Realizar operación sobre ElementA
+ }
+
+ method visit(ElementB element) {
+ // Realizar operación sobre ElementB
+ }
+}
+
+// Elemento base que puede ser visitado por un visitante
+class Element {
+ method accept(visitor: Visitor) {
+ visitor.visit(this)
+ }
+}
+
+// Elementos concretos con tipos específicos
+class ElementA extends Element {
+ method accept(visitor: Visitor) {
+ visitor.visit(this)
+ }
+}
+
+class ElementB extends Element {
+ method accept(visitor: Visitor) {
+ visitor.visit(this)
+ }
+}
+
+// Implementación del visitante
+class ConcreteVisitor extends Visitor {
+ method visit(ElementA element) {
+ // Operación específica para ElementA
+ }
+
+ method visit(ElementB element) {
+ // Operación específica para ElementB
+ }
+}
+
+
+
+
+
+
Aplicabilidad
+
+
Cuando se necesita realizar operaciones sobre una estructura compleja de objetos y no deseas modificar las clases de esos objetos.
+
Cuando se quiere mantener el código abierto para la extensión pero cerrado para la modificación (principio de abierto/cerrado).
+
Cuando la estructura de clases de los objetos es estable, pero las operaciones que se realizan sobre ellas pueden cambiar o crecer con el tiempo.
+
+
+
+
+
Cómo implementarlo
+
+
Define una interfaz **Visitor** con un método `visit` para cada tipo de objeto que se va a visitar.
+
Crea una clase base **Elemento** que tenga un método `accept` que reciba un visitante y le pase a la visita correspondiente.
+
Los **Elementos concretos** deben implementar el método `accept` y llamar al método `visit` adecuado del visitante.
+
Los **Visitantes** concretos implementan las operaciones sobre los elementos sin modificarlos directamente.
+
+
+
+
+
Pros y Contras
+
+
Pros: Permite añadir nuevas operaciones sin modificar las clases existentes. Mejora la flexibilidad y el mantenimiento del código.
+
Contras: Puede ser complejo de implementar si hay muchas clases de elementos y visitantes. Si se agregan o eliminan tipos de elementos, todos los visitantes deben ser actualizados.
+
+
+
+
+
Relaciones con otros patrones
+
+
Strategy: Ambos patrones permiten cambiar el comportamiento de un objeto sin modificar su clase. Sin embargo, **Visitor** se enfoca en añadir nuevas operaciones, mientras que **Strategy** se enfoca en cambiar comportamientos específicos.
+
Composite: **Composite** permite tratar objetos individuales y compuestos de la misma forma, mientras que **Visitor** se enfoca en realizar operaciones sobre la estructura de objetos.
+
Decorator: Mientras que **Decorator** añade funcionalidades adicionales a un objeto sin alterar su estructura, **Visitor** agrega operaciones sin modificar los objetos visitados.
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git "a/practicas/patrones de dise\303\261o/patrones/comportamiento.php" "b/practicas/patrones de dise\303\261o/patrones/comportamiento.php"
new file mode 100644
index 00000000..e2250dbe
--- /dev/null
+++ "b/practicas/patrones de dise\303\261o/patrones/comportamiento.php"
@@ -0,0 +1,171 @@
+
+
+
+
+
+
+
+
+ Patrones de Comportamiento
+
+
+
+
+
+
+
+
+
Patrones de Comportamiento
+
Selecciona un patrón de comportamiento para aprender más.
+
+
+
+
+
Chain of Responsibility
+
Permite pasar solicitudes a lo largo de una cadena de manejadores. Cada manejador decide si la procesa o pasa al siguiente manejador.
+
+
+
+
+
\ No newline at end of file
diff --git "a/practicas/patrones de dise\303\261o/patrones/creacionales-AbstractFalctory.php" "b/practicas/patrones de dise\303\261o/patrones/creacionales-AbstractFalctory.php"
new file mode 100644
index 00000000..2d1ce49b
--- /dev/null
+++ "b/practicas/patrones de dise\303\261o/patrones/creacionales-AbstractFalctory.php"
@@ -0,0 +1,171 @@
+
+
+
+
+
+
+
+ Patrón Abstract Factory
+
+
+
+
+
+
+
Patrón Abstract Factory
+
+
+
Propósito
+
El patrón Abstract Factory permite producir familias de objetos relacionados sin especificar sus clases concretas. Es útil cuando el sistema debe ser independiente de cómo se crean, componen y representan los objetos.
+
+
+
+
Problema
+
Si estás trabajando con una tienda de muebles y necesitas crear productos como Sillas, Sofás y Mesillas, y quieres que estos productos tengan distintas variantes (moderna, victoriana, etc.), puedes enfrentar dificultades para gestionar estas variantes si el código cliente depende de clases concretas.
+
+
+
+
Solución
+
La solución es usar el patrón Abstract Factory, donde se definen interfaces para las familias de productos. Las fábricas concretas implementan estas interfaces y permiten que el código cliente trabaje con las fábricas sin preocuparse de los detalles de implementación.
+
+
+
+
Estructura
+
+
Producto abstracto: Define una interfaz para los productos que se pueden crear.
+
Producto concreto: Implementa las interfaces de los productos definidos en la fábrica abstracta.
+
Fábrica abstracta: Declara los métodos de creación de productos abstractos.
+
Fábrica concreta: Implementa los métodos de creación de productos específicos, según la variante.
+
Cliente: Usa las fábricas abstractas para crear productos, sin depender de clases concretas.
+
+
+
+
+
Ejemplo
+
+
+interface GUIFactory {
+ function createButton();
+ function createCheckbox();
+}
+
+class WinFactory implements GUIFactory {
+ function createButton() { return new WinButton(); }
+ function createCheckbox() { return new WinCheckbox(); }
+}
+
+interface Button {
+ function paint();
+}
+
+class WinButton implements Button {
+ function paint() { echo "Botón estilo Windows"; }
+}
+
+interface Checkbox {
+ function paint();
+}
+
+class WinCheckbox implements Checkbox {
+ function paint() { echo "Checkbox estilo Windows"; }
+}
+
+class Application {
+ private $factory;
+
+ function __construct(GUIFactory $factory) {
+ $this->factory = $factory;
+ }
+
+ function createUI() {
+ $button = $this->factory->createButton();
+ $checkbox = $this->factory->createCheckbox();
+
+ $button->paint();
+ $checkbox->paint();
+ }
+}
+
+
+
+
+
+
Aplicabilidad
+
+
Cuando tu código necesita trabajar con múltiples variantes de productos sin saber sus clases concretas.
+
Cuando desees asegurar la compatibilidad entre productos creados por diferentes fábricas.
+
Cuando quieras crear sistemas fáciles de extender con nuevos tipos de productos sin modificar el código cliente.
+
+
+
+
+
Pros y Contras
+
+
Pros: Desacopla la creación de productos, facilita la extensión de productos sin afectar el código cliente.
+
Contras: Aumenta la complejidad del sistema debido a la cantidad de interfaces y clases.
+
+
+
+
+
Relaciones con otros patrones
+
+
Factory Method: Ambos patrones encapsulan la creación de objetos, pero Abstract Factory se enfoca en familias de objetos.
+
Builder: Abstract Factory crea productos de una familia, mientras que Builder construye productos complejos paso a paso.
+
Prototype: Utiliza un prototipo de productos que puede ser modificado, mientras que Abstract Factory asegura la compatibilidad entre productos.
+
Facade: Abstract Factory puede ser usado en conjunto con Facade para ocultar la complejidad de la creación de productos del cliente.
+
Bridge: Ambos patrones ayudan a desacoplar abstracciones y implementaciones, pero en el caso de Abstract Factory, se enfoca en la creación de productos específicos.
+
+
+
+
+
+
+
+
diff --git "a/practicas/patrones de dise\303\261o/patrones/creacionales-Builder.php" "b/practicas/patrones de dise\303\261o/patrones/creacionales-Builder.php"
new file mode 100644
index 00000000..ef6f0e9d
--- /dev/null
+++ "b/practicas/patrones de dise\303\261o/patrones/creacionales-Builder.php"
@@ -0,0 +1,214 @@
+
+
+
+
+
+
+
+ Resumen del Patrón Builder
+
+
+
+
+
+
+
Builder
+
+
+
Propósito
+
Builder es un patrón de diseño creacional que nos permite construir objetos complejos paso a paso. El patrón nos permite producir distintos tipos y representaciones de un objeto empleando el mismo código de construcción.
+
+
+
+
Problema
+
Imagina un objeto complejo que requiere una inicialización laboriosa, paso a paso, de muchos campos y objetos anidados. Normalmente, este código de inicialización está sepultado dentro de un monstruoso constructor con una gran cantidad de parámetros. O, peor aún: disperso por todo el código cliente.
+
Una gran cantidad de subclases genera otro problema. Crear una subclase por cada configuración posible de un objeto puede complicar demasiado el programa.
+
Por ejemplo, pensemos en cómo crear un objeto Casa. Para construir una casa sencilla, debemos construir cuatro paredes y un piso, así como instalar una puerta, colocar un par de ventanas y ponerle un tejado. Pero ¿qué pasa si quieres una casa más grande y luminosa, con un jardín y otros extras (como sistema de calefacción, instalación de fontanería y cableado eléctrico)?
+
La solución más sencilla es extender la clase base Casa y crear un grupo de subclases que cubran todas las combinaciones posibles de los parámetros. Pero, en cualquier caso, acabarás con una cantidad considerable de subclases. Cualquier parámetro nuevo, como el estilo del porche, exigirá que incrementes esta jerarquía aún más.
+
Existen otras soluciones, como un constructor telescópico, pero este puede volverse muy complejo y difícil de gestionar.
+
+
+
+
Solución
+
El patrón Builder sugiere que saques el código de construcción del objeto de su propia clase y lo coloques dentro de objetos independientes llamados constructores.
+
+
+
+
Aplicación del patrón Builder
+
El patrón Builder te permite construir objetos complejos paso a paso, organizando la construcción en una serie de pasos (por ejemplo, construirParedes, construirPuerta, etc.). Estos pasos pueden invocarse según sea necesario, sin tener que invocar todos los pasos. Además, diferentes constructores pueden implementar los mismos pasos de forma diferente para crear distintas representaciones del producto.
+
Un ejemplo sería la construcción de una casa que varíe en materiales: madera, piedra, oro, etc. Al invocar la misma serie de pasos, podemos obtener distintos tipos de casas sin modificar el código cliente.
+
+
+
+
Estructura
+
+
Interfaz Constructora: Declara los métodos para los pasos de construcción comunes.
+
Constructores Concretos: Implementan la interfaz constructora y proporcionan las implementaciones específicas de los pasos.
+
Productos: Son los objetos que resultan de la construcción, que no necesariamente pertenecen a la misma jerarquía de clases.
+
Clase Directora: Define el orden en que se deben ejecutar los pasos de construcción, gestionando la creación de productos más complejos.
+
Cliente: Asocia un objeto constructor con la clase directora y comienza el proceso de construcción.
Utiliza el patrón Builder para evitar un “constructor telescópico”.
+
Cuando necesites construir distintas representaciones de un producto (por ejemplo, casas de piedra y madera).
+
Cuando la construcción de un producto requiera pasos similares pero con variaciones.
+
Para construir objetos complejos o árboles con el patrón Composite.
+
+
+
+
+
Pros y Contras
+
+
Pros: Permite construir objetos paso a paso, aplazar pasos o ejecutarlos de forma recursiva. Reutiliza el mismo código de construcción para distintas representaciones de productos.
+
Contras: Aumenta la complejidad del código al requerir varias clases nuevas.
+
+
+
+
+
Relaciones con otros patrones
+
+
Builder se puede usar junto con Factory Method, Abstract Factory o Prototype para crear productos más complejos.
+
Es útil en la creación de productos con estructuras recursivas, como árboles Composite.
+
Se puede combinar con Bridge para separar la abstracción y la implementación del proceso de construcción.
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git "a/practicas/patrones de dise\303\261o/patrones/creacionales-FacrotyMethod.php" "b/practicas/patrones de dise\303\261o/patrones/creacionales-FacrotyMethod.php"
new file mode 100644
index 00000000..d8c9ea4b
--- /dev/null
+++ "b/practicas/patrones de dise\303\261o/patrones/creacionales-FacrotyMethod.php"
@@ -0,0 +1,129 @@
+
+
+
+
+
+
+
+ Patrón Factory Method
+
+
+
+
+
+
+
Patrón Factory Method
+
+
+
Propósito
+
El patrón Factory Method es un patrón de diseño creacional que proporciona una interfaz para crear objetos en una superclase, permitiendo a las subclases alterar el tipo de objetos que se crearán sin modificar el código cliente.
+
+
+
+
Problema
+
Si tienes un código muy acoplado a clases específicas, como en una aplicación de transporte que maneja camiones, agregar nuevas clases de transporte puede resultar en un código desordenado lleno de condicionales. Esto dificulta la extensibilidad y el mantenimiento del código.
+
+
+
+
Solución
+
La solución es usar el patrón Factory Method, que delega la creación de objetos a un método especializado. Este método puede ser sobrescrito en subclases para cambiar la clase de los productos creados, manteniendo el código flexible y escalable.
+
+
+
+
Estructura
+
+
Producto: Declara una interfaz común para todos los productos que puede crear la clase creadora.
+
Producto Concreto: Implementaciones específicas de la interfaz de producto.
+
Creador: Declara el método de fábrica que devuelve objetos de tipo Producto.
+
Creador Concreto: Sobrescribe el método de fábrica para devolver un tipo específico de producto.
Cuando no conozcas las dependencias exactas y los tipos de objetos que tu código va a manejar.
+
Para desacoplar el código de creación de objetos del código cliente.
+
Cuando quieras que los usuarios puedan extender componentes sin modificar la lógica interna.
+
+
+
+
+
Pros y Contras
+
+
Pros: Reduce el acoplamiento, mejora la extensibilidad y el mantenimiento del código.
+
Contras: Puede llevar a un aumento en la complejidad del código, ya que requiere la creación de muchas subclases.
+
+
+
+
+
+
+
+
diff --git "a/practicas/patrones de dise\303\261o/patrones/creacionales-Prototype.php" "b/practicas/patrones de dise\303\261o/patrones/creacionales-Prototype.php"
new file mode 100644
index 00000000..f8141d14
--- /dev/null
+++ "b/practicas/patrones de dise\303\261o/patrones/creacionales-Prototype.php"
@@ -0,0 +1,189 @@
+
+
+
+
+
+
+
+ Patrón Prototype
+
+
+
+
+
+
+
Patrón Prototype
+
+
+
Propósito
+
El patrón Prototype permite copiar objetos existentes sin depender de sus clases. Este patrón delega el proceso de clonación a los propios objetos, lo que facilita la creación de copias sin necesidad de conocer la clase concreta del objeto.
+
+
+
+
Problema
+
Cuando necesitas crear una copia exacta de un objeto, lo más común es crear un nuevo objeto de la misma clase. Sin embargo, este enfoque depende de las clases concretas y puede ser complicado cuando los campos del objeto son privados o cuando no conocemos la clase exacta, solo su interfaz.
+
+
+
+
Solución
+
El patrón Prototype resuelve este problema al delegar la clonación a los propios objetos, proporcionando una interfaz común para clonar objetos. Cada objeto define su propio método clonar(), lo que permite la creación de copias sin depender de su clase concreta.
+
+
+
+
Estructura
+
+
Interfaz Prototype: Declara el método de clonación.
+
Prototipo Concreto: Implementa el método de clonación y realiza la copia de los campos del objeto original.
+
Cliente: Usa el prototipo para crear copias sin necesidad de conocer la clase concreta.
Cuando tu código necesita clonar objetos sin depender de sus clases concretas.
+
Cuando quieres reducir la cantidad de subclases mediante el uso de prototipos configurados.
+
Cuando trabajas con objetos pasados a través de interfaces y no conoces su tipo exacto.
+
+
+
+
+
Pros y Contras
+
+
Pros: Permite clonar objetos sin depender de su clase concreta, reduce la necesidad de subclases y facilita la creación de objetos complejos.
+
Contras: La clonación de objetos con referencias circulares puede ser complicada.
+
+
+
+
+
Relaciones con otros patrones
+
+
Factory Method: Prototype puede complementar Factory Method al permitir la clonación de objetos en lugar de crear nuevas instancias.
+
Abstract Factory: Ambos patrones crean objetos, pero Prototype se enfoca en copiar objetos ya existentes.
+
Composite y Decorator: Prototype puede ser útil al clonar estructuras complejas en lugar de reconstruirlas desde cero.
+
Builder: Prototype puede ser una alternativa más flexible al patrón Builder en algunos casos.
+
+
+
+
+
+
+
+
diff --git "a/practicas/patrones de dise\303\261o/patrones/creacionales-Singleton.php" "b/practicas/patrones de dise\303\261o/patrones/creacionales-Singleton.php"
new file mode 100644
index 00000000..1b0f9848
--- /dev/null
+++ "b/practicas/patrones de dise\303\261o/patrones/creacionales-Singleton.php"
@@ -0,0 +1,188 @@
+
+
+
+
+
+
+
+ Patrón Singleton
+
+
+
+
+
+
+
Patrón Singleton
+
+
+
Propósito
+
Singleton es un patrón de diseño creacional que nos permite asegurarnos de que una clase tenga una única instancia, a la vez que proporciona un punto de acceso global a dicha instancia.
+
+
+
+
Problema
+
El patrón Singleton resuelve dos problemas al mismo tiempo, vulnerando el Principio de responsabilidad única:
+
+
Garantizar que una clase tenga una única instancia: Esto es útil para controlar el acceso a recursos compartidos, como bases de datos o archivos.
+
Acceso global a un objeto: Permite que los clientes trabajen con el mismo objeto sin darse cuenta, evitando sobrescritura accidental.
+
+
+
+
+
Solución
+
El patrón Singleton implementa dos pasos clave:
+
+
Hacer privado el constructor para evitar la creación de instancias fuera de la clase Singleton.
+
Crear un método estático que devuelva la instancia única, almacenada en un campo estático para ser reutilizada.
+
+
+
+
+
Analogía en el mundo real
+
El gobierno es un ejemplo excelente de patrón Singleton. Un país sólo tiene un gobierno oficial, y la figura del gobierno es el punto de acceso global que identifica al grupo de personas a cargo.
+
+
+
+
Estructura
+
+
Clase Singleton: Declara el método estático obtenerInstancia, que garantiza que sólo haya una instancia de la clase.
+
Constructor Privado: El constructor se oculta para evitar instanciación directa, permitiendo el acceso sólo a través del método estático.
+
+
+
+
+
Pseudocódigo
+
+
+// La clase Base de datos define el método `obtenerInstancia`
+// que permite a los clientes acceder a la misma instancia de
+// una conexión de la base de datos a través del programa.
+class Database is
+ // El campo para almacenar la instancia singleton debe
+ // declararse estático.
+ private static field instance: Database
+
+ // El constructor del singleton siempre debe ser privado
+ // para evitar llamadas de construcción directas con el
+ // operador `new`.
+ private constructor Database() is
+ // Algún código de inicialización, como la propia
+ // conexión al servidor de una base de datos.
+ // ...
+
+ // El método estático que controla el acceso a la instancia
+ // singleton.
+ public static method getInstance() is
+ if (Database.instance == null) then
+ acquireThreadLock() and then
+ // Garantiza que la instancia aún no se ha
+ // inicializado por otro hilo mientras ésta ha
+ // estado esperando el desbloqueo.
+ if (Database.instance == null) then
+ Database.instance = new Database()
+ return Database.instance
+
+ // Lógica de negocio
+ public method query(sql) is
+ // Ejemplo de consulta a la base de datos.
+ // ...
+
+class Application is
+ method main() is
+ Database foo = Database.getInstance()
+ foo.query("SELECT ...")
+ Database bar = Database.getInstance()
+ bar.query("SELECT ...")
+ // `bar` es la misma instancia que `foo`.
+
+
+
+
+
+
Aplicabilidad
+
+
Cuando una clase debe tener solo una instancia accesible globalmente, como un objeto de base de datos.
+
Cuando necesitas controlar el acceso a una variable global, garantizando una sola instancia.
+
+
+
+
+
Cómo implementarlo
+
+
Añadir un campo estático privado a la clase para almacenar la instancia Singleton.
+
Declarar un método estático para obtener la instancia Singleton.
+
Implementar una inicialización diferida dentro del método estático.
+
Declarar el constructor como privado para prevenir la creación directa de instancias.
+
Sustituir llamadas directas al constructor por el método estático.
+
+
+
+
+
Pros y Contras
+
+
Pros: Garantiza una única instancia, acceso global, y eficiencia con la inicialización diferida.
+
Contras: Puede violar el Principio de Responsabilidad Única, complicar pruebas unitarias, y causar problemas en entornos multihilo.
+
+
+
+
+
Relaciones con otros patrones
+
+
Fachada: Una fachada puede convertirse en un Singleton, ya que se necesita un solo objeto fachada en la mayoría de los casos.
+
Flyweight: Ambos patrones tienen una sola instancia compartida, pero Flyweight permite múltiples instancias con estados distintos.
+
Abstract Factory, Builder, Prototype: Pueden implementarse como Singletons si es necesario.
+
+
+
+
+
+
+
+
diff --git "a/practicas/patrones de dise\303\261o/patrones/creacionales.php" "b/practicas/patrones de dise\303\261o/patrones/creacionales.php"
new file mode 100644
index 00000000..aa95c5b0
--- /dev/null
+++ "b/practicas/patrones de dise\303\261o/patrones/creacionales.php"
@@ -0,0 +1,122 @@
+
+
+
+
+
+
+
+ Patrones Creacionales
+
+
+
+
+
+
+
+
Patrones Creacionales
+
Selecciona un patrón creacional para aprender más.
+
+
+
+
+
Factory Method
+
Proporciona una interfaz para la creación de objetos en una superclase, mientras permite a las subclases alterar el tipo de objetos que se crearán.
Permite construir objetos complejos paso a paso. Este patrón nos permite producir distintos tipos y representaciones de un objeto empleando el mismo código de construcción.
+
+
+
+
diff --git "a/practicas/patrones de dise\303\261o/patrones/estructurales-Adapter.php" "b/practicas/patrones de dise\303\261o/patrones/estructurales-Adapter.php"
new file mode 100644
index 00000000..ece9e787
--- /dev/null
+++ "b/practicas/patrones de dise\303\261o/patrones/estructurales-Adapter.php"
@@ -0,0 +1,184 @@
+
+
+
+
+
+
+
+ Patrón Adapter
+
+
+
+
+
+
+
Patrón Adapter
+
+
+
Propósito
+
Adapter es un patrón de diseño estructural que permite la colaboración entre objetos con interfaces incompatibles.
+
+
+
+
Problema
+
Imagina que estás creando una aplicación de monitoreo del mercado de valores. La aplicación descarga la información de bolsa desde varias fuentes en formato XML para presentarla al usuario con bonitos gráficos y diagramas. Pero decides integrar una biblioteca de análisis que solo funciona con datos en formato JSON. Esto crea un conflicto de interfaces.
+
+
+
+
Solución
+
El patrón Adapter resuelve este dilema creando un adaptador que actúa como intermediario entre los objetos con interfaces incompatibles, permitiendo que el cliente use la nueva biblioteca sin necesidad de modificar el código cliente existente.
+
+
+
+
Analogía en el mundo real
+
Imagina que viajas de Europa a Estados Unidos y tienes que usar un enchufe europeo en un país con enchufes americanos. El adaptador convierte el enchufe europeo en uno compatible con el estándar estadounidense.
+
+
+
+
Estructura
+
+
Clase Cliente: Contiene la lógica de negocio y necesita usar la clase de servicio incompatible.
+
Interfaz con el Cliente: Define el protocolo de comunicación que los clientes usan para interactuar con las clases de servicio.
+
Clase de Servicio: La clase que tiene la funcionalidad que el cliente necesita, pero con una interfaz incompatible.
+
Clase Adaptadora: Envuelve la clase de servicio y convierte su interfaz a una que el cliente pueda utilizar.
+
+
+
+
+
Pseudocódigo
+
+
+// Definición de un agujero redondo.
+class RoundHole is
+ constructor RoundHole(radius) { ... }
+
+ method getRadius() is
+ return this.radius
+
+ method fits(peg: RoundPeg) is
+ return this.getRadius() >= peg.getRadius()
+
+// Definición de una pieza redonda.
+class RoundPeg is
+ constructor RoundPeg(radius) { ... }
+
+ method getRadius() is
+ return this.radius
+
+// Definición de una pieza cuadrada incompatible.
+class SquarePeg is
+ constructor SquarePeg(width) { ... }
+
+ method getWidth() is
+ return this.width
+
+// El adaptador convierte una pieza cuadrada en una pieza redonda.
+class SquarePegAdapter extends RoundPeg is
+ private field peg: SquarePeg
+
+ constructor SquarePegAdapter(peg: SquarePeg) is
+ this.peg = peg
+
+ method getRadius() is
+ return peg.getWidth() * Math.sqrt(2) / 2
+
+// Cliente que utiliza el adaptador para encajar piezas cuadradas en agujeros redondos.
+hole = new RoundHole(5)
+rpeg = new RoundPeg(5)
+hole.fits(rpeg) // verdadero
+
+small_sqpeg = new SquarePeg(5)
+large_sqpeg = new SquarePeg(10)
+small_sqpeg_adapter = new SquarePegAdapter(small_sqpeg)
+large_sqpeg_adapter = new SquarePegAdapter(large_sqpeg)
+hole.fits(small_sqpeg_adapter) // verdadero
+hole.fits(large_sqpeg_adapter) // falso
+
+
+
+
+
+
Aplicabilidad
+
+
Cuando se necesita usar una clase existente cuya interfaz no es compatible con el resto del sistema.
+
Cuando se quiere reutilizar una clase de una biblioteca externa sin modificar su código.
+
+
+
+
+
Cómo implementarlo
+
+
Crear una interfaz común que defina los métodos que el cliente necesita usar.
+
Implementar una clase adaptadora que envuelva la clase de servicio y convierta su interfaz a la interfaz común.
+
Utilizar el adaptador en lugar de la clase de servicio en el código cliente.
+
+
+
+
+
Pros y Contras
+
+
Pros: Permite la reutilización de clases con interfaces incompatibles y mantiene el código cliente limpio.
+
Contras: La complejidad aumenta, ya que se debe crear una nueva clase adaptadora para cada tipo de objeto incompatible.
+
+
+
+
+
Relaciones con otros patrones
+
+
Facade: Facade simplifica el acceso a un subsistema complejo, mientras que Adapter adapta interfaces para permitir su uso.
+
Decorator: Ambos patrones agregan funcionalidad a los objetos, pero Adapter cambia la interfaz mientras que Decorator mantiene la misma.
+
+
+
+
+
+
+
+
diff --git "a/practicas/patrones de dise\303\261o/patrones/estructurales-Bridge.php" "b/practicas/patrones de dise\303\261o/patrones/estructurales-Bridge.php"
new file mode 100644
index 00000000..4d276596
--- /dev/null
+++ "b/practicas/patrones de dise\303\261o/patrones/estructurales-Bridge.php"
@@ -0,0 +1,201 @@
+
+
+
+
+
+
+
+ Patrón Bridge
+
+
+
+
+
+
+
Patrón Bridge (Puente)
+
+
+
Propósito
+
El patrón Bridge es un patrón de diseño estructural que permite dividir una clase grande, o un conjunto de clases relacionadas, en dos jerarquías separadas (abstracción e implementación) que pueden desarrollarse de manera independiente.
+
+
+
+
Problema
+
Si tienes una clase geométrica como "Forma" con subclases como "Círculo" y "Cuadrado", y luego quieres agregar un nuevo atributo como "Color", el número de combinaciones de clases crece exponencialmente. Por ejemplo, para agregar el color "Rojo" y "Azul", necesitarías crear combinaciones como "CírculoRojo" y "CuadradoAzul". Esto se vuelve problemático a medida que aumentan las combinaciones.
+
+
+
+
Solución
+
El patrón Bridge resuelve este problema separando las dimensiones del problema en dos jerarquías de clases: una para la forma y otra para el color. Así, la clase "Forma" tiene una referencia a un objeto de la jerarquía "Color" y delega el trabajo relacionado con el color. Esto elimina la explosión de clases combinadas y facilita la extensión de la jerarquía sin generar combinaciones innecesarias.
+
+
+
+
Analogía en el mundo real
+
Imagina una aplicación de interfaz gráfica que debe funcionar en varios sistemas operativos, como Windows, Linux y macOS. El patrón Bridge permite que el código de la interfaz (abstracción) y el código del sistema operativo (implementación) estén separados. Así, puedes cambiar la interfaz gráfica o la implementación sin afectar la otra parte del sistema.
+
+
+
+
Estructura
+
+
Abstracción: La capa de control de alto nivel que delega el trabajo a la implementación.
+
Implementación: Declara la interfaz común para todas las implementaciones concretas.
+
Implementaciones Concretas: Contienen código específico de la plataforma.
+
Abstracción Refinada: Variantes de lógica de control que trabajan con diferentes implementaciones.
+
+
+
+
+
Pseudocódigo
+
+
+// La "abstracción" define la interfaz para el control
+// de las dos jerarquías de clase. Mantiene una referencia
+// a un objeto de la jerarquía de "implementación" y delega
+// el trabajo real a este objeto.
+class RemoteControl is
+ protected field device: Device
+ constructor RemoteControl(device: Device) is
+ this.device = device
+ method togglePower() is
+ if (device.isEnabled()) then
+ device.disable()
+ else
+ device.enable()
+ method volumeDown() is
+ device.setVolume(device.getVolume() - 10)
+ method volumeUp() is
+ device.setVolume(device.getVolume() + 10)
+ method channelDown() is
+ device.setChannel(device.getChannel() - 1)
+ method channelUp() is
+ device.setChannel(device.getChannel() + 1)
+
+
+// Se pueden extender clases de la jerarquía de abstracción
+// independientemente de las clases de dispositivo.
+class AdvancedRemoteControl extends RemoteControl is
+ method mute() is
+ device.setVolume(0)
+
+
+// La interfaz de "implementación" declara métodos comunes a
+// todas las clases concretas de implementación.
+interface Device is
+ method isEnabled()
+ method enable()
+ method disable()
+ method getVolume()
+ method setVolume(percent)
+ method getChannel()
+ method setChannel(channel)
+
+// Los dispositivos siguen la misma interfaz.
+class Tv implements Device is
+ // ...
+
+class Radio implements Device is
+ // ...
+
+// En el código cliente:
+tv = new Tv()
+remote = new RemoteControl(tv)
+remote.togglePower()
+
+radio = new Radio()
+remote = new AdvancedRemoteControl(radio)
+
+
+
+
+
+
Aplicabilidad
+
+
Cuando necesitas dividir y organizar una clase monolítica que tenga muchas variantes de una sola funcionalidad.
+
Cuando una clase se vuelve difícil de manejar debido a la necesidad de añadir nuevas variantes o combinaciones de funcionalidades.
+
Cuando deseas extender una clase en varias dimensiones ortogonales e independientes.
+
Cuando necesitas cambiar implementaciones en tiempo de ejecución sin modificar la abstracción.
+
+
+
+
+
Cómo implementarlo
+
+
Identifica las dimensiones ortogonales de tus clases y extráelas en jerarquías separadas.
+
Define las operaciones necesarias en la clase base de abstracción.
+
Declara las operaciones comunes en la interfaz de implementación.
+
Desarrolla las clases de implementación para cada plataforma o tipo de dispositivo, asegurándote de que todas sigan la misma interfaz.
+
En la clase de abstracción, añade una referencia al objeto de implementación y delega la mayoría del trabajo al objeto de implementación.
+
El código cliente vincula la abstracción con la implementación, y luego trabaja únicamente con la abstracción.
+
+
+
+
+
Pros y Contras
+
+
Pros: Facilita el cambio y extensión de clases sin afectar el código existente, permite el desarrollo independiente de diferentes jerarquías de clases, y soporta el principio de abierto/cerrado.
+
Contras: La complejidad puede aumentar si la clase original es muy cohesionada o si no se identifican bien las dimensiones ortogonales.
+
+
+
+
+
Relaciones con otros patrones
+
+
Adapter: Adapter conecta clases incompatibles, mientras que Bridge divide una clase monolítica en jerarquías separadas y relacionadas.
+
Strategy: Ambos patrones utilizan la composición y delegación, pero Bridge se utiliza cuando existen dimensiones ortogonales, mientras que Strategy define una única familia de algoritmos.
+
Abstract Factory: Abstract Factory puede complementar Bridge cuando se necesita encapsular la relación entre abstracción e implementación.
+
Builder: Bridge y Builder pueden combinarse cuando diferentes constructores crean distintas implementaciones para una abstracción.
+
+
+
+
+
+
+
+
diff --git "a/practicas/patrones de dise\303\261o/patrones/estructurales-Composite.php" "b/practicas/patrones de dise\303\261o/patrones/estructurales-Composite.php"
new file mode 100644
index 00000000..f7630a25
--- /dev/null
+++ "b/practicas/patrones de dise\303\261o/patrones/estructurales-Composite.php"
@@ -0,0 +1,178 @@
+
+
+
+
+
+
+
+ Patrón Composite
+
+
+
+
+
+
+
Patrón Composite
+
+
+
Propósito
+
El patrón Composite es un patrón de diseño estructural que permite tratar de manera uniforme objetos individuales y composiciones de objetos. Se utiliza para representar jerarquías de objetos, como árboles, donde los objetos pueden ser hojas (objetos simples) o nodos (composiciones de objetos).
+
+
+
+
Problema
+
Cuando necesitas representar jerarquías de objetos y deseas tratar los objetos individuales y las composiciones de la misma manera. Sin el patrón Composite, es difícil tratar a un objeto compuesto de la misma forma que un objeto simple, lo que lleva a un código repetitivo y difícil de mantener.
+
+
+
+
Solución
+
El patrón Composite resuelve este problema permitiendo que los objetos individuales y los compuestos de objetos implementen una interfaz común. De esta forma, tanto las hojas como los nodos pueden ser tratados de manera uniforme.
+
+
+
+
Analogía en el mundo real
+
Imagina una organización jerárquica dentro de una empresa, donde tienes a los empleados (hojas) y los directores (nodos) que supervisan a varios empleados. Ambos, empleados y directores, pueden ser tratados como miembros de la organización, aunque uno sea una persona y el otro un grupo de personas.
+
+
+
+
Estructura
+
+
Componente: Define la interfaz común para objetos individuales y compuestos. Los métodos pueden ser abstractos o definidos según lo que compartan los objetos.
+
Hoja: Representa los objetos simples que no tienen componentes hijos. Implementan la interfaz de Componente y definen la funcionalidad de las hojas.
+
Composición (Composite): Representa los objetos compuestos, que tienen hijos y delegan las operaciones a los mismos. Implementa la interfaz de Componente y contiene una colección de hijos.
+
Cliente: Interactúa con los objetos de forma uniforme, sin preocuparse de si el objeto es una hoja o una composición.
+
+
+
+
+
Pseudocódigo
+
+
+// Componente: Define la interfaz común para todas las clases
+interface Componente {
+ method operar(): void;
+}
+
+// Hoja: Representa objetos simples
+class Hoja implements Componente {
+ method operar() {
+ print("Operación en hoja");
+ }
+}
+
+// Composición: Representa objetos compuestos
+class Composicion implements Componente {
+ protected componentes: List = []
+
+ method agregar(component: Componente) {
+ this.componentes.add(component);
+ }
+
+ method operar() {
+ for each componente in componentes {
+ componente.operar();
+ }
+ }
+}
+
+// Uso del Composite:
+hoja1 = new Hoja()
+hoja2 = new Hoja()
+composicion = new Composicion()
+
+composicion.agregar(hoja1)
+composicion.agregar(hoja2)
+
+composicion.operar() // Llama a la operación en ambas hojas
+
+
+
+
+
+
Aplicabilidad
+
+
Cuando tienes objetos que forman una jerarquía y deseas tratarlos de manera uniforme.
+
Cuando necesitas tratar a los objetos compuestos y a los objetos simples de la misma manera sin tener que diferenciarlos.
+
Cuando un sistema necesita manejar jerarquías y la composición de objetos es algo fundamental.
+
+
+
+
+
Cómo implementarlo
+
+
Define una interfaz común para los objetos de la jerarquía (hojas y composiciones).
+
Implementa las hojas como clases que contienen operaciones simples.
+
Implementa las composiciones como clases que contienen una colección de componentes y delegan las operaciones a ellos.
+
En el cliente, usa la interfaz común para interactuar con los objetos, sin preocuparte si son hojas o composiciones.
+
+
+
+
+
Pros y Contras
+
+
Pros: Simplifica el código cliente al tratar objetos simples y compuestos de la misma manera, facilita la adición de nuevos tipos de objetos sin modificar el cliente.
+
Contras: Puede hacer que el diseño sea más complejo, especialmente cuando la jerarquía se vuelve muy profunda o cuando es difícil identificar los componentes.
+
+
+
+
+
Relaciones con otros patrones
+
+
Decorator: Ambos patrones permiten agregar funcionalidad a un objeto, pero Composite se enfoca en la creación de jerarquías y relaciones entre objetos, mientras que Decorator se enfoca en la adición de funcionalidades a un solo objeto.
+
Flyweight: Flyweight se usa para compartir objetos en lugar de crear nuevos, mientras que Composite crea una estructura jerárquica, a menudo con objetos únicos que no se comparten.
+
Iterator: Composite puede utilizar un iterador para recorrer la jerarquía de objetos y aplicar operaciones a cada componente, mientras que Iterator es un patrón para acceder secuencialmente a los elementos de una colección.
+
+
+
+
+
+
+
+
diff --git "a/practicas/patrones de dise\303\261o/patrones/estructurales-Decorator.php" "b/practicas/patrones de dise\303\261o/patrones/estructurales-Decorator.php"
new file mode 100644
index 00000000..1b37c552
--- /dev/null
+++ "b/practicas/patrones de dise\303\261o/patrones/estructurales-Decorator.php"
@@ -0,0 +1,10 @@
+
+
+.title-summary {
+ font-size: 1.5rem;
+ color: #e74c3c;
+ margin-bottom: 20px;
+ }
\ No newline at end of file
diff --git "a/practicas/patrones de dise\303\261o/patrones/estructurales-Facade.php" "b/practicas/patrones de dise\303\261o/patrones/estructurales-Facade.php"
new file mode 100644
index 00000000..478205f4
--- /dev/null
+++ "b/practicas/patrones de dise\303\261o/patrones/estructurales-Facade.php"
@@ -0,0 +1,164 @@
+
+
+
+
+
+
+
+ Patrón Facade
+
+
+
+
+
+
+
Patrón Facade
+
+
+
Propósito
+
El patrón Facade es un patrón estructural que proporciona una interfaz simplificada a un subsistema complejo. Facilita la integración con bibliotecas o marcos sofisticados, proporcionando un acceso directo y reducido a las funcionalidades esenciales.
+
+
+
+
Problema
+
Trabajar directamente con un subsistema complejo puede hacer que el código se vuelva difícil de mantener y entender, ya que se debe gestionar la interacción entre muchos objetos y sus dependencias.
+
+
+
+
Solución
+
El patrón Facade oculta la complejidad del subsistema, proporcionando una interfaz sencilla que solo expone las funciones realmente necesarias para el cliente, sin necesidad de interactuar con la implementación interna.
+
+
+
+
Analogía en el mundo real
+
Imagina hacer un pedido telefónico en una tienda. El operador es una fachada que facilita el acceso a varios departamentos sin que el cliente tenga que interactuar con cada uno de ellos.
+
+
+
+
Estructura
+
+
Fachada: Proporciona una interfaz simplificada para interactuar con el subsistema.
+
Subsistema: Un conjunto de clases complejas que realizan tareas específicas, que quedan ocultas detrás de la fachada.
+
Cliente: Utiliza la fachada para interactuar con el subsistema, sin conocer su complejidad interna.
+
+
+
+
+
Pseudocódigo
+
+
+// Ejemplo de código de una fachada para un framework de conversión de vídeo
+class VideoConverter {
+ method convert(filename, format) {
+ videoFile = new VideoFile(filename)
+ codec = new CodecFactory().extract(videoFile)
+ if (format == "mp4")
+ destinationCodec = new MPEG4Codec()
+ else
+ destinationCodec = new OggCodec()
+ buffer = BitrateReader.read(videoFile, codec)
+ result = BitrateReader.convert(buffer, destinationCodec)
+ finalResult = AudioMixer.fix(result)
+ return new File(finalResult)
+ }
+}
+
+// El cliente solo interactúa con la fachada, sin preocuparse de los detalles
+class Application {
+ method main() {
+ converter = new VideoConverter()
+ file = converter.convert("funny-cats-video.ogg", "mp4")
+ file.save()
+ }
+}
+
+
+
+
+
+
Aplicabilidad
+
+
Cuando necesitas una interfaz simplificada a un subsistema complejo.
+
Para desacoplar el cliente de la complejidad del subsistema.
+
Cuando se requieren múltiples fachadas para gestionar subsistemas complejos y facilitar la interacción entre capas del sistema.
+
+
+
+
+
Cómo implementarlo
+
+
Crea una clase fachada que proporcione una interfaz simple.
+
Encapsula las complejidades del subsistema dentro de esta fachada.
+
Haz que todo el código cliente interactúe solo con la fachada, ocultando la lógica interna del subsistema.
+
Si la fachada se vuelve muy compleja, considera dividirla en fachadas adicionales especializadas.
+
+
+
+
+
Pros y Contras
+
+
Pros: Facilita el acceso a subsistemas complejos, mejora la mantenibilidad y desacopla al cliente de la lógica interna del subsistema.
+
Contras: La fachada puede convertirse en un objeto todopoderoso que gestione demasiadas responsabilidades, lo que podría complicar su mantenimiento.
+
+
+
+
+
Relaciones con otros patrones
+
+
Adapter: Ambos patrones proporcionan una interfaz diferente, pero Facade simplifica el acceso a un subsistema completo, mientras que Adapter adapta la interfaz de un solo objeto.
+
Proxy: Ambos patrones pueden actuar como intermediarios, pero Proxy tiene la misma interfaz que el objeto que envuelve, mientras que Facade tiene una interfaz simplificada para un subsistema completo.
+
Mediator: Aunque ambos patrones coordinan la interacción entre clases, Mediator centraliza la comunicación, mientras que Facade simplifica el acceso a un subsistema sin cambiar la interacción interna.
+
+
+
+
+
+
+
+
diff --git "a/practicas/patrones de dise\303\261o/patrones/estructurales-Flyweight.php" "b/practicas/patrones de dise\303\261o/patrones/estructurales-Flyweight.php"
new file mode 100644
index 00000000..3b7daff4
--- /dev/null
+++ "b/practicas/patrones de dise\303\261o/patrones/estructurales-Flyweight.php"
@@ -0,0 +1,197 @@
+
+
+
+
+
+
+
+ Patrón Flyweight
+
+
+
+
+
+
+
Patrón Flyweight
+
+
+
Propósito
+
El patrón Flyweight es un patrón estructural que permite reducir el uso de memoria al compartir la mayor cantidad de datos posible entre objetos similares. Es ideal cuando se necesita manejar grandes cantidades de objetos, pero algunos de estos comparten muchas características comunes.
+
+
+
+
Problema
+
En aplicaciones con muchos objetos similares, como un juego con partículas (balas, misiles, explosiones), la cantidad de memoria utilizada puede ser excesiva, ya que cada objeto podría tener la misma información almacenada repetidamente.
+
+
+
+
Solución
+
Flyweight ofrece la solución de separar el estado intrínseco (información común como color, textura, etc.) del estado extrínseco (información que cambia constantemente, como la posición o la velocidad). Los objetos compartidos se almacenan una sola vez, mientras que los datos que cambian se pasan como parámetros.
+
+
+
+
Analogía en el mundo real
+
Imagina que estás jugando un juego de disparos en una computadora. En lugar de crear una nueva imagen para cada bala disparada, el sistema usa una sola instancia de un objeto de bala, y solo cambia su posición en la pantalla.
+
+
+
+
Estructura
+
+
Flyweight: Es el objeto que contiene el estado intrínseco compartido entre muchas instancias de objetos similares.
+
Contexto: Contiene el estado extrínseco de los objetos, como la posición o la velocidad.
+
Fábrica de Flyweights: Gestiona y reutiliza los objetos Flyweight, asegurando que se comparta el estado intrínseco entre las instancias.
+
+
+
+
+
Pseudocódigo
+
+
+// Ejemplo de un patrón Flyweight para un juego de disparos
+class BalaFlyweight {
+ private String color;
+ private String sprite; // Este es el estado intrínseco
+
+ // Constructor de Flyweight
+ public BalaFlyweight(String color, String sprite) {
+ this.color = color;
+ this.sprite = sprite;
+ }
+
+ public void mostrar(Contexto contexto) {
+ // El estado extrínseco (posición, velocidad) se pasa aquí
+ System.out.println("Bala de color " + color + " en " + contexto.getPosicion());
+ }
+}
+
+// Clase Contexto
+class Contexto {
+ private String posicion;
+ private String velocidad;
+
+ public Contexto(String posicion, String velocidad) {
+ this.posicion = posicion;
+ this.velocidad = velocidad;
+ }
+
+ public String getPosicion() {
+ return posicion;
+ }
+
+ public String getVelocidad() {
+ return velocidad;
+ }
+}
+
+// Fábrica de Flyweights
+class FábricaDeBalas {
+ private Map flyweights = new HashMap<>();
+
+ public BalaFlyweight obtenerFlyweight(String color) {
+ if (!flyweights.containsKey(color)) {
+ flyweights.put(color, new BalaFlyweight(color, "default-sprite"));
+ }
+ return flyweights.get(color);
+ }
+}
+
+// El cliente interactúa con el Flyweight
+class Juego {
+ public void jugar() {
+ FábricaDeBalas fabrica = new FábricaDeBalas();
+ Contexto contexto = new Contexto("Posición1", "Rápida");
+
+ BalaFlyweight bala = fabrica.obtenerFlyweight("Rojo");
+ bala.mostrar(contexto);
+ }
+}
+
+
+
+
+
+
Aplicabilidad
+
+
Cuando se necesita crear muchos objetos similares con grandes cantidades de datos compartidos.
+
Cuando se desea optimizar el uso de memoria, manteniendo solo una copia de los datos comunes.
+
En sistemas donde el rendimiento es crítico y hay una alta frecuencia de creación de objetos pequeños.
+
+
+
+
+
Cómo implementarlo
+
+
Crea clases para los objetos Flyweight, separando el estado intrínseco (común) del estado extrínseco (cambiable).
+
Usa una fábrica para manejar la creación y reutilización de Flyweights, asegurándote de que los objetos comunes se compartan.
+
Al utilizar un Flyweight, pasa el estado extrínseco como parámetros de método, sin almacenar estos datos en el objeto Flyweight.
+
+
+
+
+
Pros y Contras
+
+
Pros: Reduce el uso de memoria, mejora el rendimiento, y evita la creación innecesaria de objetos duplicados.
+
Contras: Puede complicar el diseño, especialmente en sistemas donde los estados extrínsecos cambian frecuentemente.
+
+
+
+
+
Relaciones con otros patrones
+
+
Abstract Factory: Ambos patrones se utilizan para crear familias de objetos, pero Flyweight optimiza la memoria reutilizando instancias existentes.
+
Prototype: Mientras que Prototype crea una copia de un objeto, Flyweight crea un solo objeto compartido para ser reutilizado.
+
Decorator: Aunque Decorator se utiliza para añadir funcionalidad a los objetos, Flyweight se enfoca en compartir el estado común entre los objetos.
+
+
+
+
+
+
+
+
diff --git "a/practicas/patrones de dise\303\261o/patrones/estructurales-Proxy.php" "b/practicas/patrones de dise\303\261o/patrones/estructurales-Proxy.php"
new file mode 100644
index 00000000..99b659b4
--- /dev/null
+++ "b/practicas/patrones de dise\303\261o/patrones/estructurales-Proxy.php"
@@ -0,0 +1,231 @@
+
+
+
+
+
+
+
+ Patrón Proxy
+
+
+
+
+
+
+
Patrón Proxy
+
+
+
Propósito
+
Proxy es un patrón de diseño estructural que te permite proporcionar un sustituto o marcador de posición para otro objeto. Un proxy controla el acceso al objeto original, permitiéndote hacer algo antes o después de que la solicitud llegue al objeto original.
+
+
+
+
Problema
+
¿Por qué querrías controlar el acceso a un objeto? Imagina que tienes un objeto enorme que consume una gran cantidad de recursos del sistema. Lo necesitas de vez en cuando, pero no siempre.
+
Las consultas a las bases de datos pueden ser muy lentas. Puedes llevar a cabo una implementación diferida, es decir, crear este objeto sólo cuando sea realmente necesario.
+
En un mundo ideal, querríamos meter este código directamente dentro de la clase de nuestro objeto, pero eso no siempre es posible. Por ejemplo, la clase puede ser parte de una biblioteca cerrada de un tercero.
+
+
+
+
Solución
+
El patrón Proxy sugiere que crees una nueva clase proxy con la misma interfaz que un objeto de servicio original. Después actualizas tu aplicación para que pase el objeto proxy a todos los clientes del objeto original. Al recibir una solicitud de un cliente, el proxy crea un objeto de servicio real y le delega todo el trabajo.
+
El proxy se camufla como objeto de la base de datos. Puede gestionar la inicialización diferida y el caché de resultados sin que el cliente o el objeto real de la base de datos lo sepan.
+
Si necesitas ejecutar algo antes o después de la lógica primaria de la clase, el proxy te permite hacerlo sin cambiar esa clase. Ya que el proxy implementa la misma interfaz que la clase original, puede pasarse a cualquier cliente que espere un objeto de servicio real.
+
+
+
+
Analogía en el mundo real
+
Una tarjeta de crédito es un proxy de un manojo de billetes. Las tarjetas de crédito pueden utilizarse para realizar pagos tanto como el efectivo.
+
Una tarjeta de crédito es un proxy de una cuenta bancaria, que, a su vez, es un proxy de un manojo de billetes. Ambos implementan la misma interfaz, por lo que pueden utilizarse para realizar un pago.
+
El consumidor se siente genial porque no necesita llevar un montón de efectivo encima. El dueño de la tienda también está contento porque los ingresos de la transacción se añaden electrónicamente a la cuenta bancaria de la tienda sin el riesgo de perder el depósito o sufrir un robo de camino al banco.
+
+
+
+
Estructura
+
+
Interfaz de Servicio: Declara la interfaz del servicio que el proxy debe seguir.
+
Servicio: Es una clase que proporciona la lógica de negocio útil.
+
Proxy: Tiene un campo de referencia que apunta a un objeto de servicio y delega el trabajo cuando es necesario.
+
Cliente: Utiliza el servicio o el proxy a través de la misma interfaz, sin importar cuál se utilice.
+
+
+
+
+
Pseudocódigo
+
+
+// La interfaz de un servicio remoto
+interface ThirdPartyYouTubeLib {
+ method listVideos()
+ method getVideoInfo(id)
+ method downloadVideo(id)
+}
+
+// La implementación concreta de un conector de servicio.
+class ThirdPartyYouTubeClass implements ThirdPartyYouTubeLib {
+ method listVideos() {
+ // Envía una solicitud API a YouTube
+ }
+ method getVideoInfo(id) {
+ // Obtiene metadatos de algún video
+ }
+ method downloadVideo(id) {
+ // Descarga un archivo de video de YouTube
+ }
+}
+
+// El proxy para gestionar el almacenamiento en caché
+class CachedYouTubeClass implements ThirdPartyYouTubeLib {
+ private field service: ThirdPartyYouTubeLib
+ private field listCache, videoCache
+ private field needReset
+
+ constructor CachedYouTubeClass(service: ThirdPartyYouTubeLib) {
+ this.service = service
+ }
+
+ method listVideos() {
+ if (listCache == null || needReset)
+ listCache = service.listVideos()
+ return listCache
+ }
+
+ method getVideoInfo(id) {
+ if (videoCache == null || needReset)
+ videoCache = service.getVideoInfo(id)
+ return videoCache
+ }
+
+ method downloadVideo(id) {
+ if (!downloadExists(id) || needReset)
+ service.downloadVideo(id)
+ }
+}
+
+// La clase GUI que usa el proxy
+class YouTubeManager {
+ protected field service: ThirdPartyYouTubeLib
+
+ constructor YouTubeManager(service: ThirdPartyYouTubeLib) {
+ this.service = service
+ }
+
+ method renderVideoPage(id) {
+ info = service.getVideoInfo(id)
+ // Representa la página del video.
+ }
+
+ method renderListPanel() {
+ list = service.listVideos()
+ // Representa la lista de miniaturas de los videos.
+ }
+
+ method reactOnUserInput() {
+ renderVideoPage()
+ renderListPanel()
+ }
+}
+
+// La aplicación puede configurar proxies sobre la marcha
+class Application {
+ method init() {
+ aYouTubeService = new ThirdPartyYouTubeClass()
+ aYouTubeProxy = new CachedYouTubeClass(aYouTubeService)
+ manager = new YouTubeManager(aYouTubeProxy)
+ manager.reactOnUserInput()
+ }
+}
+
+
+
+
+
+
Aplicabilidad
+
+
Inicialización diferida (proxy virtual): Para objetos pesados que consumen muchos recursos solo cuando se necesitan.
+
Control de acceso (proxy de protección): Limitar el acceso solo a ciertos clientes según las credenciales.
+
Ejecución local de un servicio remoto (proxy remoto): Gestionar solicitudes a un servicio en un servidor remoto.
+
Solicitudes de registro (proxy de registro): Registrar las solicitudes al objeto de servicio.
+
Resultados de solicitudes en caché (proxy de caché): Gestionar el ciclo de vida del caché para evitar solicitudes repetitivas.
+
Referencia inteligente: El proxy puede controlar la vida útil de un objeto pesado, liberando recursos cuando ya no se usa.
+
+
+
+
+
Cómo implementarlo
+
+
Crea una interfaz de servicio si no existe una para hacer intercambiables los objetos proxy y servicio.
+
Crea la clase proxy que administre el ciclo de vida del objeto de servicio.
+
Implementa los métodos del proxy según su propósito, delegando el trabajo cuando sea necesario.
+
Considera usar la inicialización diferida para mejorar el rendimiento.
+
+
+
+
+
Pros y Contras
+
+
Pros: Permite controlar el acceso a un objeto sin que los clientes lo sepan, y gestiona su ciclo de vida sin intervención.
+
Contras: Puede complicar el código con muchas clases adicionales y retrasar la respuesta del servicio.
+
+
+
+
+
Relaciones con otros patrones
+
+
Adapter: Ambos patrones proporcionan acceso a objetos a través de una interfaz diferente, pero Proxy mantiene la misma interfaz del servicio.
+
Decorator: Ambos basados en la composición, pero Proxy gestiona el ciclo de vida de su servicio, mientras que Decorator lo hace el cliente.
+
Facade: Similar en que ambos pueden inicializar un objeto complejos, pero Proxy mantiene la misma interfaz del objeto de servicio.
+
+
+
+
+
+
+
+
diff --git "a/practicas/patrones de dise\303\261o/patrones/estructurales.php" "b/practicas/patrones de dise\303\261o/patrones/estructurales.php"
new file mode 100644
index 00000000..856abfd2
--- /dev/null
+++ "b/practicas/patrones de dise\303\261o/patrones/estructurales.php"
@@ -0,0 +1,141 @@
+
+
+
+
+
+
+
+ Patrones Estructurales
+
+
+
+
+
+
+
+
Patrones Estructurales
+
Los patrones estructurales explican cómo ensamblar objetos y clases en estructuras más grandes, a la vez que se mantiene la flexibilidad y eficiencia de estas estructuras.
+
+
+
+
+
Adapter
+
Permite la colaboración entre objetos con interfaces incompatibles.
Permite dividir una clase grande o un grupo de clases estrechamente relacionadas, en dos jerarquías separadas (abstracción e implementación) que pueden desarrollarse independientemente la una de la otra.
Permite mantener más objetos dentro de la cantidad disponible de memoria RAM compartiendo las partes comunes del estado entre varios objetos en lugar de mantener toda la información en cada objeto.
Permite proporcionar un sustituto o marcador de posición para otro objeto. Un proxy controla el acceso al objeto original, permitiéndote hacer algo antes o después de que la solicitud llegue al objeto original.
Módulo 7 - Práctica 1. Mi primera aplicación en PHP
+
+
+
+
+
+
+
+
+
Aquesta pàgina 'hola.php' forma part de la 'pràctica 1' del mòdul 7. En el fitxer 'index.php',
+ normalment s'hi defineixen les parts bàsiques d'una pàgina PHP, com ara el 'header', que conté informació inicial de la pàgina,
+ així com el logo o títol, i el 'body', on es mostren els continguts principals. També es pot veure l'estructura de 'columnes'
+ que separen les diferents seccions del disseny
+
+
+
+
\ No newline at end of file
diff --git a/practicas/practica2/ejercicio1/index.php b/practicas/practica2/ejercicio1/index.php
new file mode 100644
index 00000000..471879e9
--- /dev/null
+++ b/practicas/practica2/ejercicio1/index.php
@@ -0,0 +1,41 @@
+
+
+
+
+
+ Document
+
+
+
+
+
";
+ }
+ echo"";
+ }
+
+ divisores();
+ ?>
+
+
\ No newline at end of file
diff --git a/practicas/practica3/ejercicio3a.php b/practicas/practica3/ejercicio3a.php
new file mode 100644
index 00000000..ef1501e0
--- /dev/null
+++ b/practicas/practica3/ejercicio3a.php
@@ -0,0 +1,214 @@
+ "Elon",
+ "apellido" => " Musk",
+ "apodo" => "Elon",
+ "imagen" => "https://static.wikia.nocookie.net/doblaje/images/a/aa/ElonMusk.jpg/revision/latest?cb=20200203042454&path-prefix=es",
+ "descripcion" => "Elon me ha enseñado a soñar en grande, a no conformarme con lo establecido y a siempre buscar innovar, incluso cuando parece imposible."
+ ],
+ [
+ "nombre" => "Oprah",
+ "apellido" => " Winfrey",
+ "apodo" => "Oprah",
+ "imagen" => "https://upload.wikimedia.org/wikipedia/commons/thumb/b/bf/Oprah_in_2014.jpg/800px-Oprah_in_2014.jpg",
+ "descripcion" => "Oprah me ha inspirado con su historia de superación personal y su capacidad para conectar con las personas a un nivel profundo, siempre promoviendo el empoderamiento."
+ ],
+ [
+ "nombre" => "Michael",
+ "apellido" => " Jordan",
+ "apodo" => "MJ",
+ "imagen" => "https://cdn.britannica.com/09/188709-050-03BF34CB/Michael-Jordan.jpg",
+ "descripcion" => "Michael Jordan me enseñó que el fracaso es solo una parte del proceso hacia el éxito. Su ética de trabajo y mentalidad competitiva me motivan diariamente."
+ ],
+ [
+ "nombre" => "Emma",
+ "apellido" => " Watson",
+ "apodo" => "Hermione",
+ "imagen" => "https://static.wikia.nocookie.net/littlewomen/images/a/ac/Emmawatson.png/revision/latest/thumbnail/width/360/height/360?cb=20191221175400",
+ "descripcion" => "Emma Watson no solo es una actriz increíble, sino también una defensora de los derechos de las mujeres, lo que me ha inspirado a ser una mejor persona."
+ ],
+ [
+ "nombre" => "Serena",
+ "apellido" => " Williams",
+ "apodo" => "Serena",
+ "imagen" => "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTh4vLbPXxSVhDTg1Y4RAsoUZR77NFb6WpbjQ&s",
+ "descripcion" => "Serena Williams me enseñó a luchar hasta el final, sin importar cuántas veces la vida te derribe. Su pasión y fuerza son inigualables."
+ ],
+ [
+ "nombre" => "Keanu",
+ "apellido" => " Reeves",
+ "apodo" => "Neo",
+ "imagen" => "https://i.redd.it/a7c3so8l2g761.jpg",
+ "descripcion" => "Keanu Reeves es un ejemplo de humildad y resiliencia. A pesar de los desafíos personales, sigue siendo una persona amable y generosa."
+ ],
+ [
+ "nombre" => "Billie",
+ "apellido" => " Eilish",
+ "apodo" => "Billie",
+ "imagen" => "https://media.vogue.es/photos/609d3714fae5608e730970ed/4:3/w_1999,h_1499,c_limit/Billie-Eilish-Happier-Than-Ever.jpeg",
+ "descripcion" => "Billie Eilish me inspira por su autenticidad. No tiene miedo de ser diferente y siempre es fiel a sí misma, rompiendo barreras en la música y más allá."
+ ],
+ [
+ "nombre" => "Cristiano",
+ "apellido" => " Ronaldo",
+ "apodo" => "CR7",
+ "imagen" => "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRMSGTtrTDtuCpVMqlcS8XLV61ORiQmOSCJUQ&s",
+ "descripcion" => "Cristiano Ronaldo me ha mostrado que la disciplina y el esfuerzo constante son las claves para ser el mejor en cualquier campo. Su dedicación es legendaria."
+ ],
+ [
+ "nombre" => "Zendaya",
+ "apellido" => " ",
+ "apodo" => "Z",
+ "imagen" => "https://cdn.hobbyconsolas.com/sites/navi.axelspringer.es/public/media/image/2024/04/zendaya-3296707.jpg?tf=3840x",
+ "descripcion" => "Zendaya me inspira no solo por su talento como actriz, sino por su activismo social, abogando por causas importantes y usando su plataforma para hacer el bien."
+ ],
+]; ?>
+
+
+
+
+
+
+
+
+
+
+
+ Album example · Bootstrap
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
About
+
Add some information about the album below, the author, or any other background
+ context. Make it a few sentences long so folks can pick up some informative tidbits. Then, link them off
+ to some social networking sites or contact information.
Something short and leading about the collection below—its contents, the creator,
+ etc. Make it short and sweet, but not too short so folks don’t simply skip over it entirely.
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/practicas/practica5/funcionesPropias/archivo.html b/practicas/practica5/funcionesPropias/archivo.html
new file mode 100644
index 00000000..e2dba7d3
--- /dev/null
+++ b/practicas/practica5/funcionesPropias/archivo.html
@@ -0,0 +1,15 @@
+
+
+
+
+
+ Document
+
+
+
DESCARGAR GRATIS SIN VIRUS(TE LO JURO ERMANO) ONLINE(NO OFLINE) SIN REGISTRO SIN IMPUESTOS(REAL) SIN ESPERAS OFICIAL☑️☑️☑️☑️☑️☑️☑️☑️☑️☑️☑️☑️☑️☑️☑️☑️☑️☑️☑️☑️☑️☑️☑️☑️☑️☑️☑️
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/prueba de mejora/add_edit_question.php b/prueba de mejora/add_edit_question.php
new file mode 100644
index 00000000..5174c58b
--- /dev/null
+++ b/prueba de mejora/add_edit_question.php
@@ -0,0 +1,63 @@
+ count($_SESSION['preguntas']) + 1,
+ 'question' => $_POST['questionmas'],
+ 'options' => [
+ $_POST['option1mas'],
+ $_POST['option2mas'],
+ $_POST['option3mas']
+ ],
+ 'answer' => $_POST['answermas']
+ ];
+
+ $_SESSION['preguntas'] . array_push($preguntas, $nuevaPregunta);
+ } else {
+ echo 'Completa todos los campos!!!!';
+ }
+}
+?>
+
+
+
+
+
+
+
+ Añadir pregunta
+
+
+
+
Añadir una nueva pregunta
+
+
+ Regresar al index.php
+
+
+
\ No newline at end of file
diff --git a/prueba de mejora/data.php b/prueba de mejora/data.php
new file mode 100644
index 00000000..e07ec57a
--- /dev/null
+++ b/prueba de mejora/data.php
@@ -0,0 +1,41 @@
+ 1,
+'question' => '¿Cuál es el océano más grande del mundo?',
+'options' => ['Atlántico', 'Pacífico', 'Índico'],
+'answer' => 'Pacífico'
+],
+[
+'id' => 2,
+'question' => '¿En qué continente se encuentra Egipto?',
+'options' => ['Asia', 'África', 'Europa'],
+'answer' => 'África'
+],
+[
+'id' => 3,
+'question' => '¿Cuántos días tiene un año bisiesto?',
+'options' => ['365', '366', '367'],
+'answer' => '366'
+],
+[
+'id' => 4,
+'question' => '¿Cuál es el metal más usado en la industria?',
+'options' => ['Hierro', 'Cobre', 'Aluminio'],
+'answer' => 'Hierro'
+],
+[
+'id' => 5,
+'question' => '¿Qué planeta es conocido como el planeta rojo?',
+'options' => ['Venus', 'Marte', 'Júpiter'],
+'answer' => 'Marte'
+]
+];
+
+if (!isset($_SESSION["preguntas"])) {
+$_SESSION["preguntas"] = $preguntas;
+}
+
+?>
\ No newline at end of file
diff --git a/prueba de mejora/delete_question.php b/prueba de mejora/delete_question.php
new file mode 100644
index 00000000..e69de29b
diff --git a/prueba de mejora/index.php b/prueba de mejora/index.php
new file mode 100644
index 00000000..c8307a57
--- /dev/null
+++ b/prueba de mejora/index.php
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+ Inicio
+
+
+
+
+
+
+
Hola, = $_SESSION['usuario']; ?>. Clica aquí para
+ empezar el trivial';
+ } else {
+ echo 'empezar el trivial';
+ }
+ ?>
+