C++ Facade Pattern Example

1. Definition

The Facade Design Pattern provides a unified interface to a set of interfaces in a subsystem, making the subsystem easier to use by hiding its complexities.

2. Problem Statement

Imagine you have a complex subsystem with dozens of intricate moving parts. If clients interact with the subsystem directly, they'd have to manage these complexities, leading to tangled code.

3. Solution

Offer a simplified, higher-level interface that shields clients from the complex internals of the subsystem. This higher-level interface is the "facade".

4. Real-World Use Cases

1. A home theater system where one remote (facade) controls lights, audio, video, etc.

2. A computer's operating system serving as a facade to hide the complexities of low-level operations from user applications.

5. Implementation Steps

1. Identify a simpler, unified interface that can cover most of the interactions of the subsystem.

2. Create a facade class that implements this interface and composes the subsystem classes.

3. Redirect the calls from the facade to the appropriate subsystem classes.

4. Clients interact only with the facade instead of touching the subsystem directly.

6. Implementation in C++

// Step 1: Define the subsystem classes
class Subsystem1 {
public:
    void operation1() const {
        std::cout << "Subsystem1: Initialization\n";
    }
};
class Subsystem2 {
public:
    void operation2() const {
        std::cout << "Subsystem2: Starting\n";
    }
};
class Subsystem3 {
public:
    void operation3() const {
        std::cout << "Subsystem3: Loading data\n";
    }
};
// Step 2: Create the Facade
class Facade {
private:
    Subsystem1* subsystem1;
    Subsystem2* subsystem2;
    Subsystem3* subsystem3;
public:
    Facade() {
        subsystem1 = new Subsystem1();
        subsystem2 = new Subsystem2();
        subsystem3 = new Subsystem3();
    }
    ~Facade() {
        delete subsystem1;
        delete subsystem2;
        delete subsystem3;
    }
    void start() {
        subsystem1->operation1();
        subsystem2->operation2();
        subsystem3->operation3();
    }
};
int main() {
    Facade* facade = new Facade();
    facade->start();
    delete facade;
    return 0;
}

Output:

Subsystem1: Initialization
Subsystem2: Starting
Subsystem3: Loading data

Explanation:

1. Subsystem1, Subsystem2, and Subsystem3 represent the complex subsystem with their distinct operations.

2. Facade class provides a higher-level interface to client code, simplifying the interaction with the subsystem.

3. When the client invokes the start method on the Facade, it internally manages the necessary interactions with the subsystem.

4. The client code (in main function) interacts solely with the Facade, avoiding direct interactions with the subsystem.

7. When to use?

Use the Facade pattern when:

1. You want to provide a simplified interface to a complex subsystem.

2. You want to decouple a subsystem from clients and other subsystems, exposing only essential features.

3. You want to layer your subsystems. A facade can define the entry point to each level of a layered software system.


Comments