Structural - Facade Pattern

This pattern helps to hide the system's complexity from the client

Imagine you want to get some money from an ATM machine. The ATM is like magic for you—when you put your card in and ask for money, the ATM gives it to you! You don’t need to know anything about how it checks the balance, how it updates the amount left, or any of the secret steps inside the machine.

In real life, there are many things happening inside the ATM:

  • The ATM checks if you have enough money.

  • It updates how much you have after taking some out.

  • It gives you only the amount you can actually withdraw.

But, we just use the ATM’s simple buttons. The ATM hides all the complicated stuff inside—that’s what we call facade.

Facade pattern is like the ATM machine—the easy part at the front. It lets you do what you want (like withdrawing money) without seeing or worrying about how all the little steps happen inside!

Low Level Design

facade pattern

Implementation

Let's build ATM withdrawal process

public class AccountDao {

	private static long balance = 1000L;

	private boolean isBalanceAvailable(long amount) {
		long balance = fetchBalance();
		if (balance >= amount) {
			return true;
		}
		return false;
	}

	private long fetchBalance() {
		return balance;
	}

	public long withdraw(long amount) { // only this method available for call
		if (isBalanceAvailable(amount)) { // first check balance
			updateBalance(amount); // update the balance
			return amount; // withdraw
		}
		return 0;
	}

	private void updateBalance(long amount) {
		balance = balance - amount;
	}

}
public class ATMFacade {
	private AccountDao accountDao = new AccountDao();

	public long withdraw(long amount) {
		return accountDao.withdraw(amount);
	}
}
public class Client {
	public static void main(String[] args) {
		ATMFacade atm = new ATMFacade();

		long cash1 = atm.withdraw(900);
		System.out.println("Amount withdrawn : " + cash1); // 900

		long cash2 = atm.withdraw(200);
		System.out.println("Amount withdrawn : " + cash2); // 0

		long cash3 = atm.withdraw(100);
		System.out.println("Amount withdrawn : " + cash3); // 100
	}
}

Next time, you go to ATM, remember this ATM Facade 😄

A classic example of the Facade pattern from the JDK is the JDBC DriverManager class. When you need to connect to a database, instead of dealing with the many complicated details of drivers, connection protocols, and so on, you just call methods on DriverManager (like getConnection). The DriverManager acts as a simple, unified interface (facade) for all the underlying database connection mechanisms, hiding all the complexity from you as the client.

Advantages of the Facade Pattern:

  • Simplifies complex systems: It provides a simple interface for complicated subsystems, making it easy for users to interact with them.

  • Reduces dependencies: Clients don’t need to know details about the subsystems, so changes inside are less likely to affect outside code.

  • Promotes loose coupling: By exposing only what's necessary, facade helps keep code modules separate and independent.

  • Improves readability: Code becomes cleaner and easier to use, since you work with a simple interface rather than lots of complex parts.

Disadvantages of the Facade Pattern:

  • May hide important features: Some advanced functionality of the subsystems might not be accessible through the facade, making it less flexible for power users.

  • Extra layer: Introducing a facade adds another layer in your design. If misused, this can make the system harder to follow and debug.

  • Potential for misuse: If the facade grows too much, it might become a "god object" that tries to do too much, violating separation of concerns.

Last updated

Was this helpful?