<p><strong>Abstract Factory Design Pattern</strong> is a <strong><a href="https://dineshonjava.com/creational-design-patterns/">creational design pattern</a></strong>, it is some high level design pattern that <strong><a href="https://dineshonjava.com/factory-method-design-pattern/">factory method design pattern</a></strong>. 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.</p>
<p>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.</p>
<h2><strong>Abstract Factory Design Pattern</strong></h2>
<div style="text-align: left;">
<blockquote><p><em><strong>According to the Gang of Four:</strong></em></p>
<div style="text-align: left;">&#8220;Provide an interface for creating families of related or dependent objects without specifying their concrete classes.&#8221;</div>
</blockquote>
</div>
<p>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.</p>
<div style="background-color: #f2f9fc; border-radius: 3px; border: 1px solid #c9e6f2; line-height: 1.45; padding: 16px 16px 16px 16px;">
<h2 dir="ltr">Spring 5 Design Pattern Book</h2>
<div dir="ltr" style="color: #20124d; font-family: 'calibri' , sans-serif; font-size: 13pt; text-align: justify;">You could purchase my <strong>Spring 5 book</strong> that is with title name &#8220;<strong>Spring 5 Design Patterns</strong>&#8220;. This book is available on the <a href="https://www.amazon.in/Spring-Design-Patterns-Dinesh-Rajput/dp/1788299450/ref=sr_1_1?ie=UTF8&;qid=1507925340&;sr=8-1&;keywords=spring+5+design+pattern" target="_blank" rel="noopener"><strong>Amazon</strong></a> and <a href="https://www.packtpub.com/application-development/spring-5-design-patterns" target="_blank" rel="noopener"><strong>Packt</strong></a> publisher website. Learn various <strong>design patterns</strong> and <strong>best practices</strong> in Spring 5 and use them to solve common design problems. You could use author discount to purchase this book by using code- &#8220;<strong>AUTHDIS40</strong>&#8220;.</div>
<div dir="ltr"></div>
<div dir="ltr"><a href="https://www.amazon.in/Spring-Design-Patterns-Dinesh-Rajput/dp/1788299450/ref=sr_1_1?s=books&;ie=UTF8&;qid=1512607966&;sr=1-1&;keywords=dinesh+rajput" target="_blank" rel="noopener"><img class="aligncenter wp-image-3053 size-medium" title="Spring-5-Design-Pattern" src="https://dineshonjava.com/wp-content/uploads/2013/03/Spring-5-design-pattern-243x300.jpg" width="243" height="300" /></a></div>
</div>
<h2><strong>Class Diagram for the Abstract Factory Pattern</strong></h2>
<p>Let&#8217;s see the following class diagram for the Abstract Factory Design Pattern, it illustrates all about its component classes and interfaces.</p>
<p><img class="aligncenter size-full wp-image-3652" src="https://dineshonjava.com/wp-content/uploads/2017/12/Abstract-Factory.png" alt="Abstract Factory Design Pattern" width="769" height="414" /></p>
<p>Let&#8217;s see the classes and objects participating in this pattern are:</p>
<p><strong>AbstractFactory (AbstractFactory )</strong></p>
<ul>
<li>It declares an interface for operations that create abstract products such as Bank and Account.</li>
</ul>
<p><strong>ConcreteFactory (BankFactory, AccountFactory)</strong></p>
<ul>
<li>It implements the operations to create concrete product objects such as Bank and Account.</li>
</ul>
<p><strong>AbstractProduct (Account, Bank)</strong></p>
<ul>
<li>It declares an interface for a type of Account and Bank object.</li>
</ul>
<p><strong>Product (SavingAccount, CurrentAccount, ICICIBank, YesBank)</strong></p>
<ul>
<li>It defines defines account and bank objects to be created by the corresponding concrete factory</li>
<li>It implements the AbstractBank and AbstractAccount interfaces.</li>
</ul>
<p><strong>Client (AbstractFactoryPatternMain)</strong></p>
<ul>
<li>It uses FactoryProducer class.</li>
</ul>
<h2><strong>Benefits of Abstract Factory Design Pattern</strong></h2>
<p>There are following benefits of using abstract factory design pattern.</p>
<ul>
<li>Abstract Factory Design provides loose coupling between the component families. It also isolates the client code from concrete classes.</li>
<li>This design pattern is some higher level design than factory pattern.</li>
<li>This pattern provide better consistency at the construction time of objects across the application.</li>
<li>This pattern easily swap the component families.</li>
</ul>
<div style="text-align: left;">
<blockquote><p><strong>also read:</strong></p>
<ul style="text-align: left;">
<li><a title="https://dineshonjava.com/creational-design-patterns/" href="https://dineshonjava.com/creational-design-patterns/">Creational GoF Design Patterns</a></li>
<li><a title="https://dineshonjava.com/structural-design-patterns/" href="https://dineshonjava.com/structural-design-patterns/">Structural GoF Design Patterns</a></li>
<li><a title="https://dineshonjava.com/behavioral-design-pattern/" href="https://dineshonjava.com/behavioral-design-pattern/">Behavioral GoF Design Patterns</a></li>
</ul>
</blockquote>
</div>
<h2><strong>Disadvantages of the Abstract Factory Pattern</strong></h2>
<p>There are following disadvantages of this pattern.</p>
<ul>
<li>With the Abstract Factory pattern the decision about which factory to use is made at runtime.</li>
<li>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.</li>
<li>No idea, how many instances of a particular concrete factory should there be?</li>
<li>During design we don&#8217;t have to predict all future uses of this application.</li>
</ul>
<h2><strong>Example of Abstract Factory Pattern</strong></h2>
<p><strong>For example,</strong> in Spring Framework, you have one of <strong>FactoryBean</strong> implementation is <strong>LocalSessionFactoryBean</strong>, 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 <strong>SessionFactory</strong>. You can use the <strong>LocalSessionFactoryBean</strong> 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.</p>
<h2><strong>Sample Implementation of Abstract Factory Design Pattern</strong></h2>
<p>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.</p>
<h3>Step 1: Create an interface Bank.</h3>
<p><strong>Bank.java</strong></p>
<pre class="highlight">/** 
 * 
 */ 
