Abstract Factory Design Pattern – Creational Patterns

Abstract Factory Design Pattern is a creational design pattern, it is some high level design pattern that factory method design pattern. According to this design pattern, you just define an interface or abstract class to create related dependent object without specifying its concrete sub class. So here abstract factory return a factory of classes.

Let me more simply it for understanding, you have a set of factory method design pattern, you just put into under a factory using factory design pattern, means it is simply factory of factories. And you no need to know about all factories into factory, you can make your program using top level factory.

Abstract Factory Design Pattern

According to the Gang of Four:

“Provide an interface for creating families of related or dependent objects without specifying their concrete classes.”

In Abstract Factory pattern an interface is responsible for creating a factory of related objects without explicitly specifying their classes. Each generated factory can give the objects as per the Factory pattern.

Spring 5 Design Pattern Book

You could purchase my Spring 5 book that is with title name “Spring 5 Design Patterns“. This book is available on the Amazon and Packt publisher website. Learn various design patterns and best practices in Spring 5 and use them to solve common design problems. You could use author discount to purchase this book by using code- “AUTHDIS40“.
Spring-5-Design-Pattern

Class Diagram for the Abstract Factory Pattern

Let’s see the following class diagram for the Abstract Factory Design Pattern, it illustrates all about its component classes and interfaces.

Abstract Factory Design Pattern

Let’s see the classes and objects participating in this pattern are:

AbstractFactory (AbstractFactory )

  • It declares an interface for operations that create abstract products such as Bank and Account.

ConcreteFactory (BankFactory, AccountFactory)

  • It implements the operations to create concrete product objects such as Bank and Account.

AbstractProduct (Account, Bank)

  • It declares an interface for a type of Account and Bank object.

Product (SavingAccount, CurrentAccount, ICICIBank, YesBank)

  • It defines defines account and bank objects to be created by the corresponding concrete factory
  • It implements the AbstractBank and AbstractAccount interfaces.

Client (AbstractFactoryPatternMain)

  • It uses FactoryProducer class.

Benefits of Abstract Factory Design Pattern

There are following benefits of using abstract factory design pattern.

  • Abstract Factory Design provides loose coupling between the component families. It also isolates the client code from concrete classes.
  • This design pattern is some higher level design than factory pattern.
  • This pattern provide better consistency at the construction time of objects across the application.
  • This pattern easily swap the component families.

Disadvantages of the Abstract Factory Pattern

There are following disadvantages of this pattern.

  • With the Abstract Factory pattern the decision about which factory to use is made at runtime.
  • Always be take great care with the choice of interfaces if there are any changes to any underlying detail of one factory, the interface might need to be modified for all the factories.
  • No idea, how many instances of a particular concrete factory should there be?
  • During design we don’t have to predict all future uses of this application.

Example of Abstract Factory Pattern

For example, in Spring Framework, you have one of FactoryBean implementation is LocalSessionFactoryBean, in order to get a reference of a bean that was associated with hibernate configuration, the specific configuration about DataSource should applied before get an object of SessionFactory. You can use the LocalSessionFactoryBean to apply the specific DataSource configuration in a consistent way. You may inject the result of a FactoryBean’s getObject() method into any other property.

Sample Implementation of Abstract Factory Design Pattern

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

Step 1: Create an interface Bank.

Bank.java

/**
 * 
 */
package com.doj.patterns.creational.abstractfactory;

/**
 * @author Dinesh.Rajput
 *
 */
public interface Bank {
	void bankName();
}

Step 2: Create concrete classes implementing the same above interface.

ICICIBank.java

/**
 * 
 */
package com.doj.patterns.creational.abstractfactory;

/**
 * @author Dinesh.Rajput
 *
 */
public class ICICIBank implements Bank {

	@Override
	public void bankName() {
		System.out.println("ICICI Bank Ltd.");
	}

}

YesBank.java

/**
 * 
 */
package com.doj.patterns.creational.abstractfactory;

/**
 * @author Dinesh.Rajput
 *
 */
public class YesBank implements Bank {

	@Override
	public void bankName() {
		System.out.println("Yes Bank Pvt. Ltd.");
	}

}

Step 3: Create an interface for Account.

Account.java

/**
 * 
 */
package com.doj.patterns.creational.abstractfactory;

/**
 * @author Dinesh.Rajput
 *
 */
public interface Account {
	void accountType();
}

Step 4: Create concrete classes implementing the same Account interface.

SavingAccount .java

/**
 * 
 */
package com.doj.patterns.creational.abstractfactory;

/**
 * @author Dinesh.Rajput
 *
 */
public class SavingAccount implements Account {

	@Override
	public void accountType() {
		System.out.println("SAVING ACCOUNT");
	}

}

CurrentAccount.java

/**
 * 
 */
package com.doj.patterns.creational.abstractfactory;

/**
 * @author Dinesh.Rajput
 *
 */
public class CurrentAccount implements Account {

	@Override
	public void accountType() {
		System.out.println("CURRENT ACCOUNT");
	}

}

Step 5: Create an Abstract class to get factories for Account and Bank Objects.

AbstractFactory.java

/**
 * 
 */
package com.doj.patterns.creational.abstractfactory;

/**
 * @author Dinesh.Rajput
 *
 */
public abstract class AbstractFactory {
	abstract Bank getBank(String bankName);
	abstract Account getAccount(String accountType);
}

Step 6 : Create Factory classes extending AbstractFactory to generate object of concrete class based on given information.

BankFactory.java

/**
 * 
 */
package com.doj.patterns.creational.abstractfactory;

/**
 * @author Dinesh.Rajput
 *
 */
public class BankFactory extends AbstractFactory {

	final String ICICI_BANK = "ICICI";
	final String YES_BANK   = "YES";

	@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

/**
 * 
 */
package com.doj.patterns.creational.abstractfactory;

/**
 * @author Dinesh.Rajput
 *
 */
public class AccountFactory extends AbstractFactory {

	final String CURRENT_ACCOUNT = "CURRENT";
	final String SAVING_ACCOUNT  = "SAVING";

	@Override
	Bank getBank(String bankName) {
		return null;
	}
	
	@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;  
    }

}

Step 7: Create a Factory Producer class to get factories by passing an information such as Bank or Account.

FactoryProducer.java

/**
 * 
 */
package com.doj.patterns.creational.abstractfactory;

/**
 * @author Dinesh.Rajput
 *
 */
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;
	}
}

Step 8 : Let’s use the FactoryProducer to get AbstractFactory in order to get factories of concrete classes by passing an information such as type.

AbstractFactoryPatternMain.java

/**
 * 
 */
package com.doj.patterns.creational.abstractfactory;

/**
 * @author Dinesh.Rajput
 *
 */
public class AbstractFactoryPatternMain {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		AccountFactory accountFactory = new AccountFactory();
		Account savingAccount = accountFactory.getAccount("SAVING");
		savingAccount.accountType();
		Account currentAccount = accountFactory.getAccount("CURRENT");
		currentAccount.accountType();

	}

}

Step 9: Let’s run above demo class and vrify the output.

SAVING ACCOUNT
CURRENT ACCOUNT

Previous
Next

One Response

  1. Jorge Morando July 18, 2018