Structural Design Pattern: 1. Facade Pattern

What is a structural design pattern?

Structural design pattern eases the design by identifying a simpler way to realize the relationships between entities or defines a manner for creating relationships between objects.

According to GOF, a façade is basically a wrapper class that encapsulates a subsystem in order to hide the subsystem’s complexity and it acts as a point of entry into a subsystem without adding more functionality in itself. The wrapper class allows a client class to interact with the subsystem through the façade.

How to design this pattern?

  1. Design the interface.
  2. Implement the interface with one or more classes.
  3. Create the façade class and wrap the classes that implement the interface.
  4. Use the façade class to access the subsystem.

Let’s see an example to understand better.

Suppose there is a bank and you want to open an account in that bank. As a customer, you just tell them whether you want to open a saving account or an investment account and give them an initial amount that you want to deposit. The bank opens the account for you, deposit the money and in return gives you an account number. The next time, you want to do any transaction in or through your account, you can use the same account number and can easily do it.

So, here bank is providing you an abstraction on the account creation part as well as the services it is providing you so that your interaction is as simple as possible and it hides the internal complexity of the banking service from the end-user. This is exactly what we call a facade. The client is interacting with a facade which is a simplified interface for the entire subsystem.

Therefore, a facade is a point of entry in a subsystem but it does not add any additional functionality to the system.

Image is taken from the internet

In the above example, the client for a banking service is a customer. Then there is an interface that is Account and it can have multiple implementations like Chequing account, saving account, and investment account. Whenever the customer wants any kind of service from the bank, it will directly interact with the banking service, and the banking service will then interact with the desired subsystems and respond to the customer’s query. So, here banking service is acting as a facade layer which is encapsulating and abstracting the services provided by the bank.

Let’s go through these individual pieces one by one.

  1. Interface, IAccount. The account can have multiple functionalities like getting an account number, withdrawing some money, transferring money to another account, and adding money to an account.
public interface IAccount {
public void deposit(BigDecimal amount);
public void withdraw(BigDecimal amount);
public void transfer(int accountNo, BigDecimal amount);
public int getAccountNumber();
}

2. Now, there are many types of accounts, which will implement the IAccount interface, let’s see one of them.

public class Saving implements IAccount { @Override
public int getAccountNumber(){
//have some logic for generating a saving account number and return it
}
...@Override
public void transfer(int accountNo, BigDecimal amount){
//logic for transferring amount
}

3. Facade, BankingService

public class BankService {
private Hashtable<int, IAccount> bankAccounts;
public BankService() {
this.bankAccounts = new Hashtable<int,IAccount>();
}
public int createNewAccount(String type, BigDecimal initAmount) {
IAccount newAccount = null;
switch (type) {
case "chequing": newAccount = new Chequing(initAmount);
break;
case "saving": newAccount = new Saving(initAmount);
break;
case "investment": newAccount = new Investment(initAmount);
break;
default: System.out.println("Invalid account type");
break;
} if (newAccount != null) {
this.bankAccounts.put(newAccount.getAc countNumber(), newAccount);
return newAccount.getAccountNumber();
}
return -1;
}
public void transferMoney(int to, int from, BigDecimal amount) {
IAccount toAccount = this.bankAccounts.get(to);
IAccount fromAccount = this.bankAccounts.get(from);
fromAccount.transfer(toAccount, amount);
} }

4. Client/ Customer

public class Customer {
public static void main(String args[]) {
BankService myBankService = new BankService();
int mySaving = myBankService.createNewAccount("saving", new BigDecimal(500.00));
int myInvestment = myBankService.createNewAccount("investment", new BigDecimal(1000.00));
myBankService.transferMoney(mySaving, myInvestment, new BigDecimal(300.00));
}
}

Here, it is also worth noticing that all the Account details are private in the BankingService so the client can’t access them. This also ensures data safety through information hiding. Along with that, the facade is also handling the instantiation and redirection of tasks to the appropriate class within the subsystem.

That’s all for the facade pattern. Now, you might be appreciating the power of this pattern and it is widely used in the industry and it’s good to know about it. You may refer to the book, Gang of Four’s design pattern catalog for more understanding.

Please let me know in the comments below if you have any doubts. If you like this blog, please clap and share it with your friends. Happy software engineering!

Note: Part 2 of structural pattern: https://jhanakd26.medium.com/structural-design-pattern-2-adapter-pattern-20946ff85120

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store