package com.doj.patterns.creational.abstractfactory; 
 
/** 
 * @author Dinesh.Rajput 
 * 
 */ 
public interface Bank { 
	void bankName(); 
} 
 
</pre>
<h3>Step 2: Create concrete classes implementing the same above interface.</h3>
<p><strong>ICICIBank.java</strong></p>
<pre class="highlight">/** 
 * 
 */ 
package com.doj.patterns.creational.abstractfactory; 
 
/** 
 * @author Dinesh.Rajput 
 * 
 */ 
public class ICICIBank implements Bank { 
 
	@Override 
	public void bankName() { 
		System.out.println("ICICI Bank Ltd."); 
	} 
 
} 
 
</pre>
<p><strong>YesBank.java</strong></p>
<pre class="highlight">/** 
 * 
 */ 
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."); 
	} 
 
} 
 
</pre>
<h3>Step 3: Create an interface for Account.</h3>
<p><strong>Account.java</strong></p>
<pre class="highlight">/** 
 * 
 */ 
package com.doj.patterns.creational.abstractfactory; 
 
/** 
 * @author Dinesh.Rajput 
 * 
 */ 
public interface Account { 
	void accountType(); 
} 
 
</pre>
<h3>Step 4: Create concrete classes implementing the same Account interface.</h3>
<p><strong>SavingAccount .java</strong></p>
<pre class="highlight">/** 
 * 
 */ 
package com.doj.patterns.creational.abstractfactory; 
 
/** 
 * @author Dinesh.Rajput 
 * 
 */ 
public class SavingAccount implements Account { 
 
	@Override 
	public void accountType() { 
		System.out.println("SAVING ACCOUNT"); 
	} 
 
} 
 
</pre>
<p><strong>CurrentAccount.java</strong></p>
<pre class="highlight">/** 
 * 
 */ 
package com.doj.patterns.creational.abstractfactory; 
 
/** 
 * @author Dinesh.Rajput 
 * 
 */ 
public class CurrentAccount implements Account { 
 
	@Override 
	public void accountType() { 
		System.out.println("CURRENT ACCOUNT"); 
	} 
 
} 
 
</pre>
<h3>Step 5: Create an Abstract class to get factories for Account and Bank Objects.</h3>
<p><strong>AbstractFactory.java</strong></p>
<pre class="highlight">/** 
 * 
 */ 
package com.doj.patterns.creational.abstractfactory; 
 
/** 
 * @author Dinesh.Rajput 
 * 
 */ 
public abstract class AbstractFactory { 
	abstract Bank getBank(String bankName); 
	abstract Account getAccount(String accountType); 
} 
 
</pre>
<h3>Step 6 : Create Factory classes extending AbstractFactory to generate object of concrete class based on given information.</h3>
<p><strong>BankFactory.java</strong></p>
<pre class="highlight">/** 
 * 
 */ 
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; 
	} 
 
} 
 
</pre>
<p><strong>AccountFactory.java</strong></p>
<pre class="highlight">/** 
 * 
 */ 
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; 
 } 
 
} 
 
</pre>
<h3>Step 7: Create a Factory Producer class to get factories by passing an information such as Bank or Account.</h3>
<p><strong>FactoryProducer.java</strong></p>
<pre class="highlight">/** 
 * 
 */ 
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; 
	} 
} 
 
</pre>
<h3>Step 8 : Let&#8217;s use the <em>FactoryProducer</em> to get <em>AbstractFactory</em> in order to get factories of concrete classes by passing an information such as type.</h3>
<p><strong>AbstractFactoryPatternMain.java</strong></p>
<pre class="highlight">/** 
 * 
 */ 
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(); 
 
	} 
 
} 
 
</pre>
<h3>Step 9: Let&#8217;s run above demo class and vrify the output.</h3>
<pre class="highlight">SAVING ACCOUNT 
CURRENT ACCOUNT 
 
</pre>
<div class="wp-post-navigation"> 
									 <div class="wp-post-navigation-pre"> 
									 <a href="https://dineshonjava.com/service-to-worker/">Previous</a> 
									 </div> 
									 <div class="wp-post-navigation-next"> 
									 <a href="https://dineshonjava.com/factory-method-design-pattern/">Next</a> 
									 </div> 
									</div>
<script type="text/javascript">
jQuery(document).ready(function($) {
 $.post('https://dineshonjava.com/wp-admin/admin-ajax.php', {action: 'mts_view_count', id: '3649'});
});
</script>
Strategy Design Patterns We can easily create a strategy design pattern using lambda. To implement…
Decorator Pattern A decorator pattern allows a user to add new functionality to an existing…
Delegating pattern In software engineering, the delegation pattern is an object-oriented design pattern that allows…
Technology has emerged a lot in the last decade, and now we have artificial intelligence;…
Managing a database is becoming increasingly complex now due to the vast amount of data…
Overview In this article, we will explore Spring Scheduler how we could use it by…