Ответ
Чаще всего наиболее фундаментальными считают Принцип единственной ответственности (SRP) и Принцип открытости/закрытости (OCP). Они закладывают основу для создания поддерживаемого и расширяемого кода.
1. Принцип единственной ответственности (Single Responsibility Principle, SRP)
Суть: Класс должен иметь только одну причину для изменения. Это означает, что он должен решать только одну, четко определенную задачу.
Почему это важно:
- Снижение связанности: Классы не зависят от деталей реализации других задач.
- Упрощение тестирования: Легче писать unit-тесты для класса, который делает что-то одно.
- Простота поддержки: Изменения в одной части логики не затрагивают другие.
Пример:
# Плохо: Класс отвечает и за данные, и за их сохранение
class User:
def __init__(self, name: str):
self.name = name
def save_to_db(self):
# Логика сохранения в базу данных...
print(f"Saving {self.name} to DB")
# Хорошо: Ответственности разделены
class User:
def __init__(self, name: str):
self.name = name
class UserRepository:
def save(self, user: User):
# Логика сохранения в базу данных...
print(f"Saving {user.name} to DB")
2. Принцип открытости/закрытости (Open/Closed Principle, OCP)
Суть: Программные сущности (классы, модули, функции) должны быть открыты для расширения, но закрыты для модификации.
Почему это важно:
- Стабильность: Позволяет добавлять новую функциональность, не изменяя существующий, уже протестированный код.
- Гибкость: Система легко адаптируется к новым требованиям через добавление нового кода, а не правку старого.
Пример (через абстракцию):
from abc import ABC, abstractmethod
# Абстракция, закрытая для изменений
class Notifier(ABC):
@abstractmethod
def send(self, message: str):
pass
# Реализации, открытые для расширения
class EmailNotifier(Notifier):
def send(self, message: str):
print(f"Sending email: {message}")
class SMSNotifier(Notifier):
def send(self, message: str):
print(f"Sending SMS: {message}")
# Можно легко добавить SlackNotifier, не трогая существующие классы
class SlackNotifier(Notifier):
def send(self, message: str):
print(f"Sending to Slack: {message}") Ответ 18+ 🔞
А, ну вот, опять про эти ваши принципы, блядь! Слушай, давай я тебе на пальцах, как для дебила, объясню, а то ты, сука, с умным видом книжки читаешь, а нихуя не вникаешь.
Так, первый принцип, SRP, он же «Принцип единственной ответственности». Представь себе, блядь, мужика на заводе. Он стоит у станка и делает одну деталь. Он её вытачивает, хуярит, и всё, он в этом пиздец как хорош. А теперь представь, что этот же мужик должен и деталь делать, и в бухгалтерии отчёт писать, и в столовой котлеты жарить. Что получится? Получится пиздец, блядь! Деталь кривая, отчёт с ошибками, а котлеты подгорелые. Вот и класс должен быть как этот мужик-станочник — делать что-то одно, но зато охуенно.
Вот смотри, какой бывает пиздец в коде:
# Плохо: Класс отвечает и за данные, и за их сохранение
class User:
def __init__(self, name: str):
self.name = name
def save_to_db(self):
# Логика сохранения в базу данных...
print(f"Saving {self.name} to DB")
Видишь? Этот User — он и швец, и жнец, и на дуде игрец. Он и пользователя хранит, и в базу его пихает. А если завтра база поменяется? Придётся этого юзера, сука, переписывать! А если логику сохранения надо будет протестировать отдельно? Пизда тебе, а не тесты.
А вот как надо, по-человечески:
# Хорошо: Ответственности разделены
class User:
def __init__(self, name: str):
self.name = name
class UserRepository:
def save(self, user: User):
# Логика сохранения в базу данных...
print(f"Saving {user.name} to DB")
Вот! Теперь User — это просто данные, кусок говна с полем name. А UserRepository — это отдельный пацан, который знает, как это говно в базу запихнуть. Один меняется — другой не трогаем. Красота, ёпта!
Теперь второй, OCP, «Принцип открытости/закрытости». Это вообще, блядь, магия какая-то. Суть в том, что твой код должен быть как храм — ты не можешь стены ломать, чтобы новую иконку повесить, но можешь, блядь, спокойно эту иконку на свободный гвоздик прицепить.
То есть, ты пишешь какой-то модуль, он работает, его протестировали, он святое. И тут приходит новый начальник и говорит: «А сделай-ка нам ещё и уведомления в телеграм, сука!». И ты не должен лезть в старый, отлаженный код и там что-то ковырять. Ты должен просто расширить его, добавив новую хуйню.
Смотри, как это выглядит без принципа — пиздец и ужас. Придётся везде if-ы пихать. А с принципом — красота:
from abc import ABC, abstractmethod
# Абстракция, закрытая для изменений
class Notifier(ABC):
@abstractmethod
def send(self, message: str):
pass
# Реализации, открытые для расширения
class EmailNotifier(Notifier):
def send(self, message: str):
print(f"Sending email: {message}")
class SMSNotifier(Notifier):
def send(self, message: str):
print(f"Sending SMS: {message}")
# Можно легко добавить SlackNotifier, не трогая существующие классы
class SlackNotifier(Notifier):
def send(self, message: str):
print(f"Sending to Slack: {message}")
Видишь? Есть абстрактный Notifier — это как контракт, договорённость. Все, кто его реализуют, обязуются иметь метод send. И неважно, почта это, смска или, блядь, голубиная почта — главное, что метод есть.
И когда тебе говорят: «Добавь уведомления в Телегу», ты, сука, не лезешь в EmailNotifier и не начинаешь там костыли приделывать. Ты просто создаёшь новый класс TelegramNotifier, который тоже подписывает этот контракт. И вся система продолжает работать, как часы, ни одна старая строчка кода не тронута! Это и есть «открыт для расширения, закрыт для модификации». Гениально, ёпта!
Вот эти два принципа — это как фундамент и стены дома. SRP — чтобы стены были ровные и не разъезжались в разные стороны. OCP — чтобы можно было пристроить балкон или мансарду, не разбирая весь дом до основания. Понял теперь, или тебе ещё на кошках объяснить?