
En ingeniería de software, los patrones de diseño son una solución general y reutilizable para problemas comunes que ocurren en un determinado contexto cuando estamos diseñando software. Estos no son una solución final que se puede transformar en código fuente, sino que son una descripción o plantilla de cómo resolver un problema en diferentes situaciones.
Antes de continuar, puedes leer este post o ver y escuchar esta información en formato de video en nuestro canal de Youtube, te dejamos el link por si prefieres este formato. 😃 👍
Hola mundo, y bienvenidos a este post. Los patrones de diseño son una formalización de mejores prácticas que un ingeniero de software puede utilizar para resolver un problema común. En programación orientada a objetos, los patrones de diseño por lo general muestran relaciones e interacciones entre distintas clases y objetos. Aunque patrones que impliquen un estado mutable no son útiles cuando se sigue una programación funcional estricta. Algunos patrones podrían ser catalogados de innecesarios o inútiles dependiendo del paradigma, lenguaje o framework que se esté utilizando, ya que estos podrían tener definidas herramientas o formas específicas de resolver ciertos problemas.
En este post veremos 7 patrones de diseño de software comunes, pero no pienses que estas son balas de plata, ya que estos podrían ser una pésima idea dependiendo de tu contexto. Y antes de mencionarte los 7 patrones de diseño más utilizados, qué problema resuelven y cómo se deben implementar.
Singleton
En ingeniería de software, el patrón singleton restringe la instanciación de una clase a solo una única instancia. Esto es útil cuando necesitas solo una instancia de una clase para poder coordinar acciones entre distintos sistemas, si tu sistema tiene solo una base de datos, singleton. Si tienes solo una api, singleton, si tienes que conectarte con un servicio como AWS y solo con una instancia de este, singleton.
Dependiendo del lenguaje podría ser que no necesites implementar una clase singleton, en nodeJS puedes implementar un objeto literal y exportarlo, este se comportará igual que un singleton, ya que el motor de NodeJS tiene implementado un caché con las variables exportadas. Por lo que siempre será la misma.
Pero en caso de Java, que tiene una implementación más estricta, debe implementarse de la siguiente manera:
public final class Singleton {
private static final Singleton INSTANCE = new Singleton();
private Singleton() {
// Constructor privado para evitar que se cree nuevas instancias.
}
public static Singleton getInstance() {
return INSTANCE;
}
}
Primero se crea la clase, luego defines una propiedad llamada Singleton la cual tendrá la instancia que creamos. Luego definimos un constructor llamado Singleton. Este constructor se encargará de construir el objeto que vamos a necesitar en un futuro. Luego creamos un método llamado getInstance que se encargará de devolver la instancia de nuestro singleton.
El siguiente patrón que veremos a continuación es el patrón decorador.
Decorador
En programación orientada a objetos el patrón decorador es un patrón que permite agregar funcionalidades a un objeto sin alterar el comportamiento de otras instancias de objetos de la misma clase. Soluciona el problema de agregar o quitar responsabilidades a un objeto en el run-time y es una alternativa flexible a las subclases.
Una implementación en Java sería la siguiente:
public class Coffe {
public double getCost() {
return 1;
}
public String getIngredients() {
return "Coffee";
}
}
public class WithMilk {
public WithMilk(Coffe c){
this.coffee = c;
}
public double getCost() {
return coffee.getCost() + 1;
}
public String getIngredients() {
return this.coffee.getIngredients() + ", Milk";
}
}
Coffe coffee = new Coffe();
WithMilk coffeWithMilk = new WithMilk(coffee);
Si vamos a vender café, vamos a necesitar saber el precio y también sus ingredientes, que claro el café tiene café y agua.
Pero podríamos querer vender también café con leche, y en lugar de crear una nueva clase y reimplementar los métodos lo mejor sería tomar la taza que ya existe y pasarla por el constructor a una clase con leche, esta clase crea métodos con los mismos nombres, pero llama primero a los métodos del objeto Cafe, y cuando alguien solicite el precio agregamos el valor de la leche, y cuando solicite los ingredientes agregamos también como ingrediente la leche.
El siguiente patrón es el patrón mediador
Mediador
En ingeniería de software, el patrón mediador define un objeto el cual encapsula cómo otros objetos van a interactuar. Este patrón se considera un patrón de comportamiento, ya que puede alterar cómo se ejecuta la aplicación. Un patrón mediador en JavaScript se puede definir de la siguiente manera:
const mediator = (() => {
const events = {}
const suscribe = (event, fn) => {
if (!events[event]) {
events[event] = []
}
events[event].push(fn)
}
const dispatch = function(event, payload){
if (!events[event]) {
return false
}
events[event].forEach(fn => fn(payload))
}
return {
suscribe,
dispatch
}
})()
mediator.suscribe('login', ({username, password}) => {
// acá inicio sesión...
})
mediator.dispatch("login", {username: "chanchitoFeliz", password: "123456"})
Primero definimos un IIFE, que significa Immediate Invoked Function expression, a esta le agregamos una variable la que contendrá los eventos que pueden despacharse o escucharse. Seguido creamos una function llamada sub, esta se encargara de recibir el evento y también la función que se ejecutara, esta debe quedar registrada en nuestros eventos. Después creamos una función llamada dispatch, esta recibirá el evento que se está despachando y también la data que se le pasará como argumento a la función que suscribiremos.
Esta función recorrerá todos los eventos que se encuentran registrados, y de encontrar uno o más de uno, ejecutará las funciones y pasará los datos a cada uno de estas. Luego retornamos estas funciones y con eso ya construimos nuestro mediador. La diferencia entre un mediador y un observador es que el mediador necesita un objeto aparte encargado de manejar las comunicaciones entre todos los objetos, mientras que el observador modifica el objeto que tiene que escuchar. El patrón observador no tiene este intermediario. Redux implementa el patrón mediador.
Y si quieres aprender Redux, te recomendamos nuestro curso React – Guía definitiva: hooks, router, redux, next + Proyectos , en el que aprenderás a usar la libreríaReact junto con una sección exclusiva de Redux para dominar esta herramienta.
Nuestro siguiente patrón es el patrón adaptador
Adaptador
En ingeniería de software el patrón adaptador permite que un objeto que no está diseñado para funcionar con una interfaz, lo modifique para que este sí pueda funcionar con esta.
En Python, podemos definir un patrón adaptador creando dos clases, primero creamos una clase Android y una clase iPhone, Android se recarga con usb y iPhone se recarga con lightning. Puedo crear una clase cargador que reciba el teléfono que tiene que cargar, pero este solo funciona con USB, por lo que para que el iPhone se pueda cargar, puedo crear una clase iPhoneAdapter que reciba el iPhone, y que cuando se llame a su método para cargar el teléfono con USB, que esté lo cargue con lightning. De esta manera, este iPhone adaptado puede utilizarse con el cargador de Android:
class Iphone:
__name__ = "Iphone"
def __init__(self):
self.connector = False
def use_lightning(self):
self.connector = True
def recharge(self):
if self.connector:
print("Cargando...")
class Android:
__name__ = "Android"
def __init__(self):
self.connector = False
def use_usb(self):
self.connector = True
def recharge(self):
if self.connector:
print("Cargando...")
class IphoneAdapter:
def __init__(self, iphone):
self.phone = iphone
def use_usb(self):
self.phone.use_lightning()
def recharge(self):
if self.phone.connector:
print("Cargando...")
El siguiente patrón es el MVC.
MVC
El patrón Model-View-Controller, o también conocido como MVC se utiliza comúnmente para desarrollar interfaces de usuario, dividiendo la lógica en 3 elementos interconectados: El modelo, este contiene la lógica de tu aplicación, se encarga de llamar a los distintos datos y contiene las reglas de negocio. La vista es la representación visual de los datos que se recolectan, esto es lo que verá el usuario y el controlador se encarga de recibir los datos, transformarlos en algo útil para el modelo, recibe los datos del modelo y luego construye la respuesta para el cliente.
Un ejemplo de MVC se puede ver facilmente en NodeJS con express, donde creamos un endpoint encargado de recibir las peticiones de nuestro usuario, con esa petición vamos a buscar los datos que este necesita, luego le devolvemos al usuario estos datos, y por supuesto manejamos las excepciones en el caso que estas existan. Si existe un HTML lo renderizamos con los datos que recolectamos, pero en este caso devolvemos los datos como si fuese una API rest, por lo que nuestra «vista» en este caso es un JSON.
const express = require('express');
const Model = require('./Model');
const app = express();
app.get('/', async (req, res) => {
try{
const {data} = req.body
const result = await Model.create(data)
res.send(result)
} catch (err) {
res.status(500)
res.send("An error has ocurred: " + err.message)
}
})
El siguiente patrón es el patrón flux.
Flux
El patrón flux fue desarrollado por Facebook hace algunos años en respuesta a los patrones ya existentes, y este complementa el funcionamiento de la librería que ellos crearon llamada React. Flux también es un framework con el mismo nombre, pero lo importante de este patrón, a diferencia del MVC es que este cumple con un ciclo circular, donde el usuario gatilla un evento desde la vista, este realiza unas acciones que luego actualizan el estado de nuestra aplicación, y luego de que el estado fue actualizado nuestra aplicación se renderizará nuevamente, actualizando de esta manera la vista.

Ojalá que después de haber leido este post puedas hacerte una idea de algunos de los patrones que existen, no pienses que estos son los mejores o balas de plata, estos sencillamente son herramientas que se pueden agregar a tu arsenal. Y por supuesto que cuando los estés estudiando, puedes hacerlo escuchando mi música, ya que esta ayuda a la concentración y hacer tus estudios y trabajo más productivos, puedes encontrar a «Hola Beats» en Spotify y en Apple Music.
Y esto ha sido todo de este post, si te ha encantado, ¡golpea al botón de me gusta!, visita nuestra Academia Hola Mundo, donde encontrarás todos los cursos para formarte como un desarrollador o desarrolladora.
Y para no perderte nada, no olvides suscribirte a este blog, seguirnos en todas las redes como Youtube, Twitter e Instagram.
¡Hasta la próxima!, y chao mundo
Comments (1)
7 antipatrones del desarrollo de software y como prevenirlos – Hola Mundosays:
marzo 6, 2023 at 5:29 pm[…] es decir, “patrones de diseño y como implementarlos” , te dejaremos el link al post: Los 6 patrones de diseño más utilizados en la industria y si quieres otro post mas por si te interesa saber ¿Cómo escribir código como un programador […]