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.ICICIBank;
import com.packt.patterninspring.chapter2.model.YesBank;
public class BankFactory extends AbstractFactory {
final String ICICI_BANK = "ICICI";
final String YES_BANK = "YES";
//use getBank method to get object of name bank
//It is factory method for object of name bank
@Override
Bank getBank(String bankName) {
if(ICICI_BANK.equalsIgnoreCase(bankName)){
return new ICICIBank();
} else if(YES_BANK.equalsIgnoreCase(bankName)){
return new YesBank();
}
return null;
}
@Override
Account getAccount(String accountType) {
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.