Фасад

Описание
Фасад — структурный шаблон проектирования, позволяющий скрыть сложность системы путём сведения всех возможных внешних вызовов к одному объекту, делегирующему их соответствующим объектам системы.

Шаблон фасад предоставляет упрощенный интерфейс для сложной системы.
Пример
Рассмотрим пример создания объекта текстового буфера, в который будет возможность наполнить с конца сообщениями. При переполнении лимита буфера начальные символы удаляются.

Класс TextBuffer имеет три метода
- __getitem__ - позволяет настроить обращения к элементам buffer
- write - записывает сообщения в буфер
- read - свойство отображает содержимое буфера

Класс Viewport позволяет обращаться к классу более низкого уровня, переопределяет ряд методов и расширяет возможность взаимодействия методом get_char_at

Класс Console скрывает сложность взаимодействия с Viewport, самостоятельно создает внутренние объекты и реализует методы взаимодействия с ними. Это и является классом фасадом.

from dataclasses import dataclass
from typing import ClassVar


@dataclass
class TextBuffer:
    width: int = 4
    height: int = 14
    buffer: ClassVar = ['.'] * (width*height)

    def __getitem__(self, item):
        return self.buffer.__getitem__(item)

    def write(self, text):
        self.buffer += text

    @property
    def read(self):
        return self.buffer


@dataclass
class Viewport:
    buffer: TextBuffer = TextBuffer()
    offset: ClassVar = 0

    def get_char_at(self, index):
        return self.buffer[self.offset+index]

    def append(self, text):
        self.buffer.write(text+' ')

    @property
    def read(self):
        return self.buffer.read


@dataclass
class Console:

    def __post_init__(self):
        b = TextBuffer()
        self.current_viewport = Viewport(b)
        self.buffers = [b]
        self.viewports = [self.current_viewport]

    def write(self, text):
        self.current_viewport.append(text)

    def get_char_at(self, index):
        return self.current_viewport.get_char_at(index)

    @property
    def read(self):
        return self.current_viewport.read


if __name__ == '__main__':
    c = Console()
    c.write('hello')
    c.write('world')
    print(c.read)
    ch = c.get_char_at(28)
    print(ch)