Что учить дальше: SOLID, архитектура, фреймворки
Поздравляем — вы прошли весь курс «ООП на Python»! 🎉 Это последний урок. Здесь нет домашнего задания и синтаксических упражнений. Здесь — карта: куда двигаться дальше, что читать, что изучать и как ООП живёт в реальных проектах.
🏆 Вы дошли до конца. Это серьёзно.
Вы начали с нуля — с понятия «что такое объект» — и прошли путь до декораторов, миксинов, протоколов и архитектурных паттернов. Большинство людей бросают на середине. Вы не бросили. Теперь у вас есть фундамент, на котором строятся реальные приложения. Это и правда важно — не преувеличение.
🧱 Принципы SOLID — следующая ступень
SOLID — это пять принципов объектно-ориентированного дизайна, сформулированных Робертом Мартином. Они не про синтаксис — они про то, как думать при проектировании классов. Вы уже интуитивно применяли некоторые из них в этом курсе. Теперь пора знать их по имени.
Single Responsibility — одна ответственность
Один класс — одна причина меняться. Если класс занимается и сохранением в базу, и отправкой писем — это уже два класса.
📌 В нашем курсе: когда мы разбили OrderManager на UserService, EmailService, ShippingService — это было SRP в действии.
Open/Closed — открыт для расширения, закрыт для изменения
Хороший класс можно расширять (добавлять новое поведение), не трогая существующий код. Новый класс-наследник — да. Редактировать старый рабочий код — нет.
📌 В нашем курсе: когда мы добавляли новые типы фигур через наследование от Shape, не меняя метод draw() — это был OCP.
Liskov Substitution — наследник заменяет родителя
Если код работает с объектом типа Animal, он должен работать и с любым подклассом: Dog, Cat, Bird. Наследник не должен ломать контракт родителя.
📌 В нашем курсе: мы обсуждали это когда говорили о правильном полиморфизме — одна функция работает с любым подклассом без проверок isinstance.
Interface Segregation — много маленьких интерфейсов
Лучше несколько узких протоколов/ABC, чем один большой. Класс не должен реализовывать методы, которые ему не нужны.
📌 В нашем курсе: мы создавали отдельные протоколы Drawable, Serializable, Validatable вместо одного монструозного базового класса.
Dependency Inversion — зависим от абстракций
Высокоуровневые модули не должны зависеть от низкоуровневых. Оба должны зависеть от абстракций (интерфейсов, протоколов, ABC). Это база для тестируемого кода.
📌 В нашем курсе: инъекция зависимостей в OrderService.__init__(self, email_service) — именно это. Не создаём зависимость внутри, а получаем снаружи.
💡 Пример: DIP — зависимость от абстракции
Вместо того чтобы создавать конкретный сервис внутри класса, передаём его снаружи — и можно легко подменить в тестах.
from abc import ABC, abstractmethod
# Абстракция — интерфейс для уведомлений
class Notifier(ABC):
@abstractmethod
def send(self, message: str) -> None:
...
# Конкретные реализации
class EmailNotifier(Notifier):
def send(self, message: str) -> None:
print(f"Email: {message}")
class SMSNotifier(Notifier):
def send(self, message: str) -> None:
print(f"SMS: {message}")
class SilentNotifier(Notifier):
"""Для тестов — ничего не отправляет."""
def send(self, message: str) -> None:
pass
# OrderService зависит от абстракции Notifier, а не от EmailNotifier напрямую
class OrderService:
def __init__(self, notifier: Notifier):
self.notifier = notifier # инъекция зависимости
def place_order(self, order):
# ... логика ...
self.notifier.send(f"Заказ #{order.id} принят")
# В продакшене
service = OrderService(EmailNotifier())
# В тестах — подменяем без изменения кода OrderService
service = OrderService(SilentNotifier())
🏗️ Архитектурные паттерны
SOLID — это про отдельные классы. Архитектурные паттерны — про то, как классы и модули организованы в систему. Когда проект вырастает до десятков файлов, архитектура — это то, что не даёт ему превратиться в хаос.
🎭 MVC
Model–View–Controller. Данные, отображение и логика управления — три отдельных слоя.
Именно так устроен Django: Model — таблица в БД, View — бизнес-логика запроса, Template — отображение.
🧅 Clean Architecture
Чистая архитектура Роберта Мартина. Три слоя: Domain → Application → Infrastructure.
Внутренние слои (бизнес-логика) не знают о внешних (база данных, HTTP, почта). Легко тестировать.
🗺️ DDD
Domain-Driven Design. Архитектура отражает язык бизнеса: классы называются так, как говорят эксперты.
Большая тема для изучения после Clean Architecture. Книга Эрика Эванса — классика.
🧅 Слои Clean Architecture на Python
# Слой 1: Domain — чистые бизнес-объекты, НИКАКИХ зависимостей от фреймворков
class Order:
def __init__(self, order_id: int, items: list):
self.order_id = order_id
self.items = items
self.status = "pending"
def confirm(self):
if not self.items:
raise ValueError("Нельзя подтвердить пустой заказ")
self.status = "confirmed"
# Слой 2: Application — юзкейсы, оркестрирует Domain
class ConfirmOrderUseCase:
def __init__(self, order_repo, notifier):
self.order_repo = order_repo # абстракция
self.notifier = notifier # абстракция
def execute(self, order_id: int):
order = self.order_repo.get(order_id)
order.confirm()
self.order_repo.save(order)
self.notifier.send(f"Заказ #{order_id} подтверждён")
# Слой 3: Infrastructure — конкретные реализации
class PostgresOrderRepository:
def get(self, order_id): ... # SQL-запрос
def save(self, order): ... # SQL-запрос
# Domain и Application не знают про PostgreSQL, Django, HTTP — только абстракции
🚀 Фреймворки на Python — всё ООП под капотом
Теперь, когда вы понимаете ООП, вы будете читать код популярных Python-фреймворков совершенно иначе. Это не магия — это классы, наследование, полиморфизм и протоколы.
🌐 Django
Самый популярный Python-фреймворк для веба. Весь построен на ООП:
Model
Класс = таблица в БД. Атрибуты класса = колонки. models.Model — базовый класс.
View
View, ListView, DetailView — иерархия классов-обработчиков HTTP.
Form / Serializer
Валидация данных через классы и дескрипторы — чистый ООП.
Signal
Паттерн «Наблюдатель» прямо в Django. Объект события + подписчики.
🍶 Flask
Лёгкий минималистичный фреймворк. На первый взгляд кажется «процедурным» (декораторы, функции-обработчики), но под капотом — объект Flask, Blueprint, MethodView. Хорош для изучения того, как работает HTTP и WSGI — без магии Django.
📌 Flask хорошо изучать после Django — вы увидите, что Django «автоматизирует» то, что во Flask вы делаете руками.
⚡ FastAPI
Современный асинхронный фреймворк. Использует type hints как основу: вы описываете типы — FastAPI сам генерирует валидацию, сериализацию и Swagger-документацию. Pydantic под капотом — классы с аннотациями типов превращаются в валидаторы.
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
# Pydantic-модель — это класс!
class OrderRequest(BaseModel):
product_id: int
quantity: int
user_email: str # автоматическая валидация типов
@app.post("/orders")
async def create_order(order: OrderRequest):
# FastAPI автоматически провалидирует тело запроса
# и вернёт 422 Unprocessable Entity если типы не совпадают
return {"status": "created", "order": order.model_dump()}
FastAPI — хорошая точка входа в асинхронный Python (async/await) и современную разработку API.
📚 Что читать: книги и исходники
📖 «Чистый код»
Роберт Мартин (Uncle Bob)
Классика. Про именование, функции, классы и архитектуру. Читается легко, применяется сразу. Первая книга после курса.
📖 «Fluent Python»
Лусиану Рамальо
Глубокое погружение в Python: дата-модель, протоколы, метаклассы, дескрипторы. Лучшая книга по Python ООП.
📖 «Паттерны проектирования»
GoF — Gang of Four
23 классических паттерна: Фабрика, Стратегия, Наблюдатель и другие. Язык, которым говорят разработчики во всём мире.
💻 Исходники Django, Flask, Requests
GitHub
Лучшая школа — читать как это написано профессионалами. Начни с requests — небольшая, отлично написанная библиотека.
🗺️ Рекомендуемый порядок: «Чистый код» → начать Django-проект → «Fluent Python» → GoF-паттерны → читать исходники Django. Параллельно практикуйтесь — без практики книги не усвоятся.
🎯 ООП — инструмент, а не цель
Есть соблазн везде создавать классы и выстраивать иерархии — только потому что «так правильно». Это ловушка. ООП — один из инструментов, не единственный. Python поддерживает и функциональный стиль, и процедурный. Задача программиста — решить задачу. Выбирай инструмент под задачу, а не задачу под инструмент.
Хорошая эвристика: если вам нужно состояние (данные, которые меняются) и поведение (методы работающие с этим состоянием) — ООП. Если задача — преобразовать данные без побочных эффектов — функции и генераторы.
Самый чистый код — тот, который решает задачу максимально просто. Не умный. Не «красивый». Простой. Это и есть профессиональный уровень.
🗂️ Что вы изучили в этом курсе
🐍 Модуль 1–3
Классы и объекты, __init__, атрибуты, методы. Инкапсуляция. Первые принципы ООП.
🧬 Модуль 4–5
Наследование, super(), переопределение методов, MRO, множественное наследование.
🎭 Модуль 6–7
Полиморфизм, утиная типизация, ABC, интерфейсы и протоколы.
🪄 Модуль 8–9
Магические методы, дескрипторы, @property, @classmethod, @staticmethod.
🏗️ Модуль 10–11
Паттерны проектирования: Singleton, Factory, Observer, Strategy, Decorator и другие.
⚠️ Модуль 12
Тестирование, типичные ошибки в ООП, SOLID и путь вперёд.
🎓 Поздравляем с завершением курса!
Вы прошли путь от «что такое класс» до понимания архитектурных принципов, которые используются в реальных компаниях. Это основа, которую вы будете применять каждый день — в любом проекте, на любом фреймворке.
Впереди много интересного: Django и FastAPI, тесты и CI/CD, асинхронность и микросервисы. Но теперь всё это вы будете воспринимать иначе — вы будете видеть структуру, а не просто код.
🚀 Следующий шаг: выберите один реальный проект и напишите его с нуля, применяя всё что узнали. Это лучшее закрепление. Размер не важен — важна структура. Удачи!