Patrón de diseño Factory Method en Java
El patrón de diseño Factory Method, es un patrón de diseño que lo clasificamos dentro de los patrones creacionales.
El patrón Factory Method nos proporciona una interfaz para crear objetos en una superclase, permitiendo a las subclases alterar el tipo de objeto que se crea.
Cuándo usar el patrón Factory Method
Vamos a hacer uso del patrón Factory cuando queramos hacer uso de una nueva operación dentro de nuestra lógica de negocio.
Imagina que tenemos un sistema para pagar las compras que realizamos en una tienda, este sistema es muy bueno pero solo permite pagar en dinero. Por lo que decidimos aumentar las formas de pago con tarjeta, por lo que esta nueva funcionalidad podrá ser usada creando una nueva clase a través de new, en el que llamaremos a la funcionalidad que necesitamos.
Para que tanto pago con tarjeta como pago en dinero devuelvan el mismo tipo, ambas clases heredarán de una interfaz común que devolverá el mismo tipo. Es decir tenemos dos productos:
Una vez tenemos estos dos productos que van en función de la operación que quieras realizar, necesitamos implementar las operaciones que devolverán el producto anterior.
Es decir, vamos a crear una factoría en donde vamos añadiendo nuevos métodos y formas de pago. De esta manera al añadir nuevos métodos no deberíamos de realizar modificaciones en el código.
Vamos a utilizar el patrón Factory Method cuando no conocemos las dependencias e interacciones de los objetos ni los tipos exactos con los que vamos a trabajar.
Cómo aplicar el Patrón Factory Method
La idea del Patrón Factory es poder crear un almacén o factoría de operaciones y que permite ser extensible para poder añadir las operaciones que se necesiten bajo demanda.
El Patrón Factory Method crea una interfaz común que será implementada por aquellos productos que necesite nuestras operaciones. Una vez creamos nuestras operaciones crearemos una clase para ejecutar estas operaciones.
Implementación Patrón Factory Method
A continuación vamos a ver un diagrama de aplicación del Patrón Factory Method.
Como podemos ver en el diagrama anterior, podríamos dividir el patron Factory Method en dos bloques, por un lado tendríamos la creación del producto, y por otro lado las creaciones de las operaciones que vamos a querer realizar.
El primer bloque creará las operaciones que devolverán un producto concreto en función de la implementación que se lleve a cabo. Por ejemplo, como veremos en el siguiente ejemplo, si tenemos en una tienda diversos métodos de pago, los productos serán pago en efectivo o por tarjeta de crédito y las operaciones realizar un pago u otro.
Ejemplo de Patrón Factory Method
Nuestro siguiente ejemplo se basa en una tienda en la que puedes realizar pagos de diferente manera, en dinero o por pago por tarjeta, pero es posible que en un futuro se pueda pagar de más formas.
Para ver directamente el código del ejemplo lo puedes hacer desde nuestro github.
Para poder crear nuestra factoría vamos a comenzar creando una interfaz que se llama payment().
Creación de interfaz factoría para el Patrón Factory Method
La siguiente clase en una interfaz que será implementada por todos los métodos que la necesiten:
public interface Payment { void paymentMethod(); }
Creación de métodos de Pago
A continuación vamos a crear dos «productos» para nuestra factoría, el primero será el pago en dinero (cash) y el segundo será el pago con tarjeta de crédito.
public class Cash implements Payment{ @Override public void paymentMethod() { System.out.println("Payment Method: Cash"); } }
public class CreditCard implements Payment{ @Override public void paymentMethod() { System.out.println("Payment Method: Credit Card"); } }
Creación de las lógica de uso del Producto en el Patrón Factory Method
A continuación vamos a crear la clase (abstracta) que se encargará de devolver el producto en función del tipo de pago. Por simplicidad hemos
public abstract class Shop { public void buySomething() { Payment payment = makePayment(); makePayment().paymentMethod(); } public abstract Payment makePayment(); }
public class CreditPayment extends Shop { @Override public Payment makePayment() { return new CreditCard(); } }
Probar el ejemplo de nuestro Patrón
A continuación mostramos el fragmento de código necesario para poder ejecutar nuestras pruebas.
public class Application { private static Shop shop; public static void main(String[] args) { configure(args); goShopping(); } static void configure(String[] args) { if (null != args && args[0].equalsIgnoreCase("creditCard")) shop = new CreditPayment(); else { shop = new CashPayment(); } } static void goShopping() { shop.buySomething(); } }
Pros de Patrón Factory Method
- Se evita el acoplamiento entre las operaciones y los productos a devolver.
- Se cumple el Single Responsibility Principle, es decir, responsabilidad única de cada operación.
- Permite añadir nuevas operaciones gracias a un código abierto.
Contras de Patrón Factory Method
- Incrementa la complejidad del código debido a las nuevas clases que se tienen que introducir.
Conclusión
El uso del patrón de diseño Factory Method nos va a ayudar a tener un código mucho más extensible permitiendo añadir operaciones para casos en los que es necesario incrementar el número de operaciones.
Si quieres ver el ejemplo completo lo puedes hacer en nuestro github.
Si necesitas más información puedes escribirnos un comentario o un correo electrónico a refactorizando.web@gmail.com o también nos puedes contactar por nuestras redes sociales Facebook o twitter y te ayudaremos encantados!