Sample implementation of the Abstract Factory design pattern

I am going to create a Bank and Account interface and some concrete classes implementing these interfaces. Here, I also create an abstract factory class, AbstractFactory. I have some factory classes, BankFactory and AccountFactory; these classes extend the AbstractFactory class. I will also create a FactoryProducer class to create the factories.

Let's see this design pattern in the following image:

UML diagram for the Abstract Factory design pattern

Create a demo class, AbstractFactoryPatternMain; it uses FactoryProducer to get an AbstractFactory object. Here, I pass information such as ICICI, YES to AbstractFactory to get an object of Bank, and I also pass information such as SAVING, CURRENT to AbstractFactory to get an Account type.

Here is the code for Bank.java, which is an interface:

    package com.packt.patterninspring.chapter2.model; 
    public interface Bank { 
      void bankName(); 
    } 

Now let's create ICICIBank.java, which implements the Bank interface:

    package com.packt.patterninspring.chapter2.model; 
    public class ICICIBank implements Bank { 
      @Override 
      public void bankName() { 
        System.out.println("ICICI Bank Ltd."); 
      } 
    } 

Let's create another YesBank.java, an implementing Bank interface:

    package com.packt.patterninspring.chapter2.model; 
    public class YesBank implements Bank{ 
      @Override 
      public void bankName() { 
         System.out.println("Yes Bank Pvt. Ltd."); 
      } 
   } 

In this example, I am using the same interface and implementing classes of Account as I used in the Factory pattern example in this book.

AbstractFactory.java is an abstract class that is used to get factories for Bank and Account objects:

    package com.packt.patterninspring.chapter2.abstractfactory.pattern; 
    import com.packt.patterninspring.chapter2.model.Account; 
    import com.packt.patterninspring.chapter2.model.Bank; 
    public abstract class AbstractFactory { 
      abstract Bank getBank(String bankName); 
      abstract Account getAccount(String accountType); 
    } 

BankFactory.java is a factory class extending AbstractFactory to generate an object of the concrete class based on the given information:

    package com.packt.patterninspring.chapter2.abstractfactory.pattern;
import com.packt.patterninspring.chapter2.model.Account;
import com.packt.patterninspring.chapter2.model.Bank;
import com.packt.patterninspring.chapter2.model.CurrentAccount;
import com.packt.patterninspring.chapter2.model.SavingAccount;
public class AccountFactory extends AbstractFactory
{
final String CURRENT_ACCOUNT = "CURRENT";
final String SAVING_ACCOUNT = "SAVING";
@Override
Bank getBank(String bankName)
{
return null;
}
//use getAccount method to get object of type Account
//It is factory method for object of type Account
@Override
public Account getAccount(String accountType){
if(CURRENT_ACCOUNT.equals(accountType))
{
return new CurrentAccount();
}
else if(SAVING_ACCOUNT.equals(accountType))
{
return new SavingAccount();
}
return null;
}
}

AccountFactory.java is a factory class that extends AbstractFactory.java to generate an object of the concrete class based on the given information:

     package com.packt.patterninspring.chapter2.abstractfactory.pattern; 
     import com.packt.patterninspring.chapter2.model.Account; 
     import com.packt.patterninspring.chapter2.model.Bank; 
     import com.packt.patterninspring.chapter2.model.CurrentAccount; 
     import com.packt.patterninspring.chapter2.model.SavingAccount; 
     public class AccountFactory extends AbstractFactory { 
       final String CURRENT_ACCOUNT = "CURRENT"; 
       final String SAVING_ACCOUNT  = "SAVING"; 
       @Override 
       Bank getBank(String bankName) { 
          return null; 
      } 
      //use getAccount method to get object of type Account    
      //It is factory method for object of type Account 
      @Override 
      public Account getAccount(String accountType){   
        if(CURRENT_ACCOUNT.equals(accountType)) {   
               return new CurrentAccount();   
        }
else if(SAVING_ACCOUNT.equals(accountType)){ return new SavingAccount(); } return null; } }

FactoryProducer.java is a class that creates a Factory generator class to get factories by passing a piece of information, such as Bank or Account:

    package com.packt.patterninspring.chapter2.abstractfactory.pattern; 
    public class FactoryProducer { 
      final static String BANK    = "BANK"; 
      final static String ACCOUNT = "ACCOUNT"; 
      public static AbstractFactory getFactory(String factory){ 
         if(BANK.equalsIgnoreCase(factory)){ 
               return new BankFactory(); 
         }
else if(ACCOUNT.equalsIgnoreCase(factory)){ return new AccountFactory(); } return null; } }

FactoryPatterMain.java is a demo class for the Abstract Factory design pattern. FactoryProducer is a class to get AbstractFactory in order to get the factories of concrete classes by passing a piece of information, such as the type:

    package com.packt.patterninspring.chapter2.factory.pattern; 
    import com.packt.patterninspring.chapter2.model.Account; 
    public class FactoryPatterMain { 
      public static void main(String[] args) { 
         AccountFactory accountFactory = new AccountFactory(); 
         //get an object of SavingAccount and call its accountType() 
method. Account savingAccount = accountFactory.getAccount("SAVING"); //call accountType method of SavingAccount savingAccount.accountType(); //get an object of CurrentAccount and call its accountType()
method. Account currentAccount = accountFactory.getAccount("CURRENT"); //call accountType method of CurrentAccount currentAccount.accountType(); } }

You can test this file and see the output on the console:

Now that we've seen the abstract Factory design pattern, let's turn to a different variant of it-the singleton design pattern.