Что такое принципы SOLID и зачем они нужны?
Постоянно слышу про SOLID на собеседованиях и в статьях по ООП. Понимаю, что это какие-то принципы проектирования, но что именно под ними скрывается? Можете дать общий обзор всех пяти принципов простыми словами и объяснить, какую проблему они решают?
2 ответа
SOLID — это пять принципов объектно-ориентированного проектирования, которые сформулировал Роберт Мартин (Uncle Bob). Их цель — сделать код понятным, гибким и устойчивым к изменениям, чтобы новые требования не ломали половину системы.
Аббревиатура расшифровывается так:
- S — Single Responsibility Principle (принцип единственной ответственности). У класса должна быть только одна причина для изменения. Класс отвечает за одну задачу.
- O — Open/Closed Principle (принцип открытости/закрытости). Сущности открыты для расширения, но закрыты для модификации. Добавляем поведение через новый код, а не правкой старого.
- L — Liskov Substitution Principle (принцип подстановки Барбары Лисков). Объект базового класса можно заменить объектом наследника без поломки программы.
- I — Interface Segregation Principle (принцип разделения интерфейсов). Лучше много узких интерфейсов, чем один «толстый». Клиент не должен зависеть от методов, которые не использует.
- D — Dependency Inversion Principle (принцип инверсии зависимостей). Зависимости строятся на абстракциях, а не на конкретных реализациях.
Маленький пример нарушения SRP и его исправления:
// Плохо: класс и считает зарплату, и сохраняет в БД, и шлёт отчёт
public class Employee
{
public decimal CalculatePay() { /* ... */ return 0; }
public void SaveToDatabase() { /* ... */ }
public void SendReport() { /* ... */ }
}
// Лучше: каждая ответственность в своём классе
public class PayCalculator { public decimal Calculate(Employee e) { return 0; } }
public class EmployeeRepository { public void Save(Employee e) { } }
public class ReportSender { public void Send(Employee e) { } }
Зачем это всё? SOLID снижает связанность (coupling) и повышает связность (cohesion). На практике это означает: легче писать тесты, проще менять одну часть, не задевая другие, и проще переиспользовать код. Не нужно фанатично применять все принципы везде — это инструмент, а не догма.
Если совсем коротко, то SOLID — это про то, как разбивать систему на части так, чтобы изменения были локальными.
Моё рабочее правило для каждого принципа:
- S — «один класс — одна работа».
- O — «дописывай, а не переписывай».
- L — «наследник не должен врать про базовый тип».
- I — «не заставляй реализовывать ненужное».
- D — «зависим от интерфейсов, а не от классов».
Главное — не превращать это в карго-культ. Я видел проекты, где ради «чистого SOLID» плодили десятки интерфейсов с одной реализацией. Принципы должны облегчать жизнь, а не усложнять.