Factory Method Design Pattern: Java, C#

Link Copied To Clipboard !

factory-method-design-pattern-java-csharp C#

Factory method is a design pattern used to create objects using common interface hiding the internal creation logic. Factory method design pattern a creational design pattern which uses interfaces and abstract classes in order to create objects but without exposing the creation logic. The most common usage of factory method is creating objects in runtime, what we call dynamic objects.

Problem Statement

Consider a case where we need to implement payment feature into an application. There will be multiple payment methods supported by an application and we need to process payment according to the user selected method. For example, if an user selects paypal, we will have to process using paypal, if an user selects a card payment, we will have to process using card payment and if an user selects bank transfer, we will have to process using bank transfer.

Solution

The solution to above problem is to create an interface or a parent abstract class, say PaymentMethod and create its sub-classes as PaypalPayment, CardPayment and BankPayment . These subclasses will have their own payment processing method. Now, our topic of discussion is how we create instances of these subclasses in runtime. We can simply create an instance of subclass whenever needed by doing some conditional check but this method will cause code duplication and will be less effective. The factory method design pattern introduces a FactoryClass which will do the heavy lifting of creating an appropriate instance depending upon the need in runtime. Basically, the factory class will have a method with return type of parent class or interface, having an argument type. By checking that argument, appropriate instance is created and returned. Let’s see how we can implement this payment method system using factory method design pattern.

Factory Method Design Pattern In Java

public interface PaymentMethod{
    public void pay();
}
public class PaypalPayment implements PaymentMethod{
    @Override
    public void pay(){
        //process payment using paypal
        System.out.println("Paying using paypal..");
    }
}
public class CardPayment implements PaymentMethod{
    @Override
    public void pay(){
        //process payment using card
        System.out.println("Paying using card..");
    }
}
public class BankPayment implements PaymentMethod{
    @Override
    public void pay(){
        //process payment using bank
        System.out.println("Paying using bank..");
    }
}
//This factory class is used to create instance instead of direct payment method instances
public class PaymentFactory{
    public static PaymentMethod getInstance(String paymentChannel){
        switch(paymentChannel){
            case "paypal":
                return new PaypalPayment();
            case "card":
                return new CardPayment();
            case "bank":
                return new BankPayment();
            default:
                throw new IllegalArgumentException("Invalid payment channel !");
        }
    }
}
public class Main{
  public static void main (String[]args){
    //instance will be created according to the argument passed
    PaymentMethod method = PaymentFactory.getInstance("paypal");
    method.pay ();
  }
}

Factory Method Design Pattern In C#

public interface IPaymentMethod{
    void Pay();
}
using System;
class PaypalPayment: IPaymentMethod{
    public void Pay(){
        //process payment using paypal
        Console.WriteLine("Paying using paypal..");
    }
}
using System;
class CardPayment: IPaymentMethod{
    public void Pay(){
        //process payment using card
        Console.WriteLine("Paying using card..");
    }
}
using System;
class BankPayment: IPaymentMethod{
    public void Pay(){
        //process payment using bank
        Console.WriteLine("Paying using bank..");
    }
}
using System;
public class PaymentFactory{
    public static IPaymentMethod getInstance(String paymentChannel){
        switch(paymentChannel){
            case "paypal":
                return new PaypalPayment();
            case "card":
                return new CardPayment();
            case "bank":
                return new BankPayment();
            default:
                throw new ArgumentException("Invalid payment channel !");
        }
    }
}

Note: An abstract class could also be used both in java and c#. Interface has been used for simplicity.


You May Also Like