Moe's Tech Blog
[Design Pattern] Facade Pattern 본문
Motivation
- As system gets larger, code gets more and more complex
- This can get confusing for the client classes in your system to use
- System complexity is not always a sign of poor design
- The scope of problem you are trying to solve is so large it requires a complex solution
- But client classes prefer a simplier, and easy to use interaction
- Example
- 1. Consider a large home
- has many subsystems (electrical, sanitation)
- has complex internal structures (e.g. floor layers)
- but end user is NOT exposed to internals
- consumers want it to 'just work'
- 2. Shopping Online
- has outward indication that the store you're on has a virtual storefront
- The outward indicators are used to communicate what types of services are available
- when an online sales platform sends your order to be fulfilled, works as part of a facade by hiding away all the extra work that needs to be done
- can fulfill goods and services without having to know how the request is processed
- has outward indication that the store you're on has a virtual storefront
- 1. Consider a large home
Facade Design Pattern
- Does not add more complexity
- Simply acts as a point of entry into your subsystem
- Is designed to hide all the complexities in the code
- Is a wrapper class that encapsulates a subsystem in order to hide subsystem's complexity
- Provides a simple, easy to understand / user interface over a large and sophisticated body of code
- Does exactly what a waiter or salesperson would do in real life
Example
- 1. Banking System
- Without Facade, the customer class would contain instances of
- a. Checking class
- b. Saving class
- c. Investment class
- This means that the user is responsible for properly instantiating each of the constituent classes and know all about their different attributes and methods
- After applying facade, it would look something like the following:
- BankService is introduced as a facade
- The customer no longer needs to handle instantiation and complexities of financial management
- Since the three different accounts all implement the IAccount interface, the bank's service class is effectively wrapping the account interfacing classes, and presenting a simpler front the customer clinet class to use
- Without Facade, the customer class would contain instances of
How to Apply Facade Design Pattern
- Step 1. Design the interface
- Step 2: Implement the interface with one or more classes
- interface allows us to create subtypes which means that Checking, Saving, Investment classes are subtypes of IAccount, and are expected to behave like an IAccount Type
- A Facade class can be used to wrap all the interfaces and classes for a subsystem
- It's your decision to know what you want to wrap
- Step 3: Create the Facade class and wrap the classes that implement the interface
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.getAccountNumber(), 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);
}
}
- Step 4: Use the Facade class to access the subsystem
- Now that we have facade in place, client class can access its accounts through the BankService
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));
}
}
Summary
- Facade design pattern
- Is a mean to hide the complexity of a subsystem by encapsulating it behind a unifying wrapper called a facade class
- Removes the need for client classes to manage a subsystem on their own, resulting in less coupling between the subsystem and the client classes
- Handles instantiation and redirection of tasks to the appropriate class within the subsystem
- Provides client classes with a simplified interface for the subsystem.
- Acts simply as a point of entry to a subsystem and does not add more functionality to the subsystem
FAQs
- 1. What is the difference between abstract factory design pattern and facade design pattern?
- The Facade design pattern is used when you want to hide an implementation
- The abstract factory pattern is used when you want to hide the details on constructing instances
References
- 1. Object-Oriented Design, University of Alberta: https://www.coursera.org/learn/object-oriented-design
- 2.Design Patterns in Python, Dmitri Nesteruk: https://www.udemy.com/course/design-patterns-python/
- 3. What are the differences between facade pattern and abstract factory pattern?, Stack Overflow: https://stackoverflow.com/questions/11188869/what-are-the-differences-between-facade-pattern-and-abstract-factory-pattern
'Software Design Pattern > Notes' 카테고리의 다른 글
[Design Pattern] Composite Pattern (0) | 2022.08.15 |
---|---|
[Design Pattern] Adapter Pattern (0) | 2022.08.15 |
[Design Pattern] Factory Pattern (0) | 2022.07.25 |
[OO Design Foundation] Object Oriented Modeling 2 (0) | 2022.07.13 |
[Design Pattern] Mediator Pattern (0) | 2022.07.02 |