
Принципы 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: Используйте абстракции и инъекцию зависимостей для уменьшения связности между компонентами системы.
Оригинал