Задача курса

Python: Сборщик уведомлений: замени жёсткую зависимость на инъекцию

Курс «Python для продвинутых: ООП, типизация и тестирование» · урок «Композиция: сборка поведения из нескольких объектов»

Условие

Сборщик уведомлений: замени жёсткую зависимость на инъекцию

Тебе нужно разбить монолитный класс NotificationService на несколько взаимодействующих объектов и убедиться, что замена одного компонента не ломает остальные части.

Что уже дано

Проверяющая система ничего не создаёт до твоего кода. В редакторе есть незавершённый каркас: классы с TODO-заглушками и верхнеуровневый скрипт-демонстрация. Весь код выполняется в одном процессе и пространстве имён.

Что нужно сделать

Определи следующие классы и логику на верхнем уровне:

Компонент-форматтер — два класса с одинаковым интерфейсом:

  • PlainFormatter — класс с методом format(self, recipient: str, message: str) -> str, возвращающим строку вида "To: {recipient} | {message}".
  • UpperFormatter — класс с методом format(self, recipient: str, message: str) -> str, возвращающим ту же строку, но полностью в верхнем регистре: "TO: {RECIPIENT} | {MESSAGE}".

Компонент-хранилище — два класса с одинаковым интерфейсом:

  • InMemoryStore — класс с методом save(self, text: str) -> None, который добавляет text в список self.records (список создаётся в __init__), и методом count(self) -> int, возвращающим длину self.records.
  • NullStore — класс с методом save(self, text: str) -> None (ничего не делает) и методом count(self) -> int (всегда возвращает 0).

Класс-владелец:

  • NotificationService — принимает в __init__(self, formatter, store) два компонента и сохраняет их как self.formatter и self.store.
  • Метод send(self, recipient: str, message: str) -> str — форматирует сообщение через self.formatter.format(recipient, message), сохраняет результат через self.store.save(...) и возвращает отформатированную строку.

Верхнеуровневый скрипт-демонстрация:

После определения классов напиши скрипт, который:

  1. Создаёт store1 = InMemoryStore().
  2. Создаёт svc1 = NotificationService(formatter=PlainFormatter(), store=store1) и вызывает svc1.send("alice", "hello") и svc1.send("bob", "world").
  3. Сохраняет результат в result1 = store1.count().
  4. Создаёт store2 = InMemoryStore().
  5. Создаёт svc2 = NotificationService(formatter=UpperFormatter(), store=store2) и вызывает svc2.send("carol", "test").
  6. Сохраняет результат в result2 = store2.count().
  7. Создаёт svc3 = NotificationService(formatter=PlainFormatter(), store=NullStore()) и вызывает svc3.send("dave", "ignored").
  8. Сохраняет результат в result3 = svc3.store.count().

Ввод и вывод

stdin не используется. Печатать через print в stdout ничего не нужно.

Проверяющая система запускает твой код как верхнеуровневый скрипт и после его выполнения читает глобальные имена: PlainFormatter, UpperFormatter, InMemoryStore, NullStore, NotificationService, store1, store2, svc1, svc2, svc3, result1, result2, result3.

Пример использования

store = InMemoryStore()
service = NotificationService(UpperFormatter(), store)
print(service.send("alex", "готово"))
print(store.records)

Результат:

TO: ALEX | ГОТОВО
['TO: ALEX | ГОТОВО']

Попробуйте решить

РешениеPython
Без регистрации · результат не сохраняется