Какие два принципа SOLID часто считают наиболее фундаментальными

«Какие два принципа SOLID часто считают наиболее фундаментальными» — вопрос из категории ООП, который задают на 10% собеседований Python Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Чаще всего наиболее фундаментальными считают Принцип единственной ответственности (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}")