A Guide to Software Design Patterns

Structural Design Pattern: Facade

Petey
Petey
Mar 26 · 5 min read
Photo by Justin Lawrence on Unsplash

The word facade borrowed from the French language (façade) and translates to “face” or “front of”. It’s commonly used to refer to a building structure. For instance, the facade of a building. You don’t get much information about a building just by looking at its facade.

A facade design pattern is an object that plays the role of a front-facing interface that hides the more complex underlying structure of some code. This pattern should be used when complex functionalities need to be hidden behind a single and simplified interface or as a launching point for a tightly-coupled system.

What!!! Do people actually choose to build tightly-coupled systems? Yes, they do. Sometimes, it might be necessary for very specific business cases. Most developers at some point in their career has worked or will work on some monolithic application.

The implementation of this pattern is usually a single wrapper class containing a set of functionalities required by the client. I find it way easier to grasp new concepts using real-world scenarios.

Let’s take an Automated Teller Machine ( a.k.a ATM) for instance. All that is required from you is to insert your card and a PIN. Once you’re in, your screen is a simple interface with only the essential options such as:

  1. fast cash (get money by skipping the menu with pre-selected amounts)
  2. withdrawal
  3. deposit (cash or check)
  4. balance inquiry
  5. transfer

The interface might be different in terms of additional options depending on your bank, but these options will be present in most ATMs. As a customer, you don’t care what goes behind the scene to make each one of the options possible, you just care about using them and expect them to work. Those ATMs are a facade to specific banks or third parties. This facade makes it easy for customers to access extremely complex functionality simply and intuitively.

If we were to take a look at the requirements for an ATM, it might look like this.

  • The software to be designed will control a simulated automated teller machine (ATM) having a magnetic stripe reader for reading an ATM card, a keyboard, and display for interaction with the customer, a slot for depositing envelopes, a dispenser for cash (in multiples of $20 or $50), a printer for printing customer receipts, and a key-operated switch to allow an operator to start or stop the machine. The ATM will communicate with the bank’s computer over an appropriate communication link. (The software on the latter is not part of the requirements for this problem.)
  • The ATM will service one customer at a time. A customer will be required to insert an ATM card and enter a personal identification number (PIN) — both of which will be sent to the bank for validation as part of each transaction. The customer will then be able to perform one or more transactions. The card will be retained in the machine until the customer indicates that he/she desires no further transactions, at which point it will be returned — except as noted below.

The ATM must be able to provide the following services to the customer:

  1. A customer must be able to make a cash withdrawal from any suitable account linked to the card, in multiples of $20.00 or $50.00. Approval must be obtained from the bank before cash is dispensed.
  2. A customer must be able to deposit to any account linked to the card, consisting of cash and/or checks in an envelope. The customer will enter the amount of the deposit into the ATM, subject to manual verification when the envelope is removed from the machine by an operator. Approval must be obtained from the bank before physically accepting the envelope.
  3. A customer must be able to make a transfer of money between any two accounts linked to the card.
  4. A customer must be able to make a balance inquiry of any account linked to the card.

All these requirements are hidden from the customer. Once a customer is authenticated, the facade looks like this.

To implement this, we’d need six complex objects. One to validate the user information, which essentially reads the magnetic strip from the card with the pin and run some validation complex logic, and one for each selection in the above interface. For brevity, this example won’t perform any actual operations, but rather just print out messages for each method call exposed by our system facade.

Let’s see what that looks like in code.

public class AutomatedTellMachine {
boolean validateUser(String cardNumber, String pin){
//call to complex validation logic goes here...
System.out.println("performing validation operation...");
System.out.println("validation is success...");
return true;
}
boolean getCash(String accountNumber, double preSelectedAmount){
//call to complex fast cash logic goes here...
System.out.println("running sufficient fund logic...");
System.out.println(String.format("dispensing $%.2f", preSelectedAmount));
return true;
}
boolean withdraw(String accountNumber, double amount){
//call to complex withdrawal logic goes here...
System.out.println("running sufficient fund logic...");
System.out.println(String.format("dispensing $%.2f", amount));
return true;
}
void displayBalance(String accountNumber){
//call to complex balance inquiry logic goes here...
System.out.println("retrieving balance...");
System.out.println("Balance : $23,500,500");
}
void deposit(String accountNumber, String type, double amount){
//call to complex deposit logic goes here...
System.out.println("validating amount...");
System.out.println(String.format("depositing $%.2f of type %s", amount, type));
}
boolean transfer(String accountNumberFrom, String accountNumberTo, double amount){
//call to complex transfer logic goes here...
System.out.println("running sufficient fund logic...");
System.out.println(String.format("transferring $%.2f from %s to %s",
amount, accountNumberFrom, accountNumberTo));
return true;
}
}

We can then use this object to access all these complicated features without having any knowledge of the underlying complexities that go behind the scene to make it all work.

public static void main(String[] args) {
AutomatedTellMachine atm = new AutomatedTellMachine();
//inserting card and pin number
boolean isValid = atm.validateUser("1234", "4321");
if(isValid){
//checking balance with one of the account # retrieved from User object
atm.displayBalance("A");
//transferring X from account A to B
atm.transfer("A", "B", 5000d);
//depositing a check of $50,000 into account B
atm.deposit("B", "Check", 50000d);
//withdraw $10,000 from account A
atm.withdraw("A", 10000d);
}else{
System.out.println("You've entered a damaged card or invalid pin...");
}
}

Output

performing validation operation...
validation is success...
retrieving balance...
Balance : $23,500,500
running sufficient fund logic...
transferring $5000.00 from A to B
validating amount...
depositing $50000.00 of type Check
running sufficient fund logic...
dispensing $10000.00

This is, in a nutshell, the facade pattern. Thank you for making it to the end. Happy coding.

Previous: Behavioral Design Pattern: Strategy

Next: Structural Design Pattern: Decorator

The Startup

Medium's largest active publication, followed by +611K people. Follow to join our community.

Petey

Written by

Petey

Husband, father, engineer, musician, and writer by luck. I write mostly about whatever comes to mind. Follow me on this crazy writing journey if you dare.

The Startup

Medium's largest active publication, followed by +611K people. Follow to join our community.

More From Medium

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade