Ответ
SOLID — это акроним для пяти ключевых принципов объектно-ориентированного проектирования, направленных на создание гибких, масштабируемых и поддерживаемых систем.
-
S — Single Responsibility Principle (Принцип единственной ответственности) Класс должен иметь только одну причину для изменения, то есть выполнять только одну основную задачу.
# Неправильно: класс делает всё сразу class User: def get_user_data(self): pass def save_to_db(self): pass # Правильно: обязанности разделены class User: def __init__(self, name): self.name = name class UserRepository: def save(self, user: User): print(f"Saving {user.name}") -
O — Open/Closed Principle (Принцип открытости/закрытости) Программные сущности (классы, модули) должны быть открыты для расширения, но закрыты для модификации.
from abc import ABC, abstractmethod class Shape(ABC): @abstractmethod def area(self): pass # Расширение: добавляем новые фигуры без изменения существующего кода class Rectangle(Shape): def area(self): return 2 * 5 class Circle(Shape): def area(self): return 3.14 * (3**2) -
L — Liskov Substitution Principle (Принцип подстановки Барбары Лисков) Объекты производных классов должны иметь возможность заменять объекты базовых классов, не нарушая работу программы.
class Bird: def fly(self): print("I can fly") class Duck(Bird): pass # Утка - птица, она летает. OK. # Нарушение LSP: страус - птица, но не летает class Ostrich(Bird): def fly(self): raise Exception("I can't fly") -
I — Interface Segregation Principle (Принцип разделения интерфейса) Клиенты не должны зависеть от интерфейсов, которые они не используют. Лучше иметь много маленьких, специфичных интерфейсов, чем один большой и общий.
class Worker(ABC): @abstractmethod def work(self): pass class Eater(ABC): @abstractmethod def eat(self): pass # Класс реализует только те интерфейсы, которые ему нужны class Human(Worker, Eater): def work(self): pass def eat(self): pass class Robot(Worker): def work(self): pass -
D — Dependency Inversion Principle (Принцип инверсии зависимостей) Модули верхнего уровня не должны зависеть от модулей нижнего уровня. И те, и другие должны зависеть от абстракций. Абстракции не должны зависеть от деталей.
class Switchable(ABC): # Абстракция @abstractmethod def turn_on(self): pass class LightBulb(Switchable): # Низкоуровневый модуль def turn_on(self): print("LightBulb: on") class Switch: # Высокоуровневый модуль def __init__(self, device: Switchable): self.device = device def operate(self): self.device.turn_on() # Switch зависит от абстракции Switchable, а не от конкретного LightBulb bulb = LightBulb() switch = Switch(bulb) switch.operate()