Abstract Factory Pattern In Java
Join the DZone community and get the full member experience.Join For Free
In the continuation of my previous article (Strategy vs. Factory Design Patterns in Java), I am here with an article on Abstract Factory Pattern. In this article, I will try to highlight the usage of the pattern along with the difference with the Factory Pattern.
Abstract Factory Pattern
- The abstract factory pattern is a creational pattern which provides a way to encapsulate a group of individual factories that have a common purpose or theme; without specifying their concrete classes.
- The Abstract Factory patterns work around a super-factory which creates other factories.
- This super-factory is also known as a factory of factories.
- The Abstract Factory pattern 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.
- So in short, Abstract factory provides an interface to create different concrete factories. Each such factory works with a family or group objects. and hence Abstract factory provides a way to work with multiple such factories. So, we can also call it as factory of factories.
As we can see in the above class diagram, there is a car factory which is in business for ages. So it has an old car factory called ClassicCarFactory. Later, the company started manufacturing some new modern cars and hence started another factory called ModernCarFactory. So, for the that, we used AbtractCarFactory as Abstract Factory Design Pattern. In that way, we will make sure to have no or minimum changes on the client end.
Suppose by the success in the modern cars, the company decided to also start manufacturing the sports cars and started another factory for that, the design will be as below by using the same pattern.
So, the Abstract Factory design pattern solves problems like:
- How can an application be independent of how its objects are created?
- How can a class be independent of how the objects it requires are created?
- How can families of related or dependent objects be created?
To make it easy to understand and to highlight similarities and differences with Factory Pattern, I am using the same example of Account Management what I took in the article Strategy vs. Factory Design Patterns in Java.
In the example, I only did some re-structuring/packaging to make code more cleaner and easy to understand. May be its not best example to list here. But my intention is to show the implementation and use of the Abstract Factory and not any other accounting system. So, please excuse if it does not look good to you.
Account-Management Example Using the Abstract Factory Pattern
We have the
AccountType interface to define account-types with the pre-defined or fixed rate of interest. Here, I have added more account types to make use or more Factory Classes.
I am implementing an abstract base class for the account and creating the various flavors of
Account by sub-classing it.
Below is the code for the
Account. Please note that I have defined the class as
abstract to force the sub-classing of it.
In this example, since the we are gonna create many sub-types of
Account class, I am writing a new enum
InterestStrategy to provide interest calculation algorithms.
Now, we have to create the types for the account. I create the
SavingAccount, which is tied up with the compound interest algorithm.
You can compare the above code of SavingAccount with the code in the article Strategy vs. Factory Design Patterns in Java to understand the use of enum. And to understand the code written inside of enum you may refer to my article Java Enums: How to Make Enums More Useful.
Next, I created the
CurrentAccount, which is tied up with the simple-interest algorithm.
So, basically, the types of accounts not only have pre-defined rates (as in the strategy) but also the pre-defined interest calculation algorithms, which are tightly coupled. Therefore, the account instance will have defined functionality.
Because the above two accounts
CurrentAccount are type of saving, I put them into a sub-package called saving. This is something I did just to organize the code and there is no relation of this with the design pattern I am discussing here.
Now, I will write more concrete sub-classes of
Account to represent each of the
AccountType we have created.
Below is the code of
LoanAccount , which is an abstract class and a sub-type of Account. I made it abstract just to have different flavors of loan-types like Home Loan, Vehicle Loan or Personal Loan.
LoanAccount sub-class, I placed all of the common code I needed to operate any kind of loan account like any loan requires a term to clear. Also, because I like to avoid the much of the coding, I reversed the deposit and withdraw with respect to amount. I mean deposit in loan means clearing the amount and withdraw from loan means a kind of disbursement of the amount to the builder of the home or the vehicle supplier.
To organize the loan related code, I use loan as a sub-package.
Now I created
HomeLoanAccount, which is tied up with the compound-interest algorithm.
Next I created
VehicleLoanAccount, which is tied up with the compound-interest algorithm.
Next I created
PersonalLoanAccount, which is tied up with the compound-interest algorithm.
Similarly for deposit type of account, I use sub-package called deposit to organize the code.
Below is the code of
DepositAccount where I placed all of the common code I needed to operate any kind of deposit account like there is restriction on amount and number of withdraw and deposit.
Next I created
FixedDepositAccount, which is tied up with the simple-interest algorithm.
Next I created
RecurringDepositAccount, which is tied up with the compound-interest algorithm.
So now we are ready with all the flavors of account we are gonna support in the application.
As we have noticed that we have 3 categories of
Account sub-types as below:
Saving(in package saving)
Loan(in package loan)
Deposit(in package deposit)
Now, its time to do Step 1 to implement Abstract Factory for the design pattern we are discussing. We can create AbstractFactory as interface (to server multiple inheritence in java) or as abstract class. Both approach are OK.
Step 1: Here I am creating it as abstract class
Please note that the abstract method inside factory class returns the highest-level of the account class/interface to show that all the concrete implementation of factory will have a same purpose or theme. Here, I also changed multiple parameters to a single POJO class called
AccountOpendingDetails. This is to avoid lengthy parameter list as well as validating parameter values
You can see that the
AccountOpeningDetails deals with the same parameters as fields and provides the validation on that as well. This is just for simplicity of the code.
Step 2: Now, let's take a look at the most important step. We have to define the factory class (
AccountFactory) for the
Account based on the given saving account-type i.e SAVING and CURRENT. I am placing the class into the same package of the class which the factory deals with i.e. saving; again just for organizing the code.
Please note that the
AccountFactory is now a sub-type/implementation of the
Next I created
LoanAccountFactory for the
PERSONAL_LOAN and placed under that package loan.
And I created
RECURRING_DEPOSIT and placed under the package deposit.
So, we have three concrete implementation of factories as below:
AccountFactory- for SAVING family of Account classes.
LoanAccountFactory- for LOAN family of Account classes.
DepositAccountFactory- for DEPOSIT family of Account classes.
Now, we need a provider or producer class which will give us the factory class depending upon our category or family selection. So, here is the code of
AccountFactoryProvider to do that:
That's it. Its time to write a
Main program to execute the code and test the output:
And here the the output of the program:
I hope this tutorial helped demonstrate the business context and technical implementation of the Abstract Factory Pattern.
Source Code can be found here: Abstract-Factory-Design-Pattern-Sample-Code
Liked the article? Please don't forget to press that like button. Happy coding!
Need more articles, please visit my profile: Brijesh Saxena
Opinions expressed by DZone contributors are their own.