opencodez

Java Creational Design Patterns – Abstract Factory Pattern

The Abstract Factory Pattern is one of the creational design patterns. We can say Abstract Factory patterns acts as a super-factory which produces other factories. The role of the Abstract Factory is to provide an interface for creating families of related or dependent objects without specifying their concrete classes.

If we are using an abstract factory pattern, then the client program will never create platform objects directly, they ask the factory to perform this task for them. So the factory object has the total responsibility for proving this service for the entire platform family. You can use this pattern if-

xHere are ALL Java Design Patterns, explained in detail with examplesx

Abstract Factory Pattern by Example

For our understanding of this pattern, we will take a simple example of different types of Bank Accounts. When you are dealing with Bank, for every type of your need there is an account created to track the books.  We will try to apply this pattern on account types like Savings, Current, HomeLoan etc.

To start we will define our core interface, which has a single method to show us the interest rate of that account type.

public interface Account {
	public void getInterestRate();
}

Now, we will define a few concrete classes, that will implement the above interface.

SavingsAccount

public class SavingsAccount implements Account {

	@Override
	public void getInterestRate() {
		System.out.println("Savings Account Interest Rate = 4.0% pa");
	}

}

Current Account

public class CurrentAccount implements Account {

	@Override
	public void getInterestRate() {
		System.out.println("Current Account Interest Rate = 5.0% pa");
	}

}

Home Loan Account

public class HomeLoan implements Account {

	@Override
	public void getInterestRate() {
		System.out.println("Home Loan Interest Rate = 8.5% pa");
	}

}

Education Loan Account

public class EducationLoan implements Account {

	@Override
	public void getInterestRate() {
		System.out.println("Education Loan Interest Rate = 11.5% pa");
	}

}

After this, we will define our Abstract Factory abstract class. This class will be extended by different Family Factories such as Account Factory or Loan Factory.

public abstract class AbstractFactory {
	abstract Account getAccount(String type) ;
}

also below are different factories-

LoanFactory

public class LoanFactory extends AbstractFactory {

	@Override
	Account getAccount(String type) {

		Account account = null;

		if ("Home".equalsIgnoreCase(type)) {
			account = new HomeLoan();
		} else if ("Education".equalsIgnoreCase(type)) {
			account = new EducationLoan();
		}

		return account;
	}

}

AccountFactory

public class AccountFactory extends AbstractFactory {

	@Override
	Account getAccount(String type) {

		Account account = null;

		if ("Savings".equalsIgnoreCase(type)) {
			account = new SavingsAccount();
		} else if ("Current".equalsIgnoreCase(type)) {
			account = new CurrentAccount();
		}

		return account;
	}

}

Last but not least we will add a Factory Provider, which is kind of a wrapper or super factory.

public class FactoryProvider {
	public static AbstractFactory getFactory(String choice) {
		AbstractFactory af = null;
		if ("Loan".equalsIgnoreCase(choice)) {
			af = new LoanFactory();
		} else if ("Account".equalsIgnoreCase(choice)) {
			af = new AccountFactory();
		}
		return af;
	}
}

Running the Example

public class AbstractFactoryDemo {

	public static void main(String[] args) {

		AbstractFactory lf = FactoryProvider.getFactory("Loan");

		Account loan1 = lf.getAccount("Home");
		loan1.getInterestRate();

		Account loan2 = lf.getAccount("Education");
		loan2.getInterestRate();

		AbstractFactory af = FactoryProvider.getFactory("Account");

		Account account1 = af.getAccount("Savings");
		account1.getInterestRate();

		Account account2 = af.getAccount("Current");
		account2.getInterestRate();

	}

}

Output:

Home Loan Interest Rate = 8.5% pa
Education Loan Interest Rate = 11.5% pa
Savings Account Interest Rate = 4.0% pa
Current Account Interest Rate = 5.0% pa

Conclusion

In this article, we understood the Abstract Factory Pattern with the help of a simple example. While the pattern is great when creating predefined objects and providing abstraction, a new addition of object family might be difficult. To support the new type of objects will require changing the AbstractFactory class and all of its subclasses.

The source code is available in our Github repository.

Download Code

xHere are ALL Java Design Patterns, explained in detail with examplesx