7.4. Façade

  • EN: Façade

  • PL: Fasada

  • Type: object

The Facade design pattern is a structural design pattern that provides a simplified interface to a complex subsystem. It provides a unified interface to a set of interfaces in a subsystem, which makes the subsystem easier to use.

>>> class Subsystem1:
...     def operation1(self) -> str:
...         return "Subsystem1: Ready!\n"
...
>>> class Subsystem2:
...     def operation2(self) -> str:
...         return "Subsystem2: Go!\n"
...
>>> class Facade:
...     def __init__(self, subsystem1: Subsystem1, subsystem2: Subsystem2) -> None:
...         self._subsystem1 = subsystem1
...         self._subsystem2 = subsystem2
...
...     def operation(self) -> str:
...         results = []
...         results.append("Facade initializes subsystems:\n")
...         results.append(self._subsystem1.operation1())
...         results.append(self._subsystem2.operation2())
...         return "".join(results)
...
>>> subsystem1 = Subsystem1()
>>> subsystem2 = Subsystem2()
>>> facade = Facade(subsystem1, subsystem2)
>>> print(facade.operation())
Facade initializes subsystems:
Subsystem1: Ready!
Subsystem2: Go!

In this example, Subsystem1 and Subsystem2 are parts of a complex subsystem that perform some operation. Facade is a class that provides a simple interface to the complex subsystem. It initializes the subsystems and delegates the execution to them. The client code works with the Facade instead of working with the subsystem directly.

7.4.1. Pattern

  • Provide simple interface to complex system

design-patterns/structural/img/designpatterns-facade-pattern.png

7.4.2. Problem

  • Every time we want to send a push notification to users, we need to follow all steps:

    • connect() -> Connection

    • authenticate(appid, key) -> AuthToken

    • send(AuthToken, message, target)

    • conn.disconnect()

design-patterns/structural/img/designpatterns-facade-problem.png

from dataclasses import dataclass


@dataclass
class Message:
    content: str


class Connection():
    def disconnect(self) -> None:
        pass


class AuthToken:
    pass


class NotificationServer:
    """
    connect() -> Connection
    authenticate(appid, key) -> AuthToken
    send(AuthToken, message, target)
    conn.disconnect()
    """

    def connect(self, ip_address: str) -> Connection:
        return Connection()

    def authenticate(self, appid: str, key: str) -> AuthToken:
        return AuthToken()

    def send(self, authtoken: AuthToken, message: Message, target: str):
        print('Sending a message')


if __name__ == '__main__':
    server = NotificationServer()
    connection = server.connect('127.0.0.1')
    authtoken = server.authenticate('AppId', 'Key')
    message = Message('Hello World')
    server.send(authtoken, message, '192.168.0.1')
    connection.disconnect()

7.4.3. Solution

../../_images/designpatterns-facade-solution.png

from dataclasses import dataclass


@dataclass
class Message:
    content: str


class Connection():
    def disconnect(self) -> None:
        pass


class AuthToken:
    pass


class NotificationService:
    def send(self, message: str, target: str) -> None:
        server = NotificationServer()
        connection = server.connect('127.0.0.1')
        authtoken = server.authenticate('AppId', 'Key')
        server.send(authtoken, Message(message), target)
        connection.disconnect()


class NotificationServer:
    """
    connect() -> Connection
    authenticate(appid, key) -> AuthToken
    send(AuthToken, message, target)
    conn.disconnect()
    """

    def connect(self, ip_address: str) -> Connection:
        return Connection()

    def authenticate(self, appid: str, key: str) -> AuthToken:
        return AuthToken()

    def send(self, authtoken: AuthToken, message: Message, target: str):
        print('Sending a message')


if __name__ == '__main__':
    service = NotificationService()
    service.send('Hello World', '192.168.0.1')

7.4.4. Assignments

  • Clean datetime

  • Split name into firstname and lastname

  • Example from @staticmethod chapter