Facade Pattern

The Facade design pattern is used to provide a simplified interface to a complex system, making it easier for clients to interact with the system.

It acts as a unified front that hides the underlying complexities and provides a more straightforward way for clients to access various functionalities.

Think of it as a simplified front desk in a hotel that handles all guest requests and interacts with different hotel departments on their behalf.

Facade Pattern C++ Example:


Let’s consider following example of the Facade pattern to demonstrate how it simplifies interactions with a complex subsystem.

#include <iostream>

// Subsystem 1: Class representing CPU
class CPU {
public:
    void start() {
        std::cout << "CPU started." << std::endl;
    }

    void execute() {
        std::cout << "CPU executing instructions." << std::endl;
    }

    void stop() {
        std::cout << "CPU stopped." << std::endl;
    }
};

// Subsystem 2: Class representing Memory
class Memory {
public:
    void load() {
        std::cout << "Memory loaded with data." << std::endl;
    }

    void free() {
        std::cout << "Memory freed." << std::endl;
    }
};

// Subsystem 3: Class representing Hard Disk
class HardDisk {
public:
    void read() {
        std::cout << "Reading data from hard disk." << std::endl;
    }

    void write() {
        std::cout << "Writing data to hard disk." << std::endl;
    }
};

// Facade: Simplified interface to the complex subsystem
class ComputerFacade {
public:
    ComputerFacade() : cpu_(), memory_(), hardDisk_() {}

    void startComputer() {
        cpu_.start();
        memory_.load();
        hardDisk_.read();
        std::cout << "Computer started and ready to use." << std::endl;
    }

    void shutDownComputer() {
        cpu_.stop();
        memory_.free();
        hardDisk_.write();
        std::cout << "Computer shut down." << std::endl;
    }

private:
    CPU cpu_;
    Memory memory_;
    HardDisk hardDisk_;
};

int main() {
    // Use the Facade to start and shut down the computer
    ComputerFacade computerFacade;
    computerFacade.startComputer();
    std::cout << std::endl;
    computerFacade.shutDownComputer();

    return 0;
}

Facade Pattern Explanation:
In this example, we have three subsystems: CPU, Memory, and HardDisk, each representing different components of a computer. They have their own methods to start, execute, read, write, load, and free.

We then create a ComputerFacade class, which acts as the Facade. It provides a simplified interface to the complex subsystem by defining methods to start and shut down the computer. Inside these methods, it calls the appropriate methods of the CPU, Memory, and HardDisk classes, hiding the complexities from the client.

In the main() function, we demonstrate how the Facade pattern works. We create an instance of the ComputerFacade, and through it, we start and shut down the computer. The client interacts with the Facade, which internally handles the interactions with the subsystems.

Applications of the Facade Design Pattern:

  1. Simplified Interface: It provides a simple and unified interface to a complex system, making it easier for clients to use.
  2. Subsystem Decoupling: It decouples the client code from the subsystems, as clients interact only with the Facade, not the individual subsystems.
  3. Code Maintenance: It improves code maintainability by encapsulating complex interactions within the Facade, reducing the impact of changes in the subsystems on the client code.

Pros of the Facade Design Pattern:

  • Provides a simplified interface, reducing the complexity of using a system.
  • Improves code readability and maintainability.
  • Allows easier adaptation to changes in the system.

Cons of the Facade Design Pattern:

  • If the Facade interface becomes too large or exposes too many details, it may violate the principle of a simple and clean interface.
  • It can add an additional layer of abstraction, which may impact performance in some scenarios.

In summary, the Facade pattern simplifies interactions with complex systems by providing a straightforward interface, hiding the underlying complexities, and decoupling the client code from the subsystems. It is especially useful when dealing with intricate systems that have multiple components and interactions.

Leave a Reply