Задача курса
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(...)и возвращает отформатированную строку.
Верхнеуровневый скрипт-демонстрация:
После определения классов напиши скрипт, который:
- Создаёт
store1 = InMemoryStore(). - Создаёт
svc1 = NotificationService(formatter=PlainFormatter(), store=store1)и вызываетsvc1.send("alice", "hello")иsvc1.send("bob", "world"). - Сохраняет результат в
result1 = store1.count(). - Создаёт
store2 = InMemoryStore(). - Создаёт
svc2 = NotificationService(formatter=UpperFormatter(), store=store2)и вызываетsvc2.send("carol", "test"). - Сохраняет результат в
result2 = store2.count(). - Создаёт
svc3 = NotificationService(formatter=PlainFormatter(), store=NullStore())и вызываетsvc3.send("dave", "ignored"). - Сохраняет результат в
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 | ГОТОВО']
