Abstract Design Pattern in Java Example
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 theAccount
. 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 enumyou 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 SavingAccount
and 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.
So with 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)- SavingAccount
- CurrentAccount
-
Loan
(in package loan)- LoanAccount
- HomeLoanAccount
- VehicleLoanAccount
- PersonalLoanAccount
- LoanAccount
-
Deposit
(in package deposit)- DepositAccount
- FixedDepositAccount
- RecurringDepositAccount
- DepositAccount
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 AbstractAccountFactory
:
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 AbstractAccountFactory
.
Next I created LoanAccountFactory
for the AccountType
HOME_LOAN
, VEHICLE_LOAN
, and PERSONAL_LOAN
and placed under that package loan.
And I created DepositAccountFactory
for AccountType
FIXED_DEPOSIT
and 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
Factory (object-oriented programming) Java (programming language) Abstract factory pattern
Opinions expressed by DZone contributors are their own.
Source: https://dzone.com/articles/abstract-factory-pattern-in-java
0 Response to "Abstract Design Pattern in Java Example"
Postar um comentário