Design Pattern

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“.

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.

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
Dinesh Rajput

Dinesh Rajput is the chief editor of a website Dineshonjava, a technical blog dedicated to the Spring and Java technologies. It has a series of articles related to Java technologies. Dinesh has been a Spring enthusiast since 2008 and is a Pivotal Certified Spring Professional, an author of a book Spring 5 Design Pattern, and a blogger. He has more than 10 years of experience with different aspects of Spring and Java design and development. His core expertise lies in the latest version of Spring Framework, Spring Boot, Spring Security, creating REST APIs, Microservice Architecture, Reactive Pattern, Spring AOP, Design Patterns, Struts, Hibernate, Web Services, Spring Batch, Cassandra, MongoDB, and Web Application Design and Architecture. He is currently working as a technology manager at a leading product and web development company. He worked as a developer and tech lead at the Bennett, Coleman & Co. Ltd and was the first developer in his previous company, Paytm. Dinesh is passionate about the latest Java technologies and loves to write technical blogs related to it. He is a very active member of the Java and Spring community on different forums. When it comes to the Spring Framework and Java, Dinesh tops the list!

Share
Published by
Dinesh Rajput

Recent Posts

Strategy Design Patterns using Lambda

Strategy Design Patterns We can easily create a strategy design pattern using lambda. To implement…

2 years ago

Decorator Pattern using Lambda

Decorator Pattern A decorator pattern allows a user to add new functionality to an existing…

2 years ago

Delegating pattern using lambda

Delegating pattern In software engineering, the delegation pattern is an object-oriented design pattern that allows…

2 years ago

Spring Vs Django- Know The Difference Between The Two

Technology has emerged a lot in the last decade, and now we have artificial intelligence;…

2 years ago

TOP 20 MongoDB INTERVIEW QUESTIONS 2022

Managing a database is becoming increasingly complex now due to the vast amount of data…

2 years ago

Scheduler @Scheduled Annotation Spring Boot

Overview In this article, we will explore Spring Scheduler how we could use it by…

3 years ago