Factory
Design Pattern in Java
Intent
Define an
interface for creating an object, but let subclasses decide which class to
instantiate. Factory Method lets a class defer instantiation to subclasses.
Motivation
Factory
Design pattern is also known as Virtual Constructor, the Factory Method is
related to the idea on which libraries work: a library uses abstract classes for
defining and maintaining relations between objects. One type of responsibility
is creating such objects.
The
library knows when an object needs to be created, but not what kind of object
it should create, this being specific to the application using the library.
The
Factory method works just the same way: it defines an interface for creating an
object, but leaves the choice of its type to the subclasses, creation being
deferred at run-time.
A simple real life example of the Factory
Method is the Bank Account.
A
user wants to open an Account in a bank. A user can open either a Saving Account,
Current Account, Salary Account, Demat
Account based on their requirement.
Depending
on the requirement the subclass object for any of the account type can be
created can be created.
Applicability
Use the
Factory Method pattern when
- A class can't anticipate the class of objects it must create.
- A class wants its subclasses to specify the objects it creates.
- Classes delegate responsibility to one of several helper subclasses, and you want to localize the knowledge of which helper subclass is the delegate.
Consequences
- Factory methods eliminate the need to bind application-specific classes into your code.
- Provides hooks for subclasses. Creating objects inside a class with a factory method is always more flexible than creating an object directly. Factory Method gives subclasses a hook for providing an extended version of an object.
- Connects parallel class hierarchies. Parallel class hierarchies result when a class delegates some of its responsibilities to a separate class.
Implementation
We're
going to create an Account interface and concrete classes implementing the
Account interface.
A
factory class AccountFactory would be responsible for returning object.
FactoryPatternDemo class will use AccountFactory to get an
Account object.
It
will pass information (Saving / Current / Salary / Demat) to AccountFactory to
get the type of object it needs.
Create an Interface Account
public interface Account {
public void
openAccount();
}
|
Create
Classes SavingAccount, SalaryAccount, CurrentAccount, DematAccount which
implements the Account interface.
public class SavingAccount
implements Account{
@Override
public void openAccount()
{
System.out.println("Opening
Savings Account");
}
}
|
public class
CurrentAccount implements Account{
@Override
public void openAccount()
{
System.out.println("Opening
Current Account");
}
}
|
public class SalaryAccount
implements Account{
@Override
public void openAccount()
{
System.out.println("Opening
Salary Account");
}
}
|
public class DematAccount implements Account{
@Override
public void openAccount()
{
System.out.println("Opening
Demat Account");
}
}
|
Create
the AccountFactory Class which returns Objects of the Subclasses.
public class
AccountFactory {
public Account
getAccountType(String accountType){
if(accountType==null){
return null;
}
if(accountType.equalsIgnoreCase("saving")){
return new
SavingAccount();
}
else if(accountType.equalsIgnoreCase("current")){
return new
CurrentAccount();
}
else if(accountType.equalsIgnoreCase("salary")){
return new
SalaryAccount();
}
else if(accountType.equalsIgnoreCase("demat")){
return new
DematAccount();
}
return null;
}
}
|
Create
the FactoryPatternDemo with the main method
public class
FactoryPatternDemo {
public static void main(String[]
args) {
AccountFactory accountFactory=new
AccountFactory();
Account saving=accountFactory.getAccountType("saving");
saving.openAccount();
Account current=accountFactory.getAccountType("current");
current.openAccount();
Account salary=accountFactory.getAccountType("salary");
salary.openAccount();
Account demat=accountFactory.getAccountType("demat");
demat.openAccount();
}
}
|