Patrones de Diseño en JavaScript

  1. Patrones de Diseño en JavaScript

Los patrones de diseño son soluciones comunes a problemas comunes en el desarrollo de software. En JavaScript, hay una gran variedad de patrones de diseño disponibles, desde patrones de creación hasta patrones de arquitectura.

11.1 Patrones de creación (Constructor, Módulo, Singleton)

Los patrones de creación son patrones que se utilizan para crear objetos de una manera específica. En JavaScript, algunos de los patrones de creación más comunes son el patrón Constructor, el patrón Módulo y el patrón Singleton.

Ejemplo:

// Constructor
function Persona(nombre, edad) {
  this.nombre = nombre;
  this.edad = edad;
}

const persona1 = new Persona("Juan", 30);
const persona2 = new Persona("María", 25);

// Módulo
const miModulo = (() => {
  const variablePrivada = "Esto es privado";

  const funcionPrivada = () => {
    console.log(variablePrivada);
  };

  const funcionPublica = () => {
    console.log("Esto es público");
  };

  return {
    funcionPublica
  };
})();

miModulo.funcionPublica();

// Singleton
const miSingleton = (() => {
  let instancia;

  const crearInstancia = () => {
    const objeto = new Object("Esto es un singleton");
    return objeto;
  };

  return {
    obtenerInstancia: () => {
      if (!instancia) {
        instancia = crearInstancia();
      }
      return instancia;
    }
  };
})();

const instancia1 = miSingleton.obtenerInstancia();
const instancia2 = miSingleton.obtenerInstancia();
console.log(instancia1 === instancia2); // true

11.2 Patrones de comportamiento (Observador, Iterador, Estrategia)

Los patrones de comportamiento son patrones que se utilizan para definir la interacción entre objetos y la forma en que responden a cambios en el estado del sistema. En JavaScript, algunos de los patrones de comportamiento más comunes son el patrón Observador, el patrón Iterador y el patrón Estrategia.

Te recomendamos leer:  Introducción a JavaScript

Ejemplo:

// Observador
const observable = (() => {
  const suscriptores = [];

  const suscribirse = fn => suscriptores.push(fn);

  const notificar = valor => suscriptores.forEach(fn => fn(valor));

  return {
    suscribirse,
    notificar
  };
})();

observable.suscribirse(valor => console.log(`Suscriptor 1: ${valor}`));
observable.suscribirse(valor => console.log(`Suscriptor 2: ${valor}`));

observable.notificar("Esto es un mensaje");

// Iterador
const iterable = (() => {
  const arreglo = [1, 2, 3, 4, 5];

  const iterator = {
    indice: 0,
    siguiente: () => {
      if (iterator.indice < arreglo.length) {
        const valor = arreglo[iterator.indice];
        iterator.indice++;
        return { value: valor, done: false };
      } else {
        return { done: true };
      }
    }
  };

  return {
    [Symbol.iterator]: () => iterator
  };
})();

for (const valor of iterable) {
  console.log(valor);
}

// Estrategia
const estrategia = (() => {
  const estrategias = {
    sumar: (a, b) => a + b,
    restar: (a, b) => a - b,
    multiplicar: (a, b) => a * b
  };

  const ejecutar = (estrategia, a, b) => estrategias[estrategia](a, b);

  return {
    ejecutar
  };
})();

console.log(estrategia.ejecutar("sumar", 1, 2)); // 3
console.log(estrategia.ejecutar("restar", 1, 2)); // -1
console.log(estrategia.ejecutar("multiplicar", 1, 2)); // 2

11.3 Patrones estructurales (Fachada, Decorador, Adaptador)

Los patrones estructurales son patrones que se utilizan para definir la forma en que los objetos se relacionan entre sí y cómo se componen para formar estructuras más grandes. En JavaScript, algunos de los patrones estructurales más comunes son el patrón Fachada, el patrón Decorador y el patrón Adaptador.

Ejemplo:

// Fachada
const fachada = (() => {
  const complejoSistema1 = new ComplejoSistema1();
  const complejoSistema2 = new ComplejoSistema2();

  const operacionCompleja = () => {
    complejoSistema1.operacion1();
    complejoSistema2.operacion2();
    complejoSistema1.operacion3();
  };

  return {
    operacionCompleja
  };
})();

fachada.operacionCompleja();

// Decorador
const decorador = (() => {
  class Componente {
    constructor() {
      this.elemento = document.createElement("div");
    }

    dibujar() {
      this.elemento.innerHTML = "Esto es un componente";
      return this.elemento;
    }
  }

  class Decorador1 extends Componente {
    dibujar() {
      this.elemento.classList.add("decorador1");
      super.dibujar();
    }
  }

  class Decorador2 extends Componente {
    dibujar() {
      this.elemento.classList.add("decorador2");
      super.dibujar();
    }
  }

  const componente = new Decorador1();
  const componenteDecorado = new Decorador2(componente);
  document.body.appendChild(componenteDecorado.dibujar());
})();

