Facade Pattern in Python with Mock Simplification

This code demonstrates the Facade pattern by hiding complex subsystem interactions behind a simple start/stop interface, and adds a MockFacade for testing failure scenarios.

Medium Python 3.9+ Aug 9, 2026 System design patterns 15 views 0 copies

Python code

51 lines
Python 3.9+
class SubsystemA:
    def operation_a(self):
        return "Subsystem A: ready"

class SubsystemB:
    def operation_b(self):
        return "Subsystem B: ready"

class SubsystemC:
    def operation_c(self):
        return "Subsystem C: ready"


class Facade:
    def __init__(self):
        self._a = SubsystemA()
        self._b = SubsystemB()
        self._c = SubsystemC()

    def start(self):
        results = [
            self._a.operation_a(),
            self._b.operation_b(),
            self._c.operation_c(),
        ]
        return " | ".join(results)

    def stop(self):
        return "All subsystems stopped"


class MockFacade(Facade):
    def __init__(self, fail=False):
        super().__init__()
        self._fail = fail

    def start(self):
        if self._fail:
            return "Mock: simulation failure"
        return "Mock: " + super().start()


if __name__ == "__main__":
    real = Facade()
    mock = MockFacade()
    mock_fail = MockFacade(fail=True)

    print("Real facade:", real.start())
    print("Mock facade:", mock.start())
    print("Mock failed:", mock_fail.start())
    print("Stop:", real.stop())

Output

stdout
Real facade: Subsystem A: ready | Subsystem B: ready | Subsystem C: ready
Mock facade: Mock: Subsystem A: ready | Subsystem B: ready | Subsystem C: ready
Mock failed: Mock: simulation failure
Stop: All subsystems stopped

How it works

The Facade class encapsulates the initialization and coordination of three subsystems, exposing a simplified start and stop API. The MockFacade extends the Facade and overrides start to simulate success or failure without touching the real subsystems. This decouples client code from the subsystem internals, making it easier to test or replace complexity. The __main__ block demonstrates both real and mock behavior, showing how the facade hides implementation details.

Common mistakes

  • Forgetting to call `super().__init__()` in the mock subclass to initialize subsystems
  • Overriding `stop` in MockFacade when not needed, risking inconsistent behavior
  • Making the facade too thick by exposing subsystem methods instead of a simplified interface

Variations

  1. Use a factory function to return either a Facade or MockFacade based on configuration
  2. Implement MockFacade with dependency injection instead of inheritance for more flexibility

Real-world use cases

  • Wrapping multiple microservice clients behind a single API for a mobile app backend.
  • Providing a simplified test double for a complex payment gateway in unit tests.
  • Hiding intricate legacy system calls behind a clean interface for a new module.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from System design patterns

Related tutorials and quizzes for this topic.