Полный практический курс по паттернам проектирования для Python-разработчиков. Охватывает все 23 классических паттерна GoF, архитектурные паттерны (Repository, CQRS, Event Sourcing), asyncio-паттерны и антипаттерны. Каждый паттерн разбирается с глубоким пониманием: когда применять, когда НЕ применять, Pythonic-реализации через декораторы/contextmanager/dataclasses, реальные кейсы из production и рефакторинг легаси-кода.
Половина книги «банды четырёх» в Python не нужна в исходном виде: Strategy — это функция, переданная аргументом, Iterator — генератор, Singleton в большинстве случаев — обычный модуль. Паттерны при этом никуда не деваются, просто выглядят иначе, и главный навык — не выучить схему, а увидеть, когда язык уже решил задачу за вас.
Двадцать три темы. Все классические паттерны GoF разбираются в трёх видах: канонический вариант из книги, питоновская реализация через декораторы, contextlib, dataclasses, singledispatch, дескрипторы, __slots__, weakref — и ответ на вопрос, когда паттерн здесь вообще не нужен. У каждого есть раздел «когда НЕ применять»: чаще всего именно он экономит время.
Дальше — то, чего в книге 1994 года быть не могло. Repository и Unit of Work поверх SQLAlchemy и asyncpg. CQRS и Event Sourcing: разделение чтения и записи, события как источник истины, проекции и цена, которую за это платят. Asyncio-паттерны — Producer-Consumer, Rate Limiter, Circuit Breaker, повторы с экспоненциальной задержкой.
Заканчивается курс антипаттернами: God Object, Singleton как глобальная переменная, преждевременная оптимизация, протекающие абстракции — и рефакторингом легаси в сторону нормальной структуры.
Уровень — middle и senior. Курс не учит ООП: классы, наследование и композиция должны быть привычным инструментом, иначе разговор о выборе между ними не имеет смысла.
Что такое паттерны проектирования и когда они нужны. Singleton через __new__, метаклассы и декораторы. Monostate (Borg) как Pythonic-альтернатива.
Фабричные методы через @classmethod, абстрактные фабрики для семейств объектов. Dependency Injection через фабрики.
Построение сложных объектов пошагово. Fluent Interface через метод __enter__ и контекстные менеджеры. Dataclasses и attrs для Builder.
Прототипирование через copy/deepcopy. Магические методы __copy__ и __deepcopy__. Когда shallow copy достаточно, а когда нужен deep copy.
Адаптация интерфейсов через множественное наследование и композицию. Facade для упрощения сложных подсистем.
Разделение абстракции и реализации. Древовидные структуры через Composite. Применимость в Python.
Динамическое добавление поведения через декораторы функций и классов. functools.wraps, contextlib.contextmanager, декораторы с параметрами.
Оптимизация памяти через общие объекты. __slots__ для экономии памяти. Interning строк и кэширование мелких объектов.
Контроль доступа к объектам. Virtual Proxy для отложенной загрузки. Property-based lazy loading, __getattr__ и дескрипторы.
Цепочки обработчиков. Middleware-паттерн в веб-фреймворках. Обработка ошибок и short-circuit evaluation.
Инкапсуляция действий как объектов. Реализация отмены/повтора операций. Команды через callable-объекты и functools.partial.
Итераторы через __iter__ и __next__. Генераторы и yield from. Lazy evaluation и бесконечные последовательности.
Централизованное взаимодействие объектов. Event Bus для слабой связанности. asyncio.Queue для асинхронных событий.
Сохранение состояния объектов. Pickle для сериализации. dataclasses.asdict и __getstate__/__setstate__.
Реактивное программирование через наблюдателей. Pub/Sub для распределённых систем. Слабые ссылки через weakref.
Управление состоянием через объекты. Конечные автоматы (FSM). Библиотека transitions и state_machine.
Семейство алгоритмов через стратегию. Dependency Injection через конструктор и инжекторы. dependency_injector.
Скелет алгоритма в базовом классе. Hooks для расширения поведения. ABC и @abstractmethod.
Операции над объектами без изменения классов. Double dispatch через singledispatch. Pattern matching Python 3.10+.
Абстракция доступа к данным. Unit of Work для транзакций. SQLAlchemy и asyncpg примеры.
Разделение чтения и записи. События как источник истины. Проекции и материализованные представления.
Асинхронные паттерны: Producer-Consumer, Rate Limiter, Circuit Breaker, Retry с экспоненциальной задержкой.
Распространённые ошибки: God Object, Singleton-глобал, Premature Optimization, Leaky Abstractions. Рефакторинг к чистому коду.
Доступен после всех тем (0 из 23)
Доступен после зачёта
Повторяемое решение распространённой проблемы проектирования. Паттерн — это не готовый код, а шаблон, который адаптируется под конкретную задачу.
Пример
Singleton гарантирует, что у класса будет только один экземпляр, и предоставляет глобальную точку доступа к нему.Связанные термины
Распространённое решение, которое кажется полезным, но на деле вредит архитектуре кода. Антипаттерны часто возникают из-за неправильного применения паттернов.
Пример
Singleton, использованный как глобальная переменная, превращается в антипаттерн — код становится трудно тестировать.Связанные термины
Фундаментальное правило, направляющее проектирование кода. Принципы более абстрактны, чем паттерны.
Пример
Принцип единственной ответственности (SRP): класс должен иметь только одну причину для изменения.Связанные термины
Акроним пяти принципов объектно-ориентированного проектирования: Single Responsibility, Open-Closed, Liskov Substitution, Interface Segregation, Dependency Inversion.
Пример
Принцип инверсии зависимостей (D) требует зависеть от абстракций, а не от конкретных классов — это основа Dependency Injection.Связанные термины
Порождающий паттерн, гарантирующий, что у класса есть только один экземпляр, и предоставляющий глобальную точку доступа к нему.
Пример
Логгер, пул соединений с БД, конфигурация приложения — типичные кандидаты на Singleton.Связанные термины
Вариант Singleton, где у класса может быть много экземпляров, но все они разделяют одно и то же состояние через общий __dict__.
Пример
Класс Borg: все экземпляры имеют общий __dict__, поэтому изменение атрибута в одном экземпляре видно во всех.Связанные термины
Порождающий паттерн, определяющий интерфейс для создания объекта, но позволяющий подклассам изменить тип создаваемого объекта.
Пример
Метод @classmethod от factory() возвращает экземпляр нужного подкласса в зависимости от аргументов.Связанные термины
Паттерн, предоставляющий интерфейс для создания семейств связанных или зависимых объектов без привязки к конкретным классам.
Пример
Фабрика GUI-виджетов создаёт кнопки, меню и диалоги в стиле Windows или macOS.Связанные термины
Порождающий паттерн для пошагового создания сложных объектов, позволяющий получать разные представления одного объекта.
Пример
Построение SQL-запроса: builder.select().from_().where().order_by().build().Связанные термины
Стиль проектирования API, где методы возвращают self, позволяя цепочечные вызовы.
Пример
query.filter(x>0).sort('name').limit(10).execute()Связанные термины
Паттерн создания объектов через копирование существующего экземпляра (прототипа) вместо создания нового через конструктор.
Пример
copy.deepcopy(obj) создаёт полную копию объекта с рекурсией по вложенным объектам.Связанные термины
Структурный паттерн, позволяющий объектам с несовместимыми интерфейсами работать вместе.
Пример
Адаптер старого XML-парсера к новому JSON-интерфейсу через композицию.Связанные термины
Структурный паттерн, предоставляющий простой интерфейс к сложной системе классов, библиотеке или фреймворку.
Пример
Модуль requests — фасад для сложной работы с HTTP-сокетами, SSL, куками.Связанные термины
Структурный паттерн, разделяющий абстракцию и реализацию так, чтобы их можно было изменять независимо.
Пример
Фигуры (абстракция) и рендереры (реализация) — можно добавлять новые фигуры и рендереры независимо.Связанные термины
Структурный паттерн, организующий объекты в древовидные структуры и позволяющий работать с ними единообразно.
Пример
Файловая система: файлы и папки имеют общий интерфейс getSize(), но папка рекурсивно суммирует размеры файлов.Связанные термины
Структурный паттерн для динамического добавления поведения объектам через обёртку. В Python также языкОвая конструкция для модификации функций.
Пример
@lru_cache кэширует результаты функции; @contextmanager превращает генератор в контекстный менеджер.Связанные термины
Структурный паттерн для экономии памяти через переиспользование общих объектов вместо создания новых.
Пример
Символы в текстовом редакторе: общие данные (шрифт, размер) хранятся один раз, уникальные (позиция) — в каждом экземпляре.Связанные термины
Структурный паттерн, где объект-заместитель контролирует доступ к другому объекту.
Пример
Virtual Proxy откладывает загрузку тяжёлого изображения до момента первого отображения на экране.Связанные термины
Паттерн, откладывающий инициализацию объекта до момента первого использования.
Пример
@property с кэшированием: значение вычисляется при первом доступе и сохраняется в __dict__.Связанные термины
Поведенческий паттерн, передающий запрос по цепочке обработчиков до тех пор, пока один из них не обработает запрос.
Пример
Middleware в веб-фреймворках: запрос проходит через цепочку middleware до view-функции.Связанные термины
Компонент, обрабатывающий запрос до и/или после основного обработчика. Реализация Chain of Responsibility в веб-фреймворках.
Пример
CORS middleware добавляет заголовки; auth middleware проверяет токен перед передачей запроса дальше.Связанные термины
Поведенческий паттерн, инкапсулирующий запрос как объект, позволяя параметризовать клиентов с разными запросами и поддерживать undo/redo.
Пример
Текстовый редактор: команды Insert, Delete, Format с методами execute() и undo().Связанные термины
Поведенческий паттерн, предоставляющий способ последовательного доступа к элементам составного объекта без раскрытия его внутреннего представления.
Пример
for x in iterable: использует __iter__() и __next__() для обхода элементов.Связанные термины
Функция, возвращающая итератор и использующая yield для приостановки выполнения и возврата значения.
Пример
def count(): n=0; while True: yield n; n+=1 — бесконечная последовательность.Связанные термины
Поведенческий паттерн, централизующий взаимодействие между объектами, уменьшая связанность.
Пример
Диалоговое окно: mediator координирует кнопки, поля ввода и списки, чтобы они не ссылались друг на друга напрямую.Связанные термины
Механизм публикации/подписки на события, позволяющий компонентам общаться без прямых ссылок друг на друга.
Пример
asyncio.Queue как шина событий: продюсеры кладут события, консьюмеры обрабатывают.Связанные термины
Поведенческий паттерн, позволяющий сохранять и восстанавливать состояние объекта, не нарушая инкапсуляцию.
Пример
Сохранение состояния редактора в стек для undo: memento = editor.save(); editor.restore(memento).Связанные термины
Поведенческий паттерн, создающий механизм подписки, позволяющий одним объектам следить и реагировать на события в других объектах.
Пример
Модель данных уведомляет представления об изменениях: view.update(model.data).Связанные термины
Паттерн обмена сообщениями, где издатели отправляют сообщения в топик, а подписчики получают сообщения из топиков, на которые подписались.
Пример
Redis Pub/Sub: сервис заказов публикует 'order.created', сервис уведомлений подписывается и отправляет email.Связанные термины
Поведенческий паттерн, позволяющий объекту изменять поведение при изменении внутреннего состояния через переходы между объектами состояний.
Пример
Заказ: состояния New → Paid → Shipped → Delivered; каждый переход меняет доступные операции.Связанные термины
Модель поведения системы с конечным числом состояний и переходами между ними при наступлении событий.
Пример
Светофор: состояния Red → Green → Yellow → Red; переходы по таймеру.Связанные термины
Поведенческий паттерн, определяющий семейство алгоритмов, инкапсулирующий каждый из них и делающий их взаимозаменяемыми.
Пример
Сортировка: стратегия QuickSort для больших массивов, InsertionSort для маленьких — выбор в рантайме.Связанные термины
Паттерн, при котором зависимости объекта передаются извне (через конструктор или параметры), а не создаются внутри.
Пример
class Service: def __init__(self, repo: Repository): self.repo = repo — repo инжектится извне.Связанные термины
Поведенческий паттерн, определяющий скелет алгоритма в базовом классе, позволяя подклассам переопределять шаги без изменения структуры.
Пример
Базовый класс отчёта: generate() → fetch_data() → format() → send(); подклассы переопределяют format().Связанные термины
Метод с пустой или стандартной реализацией в базовом классе, предназначенный для переопределения в подклассах.
Пример
before_save() и after_save() в ORM — подклассы могут добавить логику в эти точки расширения.Связанные термины
Поведенческий паттерн, позволяющий добавлять операции к объектам без изменения их классов через double dispatch.
Пример
AST-обход: visitor.visit(ASTNode) применяет разные логики к разным типам узлов.Связанные термины
Механизм выбора метода для вызова на основе типов двух объектов (получатель и аргумент).
Пример
shape.intersect(circle) вызывает shape.intersectWithCircle(circle) — выбор по типу shape и circle.Связанные термины
Архитектурный паттерн, абстрагирующий доступ к данным: коллекция объектов домена с методами add(), remove(), find().
Пример
class UserRepository: def get_by_id(self, id: UUID) -> User: ... — скрывает SQL/NoSQL детали.Связанные термины
Паттерн поддержания списка объектов, изменённых в ходе бизнес-транзакции, и координация записи изменений в БД.
Пример
with UnitOfWork() as uow: uow.users.add(user); uow.commit() — атомарная транзакция.Связанные термины
Архитектурный паттерн разделения операций чтения (Query) и записи (Command) на разные модели.
Пример
Command-модель: доменные объекты с бизнес-логикой; Query-модель: денормализованные DTO для быстрого чтения.Связанные термины
Паттерн, где состояние системы определяется как последовательность событий; текущее состояние вычисляется применением событий.
Пример
Счёт банка: не хранится баланс, а есть события Deposit, Withdraw; баланс = сумма всех событий.Связанные термины
В CQRS/ES: материализованное представление данных, оптимизированное для чтения, построенное из событий.
Пример
Проекция 'Последние заказы' строится из событий OrderCreated, OrderShipped для быстрого отображения в UI.Связанные термины
Синтаксис Python для асинхронного программирования: async def объявляет корутину, await приостанавливает выполнение до результата.
Пример
async def fetch(url): response = await session.get(url); return await response.text()Связанные термины
Функция, выполнение которой можно приостановить и возобновить. В Python объявляется через async def.
Пример
async def worker(): while True: item = await queue.get(); process(item)Связанные термины
Механизм планирования и выполнения корутин: переключается между задачами при ожидании I/O.
Пример
asyncio.run(main()) запускает event loop, который выполняет корутины до завершения.Связанные термины
Паттерн обработки ошибок: при множественных неудачах размыкает цепь, предотвращая дальнейшие вызовы, и периодически пробует восстановить.
Пример
HTTP-клиент: после 5 ошибок выключатель открывается на 30 сек, затем полуоткрывается для тестового запроса.Связанные термины
Паттерн повторного выполнения операции при временных ошибках, часто с экспоненциальной задержкой (exponential backoff).
Пример
@retry(on=ConnectionError, delay=exponential(1, 2, 5)) — до 5 попыток с задержкой 1, 2, 4, 8, 16 сек.Связанные термины
Антипаттерн: класс, который знает и делает слишком много, нарушая принцип единственной ответственности.
Пример
Класс Application на 2000 строк с методами для БД, HTTP, бизнес-логики, отчётов — трудно тестировать и изменять.Связанные термины
Антипаттерн оптимизации кода до понимания реальных узких мест, усложняющий архитектуру без пользы.
Пример
Внедрение кэша Redis до запуска проекта, когда запросы выполняются за 10 мс и нагрузка 10 RPS.Связанные термины
Антипаттерн, где абстракция раскрывает детали реализации, которые должен скрывать.
Пример
ORM, где для оптимизации нужно знать SQL-запросы — абстракция 'протекает'.Связанные термины
Механизм Python для экономии памяти: объявляет фиксированный набор атрибутов класса, запрещая __dict__.
Пример
class Point: __slots__ = ['x', 'y'] — экономит ~40% памяти на экземпляре.Связанные термины
Оптимизация Python: хранение только одной копии неизменяемых объектов (строки, мелкие целые) для переиспользования.
Пример
sys.intern('hello') гарантирует, что все 'hello' в программе ссылаются на один объект.Связанные термины
Объект, определяющий методы __enter__ и __exit__, используемый в with для управления ресурсами.
Пример
with open('file.txt') as f: data = f.read() — файл автоматически закроется.Связанные термины
Модуль Python для упрощения создания контекстных менеджеров через @contextmanager и contextlib.closing.
Пример
@contextmanager def timer(): start=time(); yield; print(time()-start)Связанные термины
Объект с методами __get__, __set__, __delete__, позволяющий кастомизировать доступ к атрибутам класса.
Пример
property() — встроенный дескриптор; @property создаёт getter/setter/deleter.Связанные термины
Абстрактный базовый класс в Python через abc.ABC и @abstractmethod для определения интерфейса.
Пример
class Repository(ABC): @abstractmethod def get(self, id): ... — нельзя создать экземпляр без реализации.Связанные термины
Декоратор functools для создания функций с перегрузкой по типу первого аргумента.
Пример
@singledispatch def process(x): ...; @process.register(list) def _(x): ... — выбор реализации по типу.Связанные термины
Декоратор @dataclass для автоматической генерации __init__, __repr__, __eq__ и других методов класса.
Пример
@dataclass class Point: x: float; y: float — автоматически создаёт конструктор и repr.Связанные термины
Состав курса, уровни, практика и способы проверки знаний.
Курс включает 23 темы и 184 вопроса с разбором ответа. Начать можно с первой темы курса.
Маршрут охватывает уровни Middle, Senior. Темы расположены от основы к более сложным инженерным задачам, поэтому можно начать с подходящего места и не пропускать важные зависимости.
После прохождения тем доступен зачёт по курсу «Паттерны проектирования на Python» — 20 случайных вопросов с порогом 80%. После зачёта открывается экзамен с развёрнутыми ответами и автоматической оценкой, приближённый к техническому собеседованию.
Да, курс полностью бесплатный: все 23 темы доступны без оплаты.