// Adaptador
const adaptador = (() => {
  class APIExterna {
    obtenerDatos() {
      return "Esto es un dato de la API externa";
    }
  }

  class AdaptadorAPIExterna {
    constructor() {
      this.apiExterna = new APIExterna();
    }

    obtenerDatosAdaptados() {
      const datos = this.apiExterna.obtenerDatos();
      return `Datos adaptados: ${datos}`;
    }
  }

  const adaptador = new AdaptadorAPIExterna();
  console.log(adaptador.obtenerDatosAdaptados());
})();

11.4 Patrones de arquitectura (MVC, MVVM, Flux)

Los patrones de arquitectura son patrones que se utilizan para definir la estructura y el flujo de datos de una aplicación. En JavaScript, algunos de los patrones de arquitectura más comunes son el patrón MVC (Modelo-Vista-Controlador), el patrón MVVM (Modelo-Vista-VistaModelo) y el patrón Flux.

Te recomendamos leer:  Módulos y Paquetes

Ejemplo:

// MVC
const mvc = (() => {
  class Modelo {
    constructor() {
      this.datos = "Esto es un dato del modelo";
    }

    obtenerDatos() {
      return this.datos;
    }
  }

  class Vista {
    constructor() {
      this.elemento = document.createElement("div");
    }

    dibujar(datos) {
      this.elemento.innerHTML = datos;
      return this.elemento;
    }
  }

  class Controlador {
    constructor(modelo, vista) {
      this.modelo = modelo;
      this.vista = vista;
    }

    iniciar() {
      const datos = this.modelo.obtenerDatos();
      const elemento = this.vista.dibujar(datos);
      document.body.appendChild(elemento);
    }
  }

  const modelo = new Modelo();
  const vista = new Vista();
  const controlador = new Controlador(modelo, vista);
  controlador.iniciar();
})();

// MVVM
const mvvm = (() => {
  class VistaModelo {
    constructor() {
      this.datos = "Esto es un dato del vistaModelo";
    }

    obtenerDatos() {
      return this.datos;
    }
  }

  class Vista {
    constructor() {
      this.elemento = document.createElement("div");
      this.enlazar(new VistaModelo());
    }

    enlazar(vistaModelo) {
      this.vistaModelo = vistaModelo;
      this.actualizar();
    }

    actualizar() {
      const datos = this.vistaModelo.obtenerDatos();
      this.elemento.innerHTML = datos;
    }
  }

  const vista = new Vista();
  document.body.appendChild(vista.elemento);
})();

// Flux
const flux = (() => {
  const tienda = (() => {
    let datos = "Esto es un dato de la tienda";

    const obtenerDatos = () => datos;

    const actualizarDatos = nuevoDato => {
      datos = nuevoDato;
    };

    return {
      obtenerDatos,
      actualizarDatos
    };
  })();

  const acciones = {
    actualizarDatos: nuevoDato => tienda.actualizarDatos(nuevoDato)
  };

  const vista = (() => {
    const elemento = document.createElement("div");

    const actualizar = () => {
      const datos = tienda.obtenerDatos();
      elemento.innerHTML = datos;
    };

    tienda.suscribirse(actualizar);

    return elemento;
  })();

  acciones.actualizarDatos("Esto es un nuevo dato");
  document.body.appendChild(vista);
})();

11.5 Ejemplos y casos de uso

Algunos ejemplos y casos de uso de los patrones de diseño en JavaScript incluyen:

  • Utilizar el patrón Constructor para crear objetos con propiedades y métodos específicos.
  • Utilizar el patrón Módulo para encapsular código y exponer solo las funcionalidades necesarias.
  • Utilizar el patrón Singleton para garantizar que solo haya una instancia de un objeto en la aplicación.
  • Utilizar el patrón Observador para notificar a múltiples objetos cuando ocurre un evento.
  • Utilizar el patrón Iterador para recorrer una colección de objetos de manera secuencial.
  • Utilizar el patrón Estrategia para definir diferentes algoritmos y seleccionar el más adecuado en tiempo de ejecución.
  • Utilizar el patrón Fachada para simplificar la interacción con sistemas complejos.
  • Utilizar el patrón Decorador para agregar funcionalidades adicionales a objetos de manera dinámica.
  • Utilizar el patrón Adaptador para adaptar la interfaz de un objeto a la interfaz esperada por la aplicación.
  • Utilizar el patrón MVC para separar la lógica de negocio, la interfaz de usuario y el controlador en una aplicación.
  • Utilizar el patrón MVVM para separar la lógica de negocio y la interfaz de usuario mediante un vistaModelo.
  • Utilizar el patrón Flux para manejar el flujo de datos unidireccional en una aplicación.
Rate this post

Deja un comentario

Desarrolladores web