Facade Design Pattern in C#

Facade Design Pattern in C#

·

4 min read

The Facade Design Pattern is a structural design pattern that provides a simplified interface to a complex system. It acts as a single entry point to the system and hides the complexity of the underlying components. The Facade Design Pattern is useful when you want to provide a simple interface to a complex system, or when you want to decouple the client from the implementation details of the system.

When to use the Facade Design Pattern

The Facade Design Pattern should be used when:

  • You want to provide a simple interface to a complex system

  • You want to decouple the client from the implementation details of the system

  • You want to improve the readability and maintainability of the code

Example of the Facade Design Pattern

Let's consider an example of a computer system that has multiple components such as the CPU, memory, and hard drive. The computer system has a simple interface that allows the user to turn the system on and off, but the underlying components have complex interfaces that are not accessible to the user.

To implement the Facade Design Pattern, we can create a Computer class that has a simple interface that allows the user to turn the system on and off. The Computer class will have a reference to the CPU, Memory, and HardDrive classes, which represent the underlying components of the system.

class CPU {
  void start() {
    // implementation details
  }

  void shutdown() {
    // implementation details
  }
}

class Memory {
  void load(long position, byte[] data) {
    // implementation details
  }
}

class HardDrive {
  byte[] read(long lba, int size) {
    // implementation details
  }
}

class Computer {
  private CPU cpu;
  private Memory memory;
  private HardDrive hardDrive;

  Computer() {
    this.cpu = new CPU();
    this.memory = new Memory();
    this.hardDrive = new HardDrive();
  }

  void startComputer() {
    cpu.start();
    memory.load(BOOT_ADDRESS, hardDrive.read(BOOT_SECTOR, SECTOR_SIZE));
    cpu.jump(BOOT_ADDRESS);
    cpu.execute();
  }

  void shutDownComputer() {
    cpu.shutdown();
  }
}

With the above implementation, the user can turn the computer on and off using the simple startComputer and shutDownComputer methods, without having to worry about the complexity of the underlying components.

Real-World Example: ATM machine

One real-world example of the Facade Design Pattern is the use of an ATM machine. An ATM machine provides a simple interface for users to perform financial transactions, such as withdrawing cash or checking their account balance. However, behind the scenes, the ATM machine is connected to a complex system that includes the bank's database, security protocols, and network infrastructure.

To implement the Facade Design Pattern in this scenario, we can create a Bank class that acts as the facade. The Bank class has a simple interface that allows the user to perform transactions, such as withdrawing cash or checking their account balance. The Bank class also has references to the underlying components, such as the Security class, which handles security protocols, and the Database class, which handles access to the bank's database.

class Security {
  boolean checkPin(String pin) {
    // implementation details
  }
}

class Database {
  Account getAccount(String accountNumber) {
    // implementation details
  }

  void updateAccount(Account account) {
    // implementation details
  }
}

class Bank {
  private Security security;
  private Database database;

  Bank() {
    this.security = new Security();
    this.database = new Database();
  }

  boolean withdrawCash(String accountNumber, String pin, double amount) {
    Account account = database.getAccount(accountNumber);
    if (security.checkPin(pin) && account.getBalance() >= amount) {
      account.setBalance(account.getBalance() - amount);
      database.updateAccount(account);
      return true;
    }
    return false;
  }

  double checkBalance(String accountNumber, String pin) {
    Account account = database.getAccount(accountNumber);
    if (security.checkPin(pin)) {
      return account.getBalance();
    }
    return -1;
  }
}

With the above implementation, the user can perform transactions using the simple withdrawCash and checkBalance methods, without having to worry about the complexity of the underlying components. The Facade Design Pattern in this example decouples the user from the implementation details of the system and provides a simple interface for performing financial transactions.

Advantages

  • It provides a simple interface to a complex system

  • It decouples the client from the implementation details of the system

  • It improves the readability and maintainability of the code

Disadvantages

  • It can make the system more inflexible, as the client is not aware of the implementation details of the underlying components

  • It can increase the overall size of the code, as it requires the creation of an additional layer of abstraction

Conclusion

In conclusion, the Facade Design Pattern is a useful tool for providing a simple interface to a complex system and decoupling the client from the implementation details of the system. It can improve the readability and maintainability of the code, but it can also make the system more inflexible