← Все вопросы

Что такое принцип единственной ответственности (Single Responsibility) и как его применять?

Задан 24 месяца назад427 просмотров2 ответа
8

Первая буква в SOLID — SRP, принцип единственной ответственности. Формулировка «у класса должна быть одна причина для изменения» мне не очень понятна. Что считать «одной причиной»? Как на практике понять, что класс делает слишком много, и как его правильно разделить? Желательно на примере C#.

2 ответа

14
✓ Принятый ответ — помог автору

SRP (Single Responsibility Principle) — у модуля должна быть только одна причина для изменения. Ключевое слово здесь — «причина для изменения», а не «делает одно действие». Причина = заинтересованная сторона (актор), которая может потребовать изменений.

Классический пример нарушения — класс, который смешивает бизнес-логику, хранение и форматирование:

// Нарушение SRP: три разные причины для изменения
public class Invoice
{
    public decimal Total { get; set; }

    // 1) причина: меняется бизнес-правило расчёта
    public decimal CalculateTax() => Total * 0.2m;

    // 2) причина: меняется способ хранения
    public void SaveToFile(string path) { /* запись в файл */ }

    // 3) причина: меняется формат вывода
    public string RenderHtml() => $"<b>{Total}</b>";
}

Здесь бухгалтерия отвечает за налог, DBA — за хранение, а отдел маркетинга — за вёрстку. Три разных актора → три причины → разбиваем:

public class Invoice
{
    public decimal Total { get; set; }
}

public class TaxCalculator
{
    public decimal CalculateTax(Invoice invoice) => invoice.Total * 0.2m;
}

public class InvoiceRepository
{
    public void Save(Invoice invoice, string path) { /* запись */ }
}

public class InvoiceHtmlPresenter
{
    public string Render(Invoice invoice) => $"<b>{invoice.Total}</b>";
}

Как понять, что пора делить:

  • В описании класса появляется союз «и» («считает налог и сохраняет и рендерит»).
  • Класс меняется по запросам разных команд/отделов.
  • При правке одного метода ломаются тесты совсем другой функциональности.

Не путайте SRP с «один метод на класс» — это перебор. Класс может иметь много методов, если все они обслуживают одну ответственность.

5

Мне помогает мысленный тест: «Кто придёт ко мне с просьбой изменить этот класс?». Если потенциальных заказчиков двое и более — класс, скорее всего, нарушает SRP.

Ещё полезно смотреть на причины изменения с точки зрения слоёв: логика расчёта, ввод-вывод (БД/файлы/сеть) и представление почти всегда меняются по разным причинам и в разном темпе. Поэтому их и держат раздельно.

Но осторожно: дробить до бесконечности тоже плохо. Если две вещи всегда меняются вместе — пусть живут в одном классе.

Ваш ответ

Войдите, чтобы ответить на вопрос.
Поддержать проект