Los patrones de diseño de software describen cómo resolver problemas recurrentes. Si tienes un problema de diseño es muy probable que ya exista un patrón que lo solucione, no reinventes la rueda.
Me gusta pensar que los patrones de diseño de software son como la caja de herramientas de los desarrolladores, donde usas la herramienta adecuada para solucionar un problema determinado.
Patrones de diseño los creacionales
Estos nos proveen soluciones para la creación de objetos, permitiéndonos hacer un sistema independiente de cómo sus objetos son creados. Estos son los dos más usados:
Singleton
Nos permite garantizar que una clase solo tenga una única instancia y proporciona un punto de acceso global a ella.
Resuelve problemas como:
- ¿Cómo podemos garantizar que una clase tenga una sola instancia?
- ¿Cómo podemos acceder globalmente a una única instancia de una clase?
Ejemplos de uso:
Podemos usarlo para leer configuraciones, cargar pool de conexiones a la base de datos, registro de logs, colas de impresión etc.
Solución:
- Define una constante
INSTANCE
de tipoSingleton
que tendrá la instancia única de la clase, al ser una constante será inicializada una vez y nunca cambiará. - Oculta el constructor de la clase estableciendo su visibilidad como privada, esto nos asegura que la clase no pueda ser instanciada fuera de ella.
private Singleton
. - Define un método estático para retornar la instancia única de la clase, al ser estático podemos acceder fácilmente a través del nombre de la clase y el nombre del método
Singleton.getInstance()
.
Singleton.java
public class Singleton {
// 1. La constante INSTANCE es la instancia única de la clase.
private static final Singleton INSTANCE = new Singleton();
// 2. Constructor oculto.
private Singleton() {}
// 3. Método estático de acceso público que retorna la instancia única.
public static Singleton getInstance() {
return INSTANCE;
}
}
Main.java
class Main {
public static void main(String[] args) {
Singleton a = Singleton.getInstance();
Singleton b = Singleton.getInstance();
if (a == b) {
System.out.println("La instancia es única");
}
}
}
Factory Method
Es un método que nos permite crear instancias de objetos de un tipo determinado, encapsulando así la creación de dichos objetos.
Resuelve problemas como:
- ¿Cómo podemos crear objetos de un tipo (método de pago) sino conocemos el objeto que debemos instanciar (Paypal, Tarjeta de Crédito, Efectivo), ya que solo lo sabremos en tiempo de ejecución?
- ¿Cómo puede una clase diferir la instanciación a subclases?
Ejemplos de uso:
Podrías implementar una fábrica para obtener un adaptador de una base de datos (Postgres, Oracle, MySQL) o un método de pago de una tienda en línea (Paypal, Tarjeta de Crédito, Efectivo). etc.
Solución:
Este patrón está compuesto por los siguientes elementos:
- Producto: Declara una interfaz
PayMethod
que especifique los métodos (pay()
) que deberán implementar los Productos concretos. - Productos Concretos: Son las implementaciones de la interfaz del Producto.
Paypal
,CreditCard
yCash
- Creador : Es la clase que contiene el método de fábrica que devuelve nuevos objetos del Producto.
PayMethod.java
// Producto
public interface PayMethod {
String pay();
}
Paypal.java
// Producto Concreto Paypal
public class Paypal implements PayMethod {
@Override
public String pay() {
return "Pagando con Paypal";
}
}
CreditCard.java
// Producto Concreto CreditCard
public class CreditCard implements PayMethod {
@Override
public String pay() {
return "Pagando con tarjeta crédito";
}
}
Cash.java
// Producto Concreto Cash
public class Cash implements PayMethod {
@Override
public String pay() {
return "Pagando con Cash";
}
}
FactoryPayMethod.java
public class FactoryPayMethod {
// Creador
public enum PMTypes{Paypal, CreditCard, Cash}
public static PayMethod getPayMethod(PMTypes payMethod) {
switch(payMethod) {
case Paypal:
return new Paypal();
case CreditCard:
return new CreditCard();
case Cash:
return new Cash();
}
return null;
}
}
Main.java
class Main {
public static void main(String[] args) {
PayMethod payMethod = FactoryPayMethod.getPayMethod(FactoryPayMethod.PMTypes.Paypal);
System.out.println(payMethod.pay()); // Pagando con Paypal
}
}
Si quieres aprender más sobre los distintos patrones de diseño tenemos tres cursos que te ayudarán a ser un mejor programador:
✅ Patrones de diseño - Creacionales
✅ Patrones de diseño - Estructurales
✅ Patrones de diseño - Comportamiento
Eso es todo por hoy, cuéntame en los comentarios si te ha gustado este artículo y de que otros temas te gustaría que hablemos.
Referencias
- The GoF Design Patterns Reference Version 2.0 / 01.10.2017 / Generated 12.01.2018, w3sDesign http://www.w3sdesign.com/GoF_Design_Patterns_Reference0100.pdf
- https://refactoring.guru/design-patterns