Принципы SOLID в Django

Принципы SOLID в Django

24 апреля 2025 г.


SOLID — это акроним, состоящий из пяти принципов объектно-ориентированного проектирования, которые помогают создавать систему, легко масштабируемую, тестируемую и поддерживаемую. Эти принципы были предложены Робертом Мартином (Uncle Bob) и могут быть полезны в любом программировании, включая Django.

1. S — Single Responsibility Principle (SRP)

Принцип единой ответственности: Каждый класс должен иметь только одну причину для изменения, то есть отвечать за одну задачу.


# Нарушение SRP
class UserManager:
    def create_user(self, data):
        user = User.objects.create(**data)
        send_welcome_email(user)
        log_creation(user)
        return user
# Соблюдение SRP
class UserManager:
    def create_user(self, data):
        return User.objects.create(**data)
class EmailService:
    def send_welcome_email(self, user):
        send_mail("Welcome", "Hello!", "from@example.com", [user.email])
class Logger:
    def log_creation(self, user):
        logger.info(f"User {user.username} created.")


2. O — Open/Closed Principle (OCP)

Принцип открытости/закрытости: Сущности программного обеспечения должны быть открыты для расширения, но закрыты для модификации.


# Нарушение OCP
class PaymentProcessor:
    def process(self, order):
        if order.payment_method == "credit_card":
            self._process_credit_card(order)
        elif order.payment_method == "paypal":
            self._process_paypal(order)
# Соблюдение OCP
class PaymentProcessor:
    def process(self, order):
        payment_method = self._get_payment_method(order)
        payment_method.process(order)
    def _get_payment_method(self, order):
        if order.payment_method == "credit_card":
            return CreditCardPayment()
        elif order.payment_method == "paypal":
            return PayPalPayment()
class PaymentMethod(ABC):
    @abstractmethod
    def process(self, order):
        pass
class CreditCardPayment(PaymentMethod):
    def process(self, order):
        # Логика обработки кредитной карты
class PayPalPayment(PaymentMethod):
    def process(self, order):
        # Логика обработки PayPal


3. L — Liskov Substitution Principle (LSP)

Принцип подстановки Лисков: Объекты подклассов должны быть взаимозаменяемы с объектами суперклассов без нарушения корректности программы.


# Нарушение LSP
class Bird:
    def fly(self):
        pass
class Ostrich(Bird):
    def fly(self):
        raise NotImplementedError("Ostriches can't fly")
# Соблюдение LSP
class Bird(ABC):
    @abstractmethod
    def move(self):
        pass
class Sparrow(Bird):
    def move(self):
        # Логика полёта
class Ostrich(Bird):
    def move(self):
        # Логика бега


4. I — Interface Segregation Principle (ISP)

Принцип разделения интерфейса: Клиенты не должны зависеть от интерфейсов, которые они не используют.


# Нарушение ISP
class UserManager:
    def create_user(self, data):
        # Логика создания пользователя
    def send_email(self, user):
        # Логика отправки письма
    def log_activity(self, user):
        # Логика логирования
# Соблюдение ISP
class UserManager:
    def create_user(self, data):
        # Логика создания пользователя
class EmailService:
    def send_email(self, user):
        # Логика отправки письма
class Logger:
    def log_activity(self, user):
        # Логика логирования


5. D — Dependency Inversion Principle (DIP)

Принцип инверсии зависимостей: Модули верхнего уровня не должны зависеть от модулей нижнего уровня. Оба должны зависеть от абстракций.


# Нарушение DIP
class UserManager:
    def __init__(self):
        self.email_service = EmailService()
    def create_user(self, data):
        user = User.objects.create(**data)
        self.email_service.send_welcome_email(user)
        return user
# Соблюдение DIP
class UserManager:
    def __init__(self, email_service: EmailService):
        self.email_service = email_service
    def create_user(self, data):
        user = User.objects.create(**data)
        self.email_service.send_welcome_email(user)
        return user

Применение SOLID в Django

SRP: Разделяйте логику представления, обработки данных и бизнес-логику. Используйте сервисы, формы и сериализаторы для разделения ответственности.

OCP: Используйте абстракции, такие как миксины, абстрактные классы и интерфейсы, чтобы расширять функциональность без изменения существующего кода.

LSP: Убедитесь, что подклассы корректно реализуют поведение суперклассов и не нарушают ожидаемую логику.

ISP: Разделяйте интерфейсы и классы, чтобы клиенты зависели только от тех методов, которые они действительно используют.

DIP: Используйте абстракции и инъекцию зависимостей для уменьшения связности между компонентами системы. 
 


Оригинал
PREVIOUS ARTICLE