Design Patterns Flashcards
CREATIONAL- Singleton
un tipo soltero se sube a un unicornio unicornio y hace que un grupo de unicornios con Evita peron encima se unifique en el suyo y termina cabalgando hacia una tabla de una base de datos
-
¿Qué es?
Es un patrón que asegura que una clase tenga una única instancia y proporciona un** punto de acceso** global a esa instancia. Esto significa que cada vez que se acceda a esa clase, se trabajará con la misma instancia, lo que evita duplicados y asegura consistencia en el estado compartido. -
¿Cuándo aplicarlo?
Úsalo cuando necesites gestionar un recurso centralizado en tu aplicación, como un servicio de configuración global, un registro de logs, **una conexión a una base de datos **o un controlador de estado compartido. Es útil en escenarios donde múltiples partes de la aplicación deben usar el mismo recurso sin conflictos.
Ejemplo: Clonar un objeto de configuración predefinido.
CREATIONAL- Prototype
el del juego prototype se le cae dinero y cierra una fábrica de personajes iguales a él y comienza a largar clones, despues juega a la play
- ¿Qué es?
Permite crear nuevos objetos copiando o clonando una instancia existente, en lugar de crear una desde cero. Este patrón utiliza un prototipo como plantilla para generar objetos similares sin necesidad de conocer sus detalles de implementación.
- ¿Cuándo aplicarlo?
Úsalo cuando la creación de objetos desde cero sea costosa o compleja y ya tengas un objeto base que puede servir como modelo. Es ideal para sistemas donde los objetos comparten características similares y deben generarse de forma eficiente, como juegos o sistemas gráficos.
CREATIONAL- Builder/Constructor
bob el constructor construye paso a paso un robot que tiene muchas configuraciones de botones y muchos paraguas, despues se pone unos anteojos y lo lee
- - - ¿Qué es?
Divide el proceso de construcción de un objeto complejo en una serie de pasos o métodos, proporcionando control sobre cómo se ensamblan sus partes. Esto permite crear diferentes representaciones del objeto sin cambiar su estructura interna.
- ¿Cuándo aplicarlo?
Úsalo cuando un objeto tenga **muchas configuraciones opcionales o diferentes combinaciones de parámetros, **como al construir un objeto JSON complejo, configuraciones de interfaz de usuario o estructuras de datos con múltiples variantes. Es especialmente útil para mejorar la legibilidad del código y reducir constructores demasiado cargados.
Ejemplo: Construir un objeto “Usuario” paso a paso.
CREATIONAL- Abstract Factory
en una fabrica fantasma hay familias de objetos, como teteras, el fantasma las mete en una capsula y las agrupa en un el inter de miami con un general
- - ¿Qué es?
Es un patrón que proporciona una interfaz para crear familias de objetos relacionados o dependientes sin especificar sus clases concretas. Este patrón encapsula las fábricas individuales bajo una interfaz más general.
- ¿Cuándo aplicarlo?
Úsalo cuando trabajes con sistemas que requieran múltiples tipos de objetos relacionados y quieras asegurar la coherencia entre ellos, como al conectar a multiples bases de datos o desarrollo multiplataforma, o en GUI
Ejemplo: Crear familias de botones y cuadros de diálogo para diferentes plataformas.
CREATIONAL- Factory
una fabrica a la que le entran pedidos como “toyota”,”corolla”,”rojo” y “ford,f100,azul” y salen del otro lado los vehiculos sin que se vea nada dentro de la fabrica
- - ¿Qué es?
Proporciona un método para crear objetos sin especificar la clase concreta del objeto que se va a crear. Centraliza la lógica de creación en una única ubicación, lo que hace que el código sea más modular y flexible.
- ¿Cuándo aplicarlo?
Úsalo cuando necesites delegar la creación de objetos complejos o cuando quieras mantener bajo acoplamiento en tu código. Es útil en sistemas donde las clases específicas del objeto no son conocidas hasta el momento de la ejecución, como al implementar sistemas de plugins o trabajar con datos dinámicos.
Ejemplo: Una fábrica que devuelve instancias según un tipo dado.
ESTRUCTURAL - Facade FASAD
en la fachada de un local se oculta todo el funcionamiento del negocio y sólo haces los pedidos - despues de pedirle una pizza miras el calendario y la fecha de hoy
-
¿Qué es?
Proporciona una interfaz simplificada para un subsistema complejo, ocultando la complejidad de sus componentes internos.
-
¿Qué es?
-
¿Cuándo aplicarlo?
Úsalo cuando quieras ofrecer una forma sencilla de interactuar con sistemas complejos o bibliotecas externas, como una API que combina varias operaciones en una sola.
new Date() usa un FACADE, las librerias son FACADES -
Ejemplo (texto):
Un subsistema de videojuegos con clases para gráficos, sonidos y física podría tener una fachadaGameEngine
que expone un métodostartGame()
, combinando la lógica de inicialización de todos estos módulos.
ESTRUCTURAL - Bridge
un puente une a un fantasma y a un invertido suplemento deportivo
Patrón Bridge (Puente) – Explicación Sencilla
El patrón Bridge es un patrón de diseño estructural que te ayuda a dividir una clase grande o un grupo de clases relacionadas en dos partes principales:
1. Abstracción: Lo que define qué hace algo (su función general).
2. Implementación: Cómo hace eso (los detalles técnicos específicos).
Estas dos partes pueden desarrollarse y modificarse de forma independiente. Este patrón se llama “Bridge” porque conecta (o actúa como puente entre) la abstracción y la implementación, permitiendo que ambas evolucionen sin depender una de la otra.
Ventajas del Patrón Bridge
- Separación de responsabilidades: La abstracción y la implementación están claramente separadas, lo que facilita la lectura y mantenimiento del código.
- Flexibilidad: Permite cambiar cómo funciona algo sin afectar al resto del sistema.
- Evita diseños rígidos y complicados: Reduce la posibilidad de crear estructuras de clases difíciles de modificar.
Cuándo Usar el Patrón Bridge
- Ocultar detalles internos de implementación: Si no quieres que el cliente vea cómo funciona algo, puedes mostrarle solo la parte necesaria (la abstracción).
- Soporte de comportamientos específicos: Si necesitas que algo funcione de manera diferente en distintas plataformas, puedes crear implementaciones específicas para cada una y cambiarlas fácilmente.
- Cambiar implementaciones en tiempo de ejecución: El patrón permite cambiar cómo se ejecuta algo mientras el programa está funcionando, según las condiciones del entorno.
- Estructura estable, comportamiento dinámico: Aunque la estructura del código permanezca igual, el comportamiento puede cambiar dependiendo de la implementación que se use.
- Evitar diseños monolíticos: Ayuda a que el diseño del sistema sea más modular y menos propenso a errores que afecten todo el sistema.
ESTRUCTURAL - Composite
en un compost hay un arbol que tiene ramas y despues hojas
-
¿Qué es?
Permite tratar objetos individuales y grupos de objetos de manera uniforme mediante una jerarquía de árbol. -
¿Cuándo aplicarlo?
Úsalo cuando necesites trabajar con estructuras jerárquicas como menús, sistemas de archivos o diagramas, y quieras manipular nodos y contenedores de forma similar. -
Ejemplo (texto):
Un menú de restaurante donde cada elemento es un platillo o un grupo de platillos.
```typescript
menu.add(salad); // Añade un platillo.
menu.add(compositeMenu); // Añade un grupo de platillos.
menu.display(); // Muestra todos los elementos.
~~~
ESTRUCTURAL - Decorator
hay un decorador EXTIENDE su brazo y decora con cosas de navidad un mueble sin modificar su estructura base
- ¿Qué es?
Permite agregar comportamiento o responsabilidades adicionales a un objeto de forma dinámica sin modificar su estructura base.
- ¿Cuándo aplicarlo?
Úsalo cuando necesites **extender la funcionalidad **de clases sin herencia, como al añadir características dinámicas a componentes visuales o procesos.
- Ejemplo (texto):
Un servicio de notificaciones donde puedes decorar un mensaje base con funcionalidades adicionales como encriptación o registro.
```typescript
const notification = new EncryptedDecorator(new BaseNotification());
notification.send(); // Envía el mensaje con cifrado adicional.
~~~
ESTRUCTURAL - Adapter
hay un adaptador de electricidad que traduce de un idioma al otro entre dos personas de clases diferentes. uno es extranjero.
tambien funciona al traducirle a ancianos
El patrón Adapter es un patrón de diseño que permite que una clase existente se comunique con otra que tiene una interfaz incompatible. En lugar de modificar el código original, se crea un “adaptador” que actúa como un traductor entre ambas.
Este patrón es útil cuando necesitas que dos partes de un sistema trabajen juntas, pero sus interfaces no son compatibles.
Cuándo Usar el Patrón Adapter
-
Incompatibilidad de interfaces:
Cuando dos componentes del sistema no pueden comunicarse porque sus interfaces son diferentes, el Adapter traduce las instrucciones de una interfaz a la otra. Es común al integrar bibliotecas o APIs externas. -
Refactorización de código antiguo:
Si estás rediseñando un sistema y quieres que el nuevo código funcione con componentes antiguos sin modificarlos, el Adapter conecta ambos mundos manteniendo la compatibilidad. -
Alternativa a la herencia múltiple:
En lenguajes que no permiten herencia múltiple (como Java o TypeScript), el Adapter te permite reutilizar funcionalidades de diferentes clases sin necesidad de herencia directa. -
Abstracción de clases volátiles:
Si trabajas con clases que cambian con frecuencia, el Adapter puede encapsular esos cambios, evitando que el resto del sistema se vea afectado por las modificaciones.
BEHAVIORAL - Observer
hay unos tipos observando como se suscriben a netflix y cuando sube una pelicula les aparece directamente en el celular, tienen puestas remeras de VUE
- ¿Qué es?
Define una relación uno a muchos, donde múltiples objetos (suscriptores) se actualizan automáticamente cuando un objeto (sujeto) cambia de estado.
- ¿Cuándo aplicarlo?
Úsalo para implementar sistemas de eventos o notificaciones, como actualizaciones en tiempo real en interfaces de usuario o sistemas de publicación/suscripción.
- Ejemplo (texto):
Un objeto de stock de productos notifica a los usuarios cuando hay cambios en el inventario.
```typescript
stock.subscribe(userObserver);
stock.notify(); // Informa a todos los observadores del cambio.
~~~
BEHAVIORAL - Iterator
estas iterando un objeto y de golpe estas corriendo sobre las ramas de un arbol y aparecen graficos volando y el piso se convierte en una lista de tareas
- ¿Qué es?
Proporciona una forma de acceder secuencialmente a los elementos de una colección sin exponer su implementación interna.
- ¿Cuándo aplicarlo?
Úsalo cuando necesites recorrer estructuras de datos complejas, como listas, árboles o gráficos, de manera uniforme.
- Ejemplo (texto):
Un iterador para una lista de reproducción que permite reproducir canciones una a una.
```typescript
while (playlist.hasNext()) {
console.log(playlist.next().title); // Imprime los títulos de las canciones.
}
~~~
BEHAVIORAL - Template Method
hay un templario haciendo templates de torneos de vue y despues se pone a preparar bebidas como té y café
- - ¿Qué es?
Define el esqueleto de un algoritmo en un método base y permite que las subclases implementen pasos específicos sin alterar su estructura general.
- ¿Cuándo aplicarlo?
Úsalo cuando varios algoritmos tengan la misma estructura general pero detalles diferentes, como en sistemas de procesamiento de datos o flujos de trabajo.
- Ejemplo (texto):
Un proceso de preparación de bebidas que varía según el tipo (café, té).
```typescript
tea.prepare(); // Llama al método base con pasos específicos de té.
~~~
BEHAVIORAL - Chain of Responsibility
hay una cadena y ant man va corriendo con una solicitud hasta que cae en un eslabón que lo procesa onda procesadora
- - ¿Qué es?
Permite que varias clases manejen una solicitud, pasándola a lo largo de una cadena hasta que alguien la procese.
- ¿Cuándo aplicarlo?
Úsalo para evitar el acoplamiento directo entre emisores y receptores de solicitudes, como en sistemas de autorización o validación de datos.
- Ejemplo (texto):
Un sistema de soporte técnico donde las solicitudes pasan por niveles (soporte básico, técnico, especialista).
```typescript
handler.setNext(specialistHandler);
handler.handleRequest(request); // Se procesa en el nivel adecuado.
~~~
TypeScript permite herencia multiple?
- Ni JavaScript ni TypeScript permiten herencia múltiple directa.
- Ambos lenguajes utilizan mixins, composición, o delegación para lograr un comportamiento similar.