$ sudo teach IT
МОДУЛЬ 12 · УРОК 3 · ФИНАЛЬНЫЙ

Что учить дальше: SOLID, архитектура, фреймворки

Поздравляем — вы прошли весь курс «ООП на Python»! 🎉 Это последний урок. Здесь нет домашнего задания и синтаксических упражнений. Здесь — карта: куда двигаться дальше, что читать, что изучать и как ООП живёт в реальных проектах.

⏱ ~30 минут 🏛️ SOLID 🏗️ Архитектура 🚀 Фреймворки 🎓 Финал курса

🏆 Вы дошли до конца. Это серьёзно.

Вы начали с нуля — с понятия «что такое объект» — и прошли путь до декораторов, миксинов, протоколов и архитектурных паттернов. Большинство людей бросают на середине. Вы не бросили. Теперь у вас есть фундамент, на котором строятся реальные приложения. Это и правда важно — не преувеличение.

🧱 Принципы SOLID — следующая ступень

SOLID — это пять принципов объектно-ориентированного дизайна, сформулированных Робертом Мартином. Они не про синтаксис — они про то, как думать при проектировании классов. Вы уже интуитивно применяли некоторые из них в этом курсе. Теперь пора знать их по имени.

S

Single Responsibility — одна ответственность

Один класс — одна причина меняться. Если класс занимается и сохранением в базу, и отправкой писем — это уже два класса.

📌 В нашем курсе: когда мы разбили OrderManager на UserService, EmailService, ShippingService — это было SRP в действии.

O

Open/Closed — открыт для расширения, закрыт для изменения

Хороший класс можно расширять (добавлять новое поведение), не трогая существующий код. Новый класс-наследник — да. Редактировать старый рабочий код — нет.

📌 В нашем курсе: когда мы добавляли новые типы фигур через наследование от Shape, не меняя метод draw() — это был OCP.

L

Liskov Substitution — наследник заменяет родителя

Если код работает с объектом типа Animal, он должен работать и с любым подклассом: Dog, Cat, Bird. Наследник не должен ломать контракт родителя.

📌 В нашем курсе: мы обсуждали это когда говорили о правильном полиморфизме — одна функция работает с любым подклассом без проверок isinstance.

I

Interface Segregation — много маленьких интерфейсов

Лучше несколько узких протоколов/ABC, чем один большой. Класс не должен реализовывать методы, которые ему не нужны.

📌 В нашем курсе: мы создавали отдельные протоколы Drawable, Serializable, Validatable вместо одного монструозного базового класса.

D

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, асинхронность и микросервисы. Но теперь всё это вы будете воспринимать иначе — вы будете видеть структуру, а не просто код.

🚀 Следующий шаг: выберите один реальный проект и напишите его с нуля, применяя всё что узнали. Это лучшее закрепление. Размер не важен — важна структура. Удачи!