1. What is the Factory Design Pattern?
Before delving into the concept of the Factory Design Pattern in Java, let’s take a look at this practical example. The emergence of fintech has been a powerful aid in developing systems related to Finance, Insurance, and Banking. I also have a few years of experience in Banking, so I will use a Banking service as an example.
Most banks will support four types of accounts as follows:
- Checking Account
- Savings Account
- Money Market Account
- Certificate of Deposit
The challenge is to find a suitable solution to create these types of Banking Accounts. The Factory Design Pattern is a promising candidate because its purpose is to manage the creation of objects as required.
2. Factory Design Pattern Diagram
Now let’s explore the ways to implement the Factory design pattern together. From the class diagram, coders can easily see that the implementation for Factory is extremely straightforward. AccountFactory takes an AccountType as input and returns a specific BankAccount as output.
3. Factory Design Pattern Implementation
Based on the diagram above, let’s go through the implementation of this design pattern together.
First, we create a BankAccount, which is an abstract class that will contain information commonly used for specific Accounts.
public abstract class BankAccount{
protected String bankName;
protected String accountNumber;
protected BigDecimal balance;
protected abstract String withDraw();
protected abstract String deposit();
}
CheckingAccount is a class that extends BankAccount. This class is responsible for implementing specific business logic for Checking accounts.
public class CheckingAccount extends BankAccount{
@Override
protected String withDraw(){
return “Checking account withdraws”;
}
@Override
protected String deposit(){
return “Checking account deposits”;
}
}
SavingAccount is a class that extends BankAccount. This class is responsible for implementing specific business logic for Saving accounts.
public class SavingsAccount extends BankAccount{
@Override
protected String withDraw(){
return “Saving account withdraws”;
}
@Override
protected String deposit(){
return “Saving account deposits”;
}
}
MoneyMarketAccount is a class that extends BankAccount. This class is responsible for implementing specific business logic for MoneyMarket accounts.
public class MoneyMarketAccount extends BankAccount{
@Override
protected String withDraw(){
return “MoneyMarket account withdraws”;
}
@Override
protected String deposit(){
return “MoneyMarket account deposits”;
}
}
CertificateDepositAccount is a class that extends BankAccount. This class is responsible for implementing specific business logic for Certificate Deposit accounts.
public class CertificateDepositAccount extends BankAccount{
@Override
protected String withDraw(){
return “CertificateDeposit account withdraws”;
}
@Override
protected String deposit(){
return “CertificateDeposit account deposits”;
}}
AccountType consists of fixed values that have been predefined in the banking industry domain; therefore, it is a constant, and we use Enum for this data type to ensure integrity.
public enum AccountType{
CHECKING,
SAVINGS,
MONEY,
CERTIFICATE
}
AccountFactory is a class that implements the Factory design pattern. It uses the accountType to create the corresponding type of BankAccount.
public class AccountFactory{
public BankAccount createAccount(AccountType accountType){
switch(accountType) {
case CHECKING:
return new CheckingAccount();
case SAVINGS:
return new SavingsAccount();
case MONEY:
return new MoneyMarketAccount();
case CERTIFICATE:
return new CertificateDepositAccount();
default:
throw new IllegalArgumentException(“Error”));
}
}
}
Below is how to use AccountFactory to create a CheckingAccount.
public class Execution{
public static void main(String[] args){
AccountFactory accountFactory = new AccountFactory();
BankAccount account = accountFactory.createAccount(AccountType.CHECKING);
account.withDraw();
account.deposit();
}
}
4. The Pros and Cons of Factory Design Pattern
The Pros of Factory
The first strength of the Factory pattern that we can see is that it centralizes the creation of objects in one place. This helps developers to easily read and maintain the code.
Secondly, this pattern minimizes the dependency between classes. This facilitates easy scaling. For example, in the future, there might be new types of accounts such as Credit, Debit, etc. At that time, we only need to create additional subclasses that extend BankAccount and add them to the factory method.
Thirdly, it can hide complex logic involved in creating objects.
The Cons of Factory
As you can see, the creation of objects in the method create(AccountType type) depends on the constructor of the sub-classes. Therefore, if the constructor has many parameters, the factory method can become complex.
The number of sub-classes may increase over time. For me, this is not really a drawback of the factory. However, this will lead to the create(AccountType type) method becoming increasingly bloated.
The Conclusion
I would like to conclude the article here. Through this article, I have listed what a Factory Design Pattern is and how to implement a Factory. I hope to receive contributions from everyone so that the programming community can continue to develop, and especially so that future articles can be better.
Related Articles on Design Patterns