Gymterview
middle

Как принципы SOLID применяются в контексте архитектуры

SOLID — пять принципов объектно-ориентированного проектирования, которые применимы не только на уровне классов, но и на уровне модулей и компонентов системы.

S — Single Responsibility Principle (Принцип единственной ответственности)

На уровне архитектуры: каждый модуль или сервис отвечает за одну бизнес-область.

Пример
// Плохо: один сервис делает всё
@Service
public class MegaService {
    public void createPayment(...) { }
    public void generateReport(...) { }
    public void sendNotification(...) { }
}

// Хорошо: разделение ответственности
@Service public class PaymentService { ... }
@Service public class ReportService { ... }
@Service public class NotificationService { ... }

В микросервисной архитектуре SRP определяет границы сервисов: сервис платежей, сервис уведомлений, сервис отчётов.

O — Open/Closed Principle (Принцип открытости/закрытости)

На уровне архитектуры: система открыта для расширения, но закрыта для модификации. Новые возможности добавляются через новые модули, а не через изменение существующих.

Пример
// Стратегия расчёта комиссии — расширяем через новую реализацию
public interface CommissionStrategy {
    Money calculate(Payment payment);
}

@Component public class StandardCommission implements CommissionStrategy { ... }
@Component public class VipCommission implements CommissionStrategy { ... }
// Новый тип — просто добавляем класс, не меняя существующий код
@Component public class CorporateCommission implements CommissionStrategy { ... }

L — Liskov Substitution Principle (Принцип подстановки Барбары Лисков)

На уровне архитектуры: любой компонент, реализующий интерфейс (порт), может быть заменён другой реализацией без нарушения работы системы. Например, замена PostgreSQL-репозитория на MongoDB-репозиторий не должна ломать бизнес-логику.

I — Interface Segregation Principle (Принцип разделения интерфейсов)

На уровне архитектуры: API модулей и сервисов должны быть узкоспециализированными. Клиент не должен зависеть от методов, которые он не использует.

Пример
// Плохо: один «жирный» интерфейс
public interface AccountOperations {
    Account findById(Long id);
    void transfer(Long from, Long to, BigDecimal amount);
    Report generateMonthlyReport(Long accountId);
    void blockAccount(Long id);
}

// Хорошо: разделённые интерфейсы
public interface AccountQueryPort { Account findById(Long id); }
public interface TransferPort { void transfer(TransferCommand cmd); }
public interface AccountAdminPort { void blockAccount(Long id); }

D — Dependency Inversion Principle (Принцип инверсии зависимостей)

На уровне архитектуры: это фундамент гексагональной и чистой архитектуры. Модули высокого уровня (бизнес-логика) не зависят от модулей низкого уровня (инфраструктура). Оба зависят от абстракций.

Пример
Без инверсии:               С инверсией:
Service → JpaRepository      Service → Repository (интерфейс)
                                              ↑
                              JpaRepository реализует Repository

На собеседовании: Интервьюер хочет услышать примеры применения SOLID именно на архитектурном уровне (модули, сервисы), а не только на уровне классов. Частая ошибка — пересказывать определения принципов, не показывая, как они влияют на структуру системы.