Перейти к основному содержимому

Одна причина для изменения

Принцип единственной ответственности — это буква S в SOLID, пяти правилах проектирования кода, который остаётся легко изменяемым. Он говорит: у класса должна быть одна задача — а значит, и только одна причина для изменения.

Когда один класс сохраняет заказы и отправляет письма, он меняется и при смене хранилища, и при смене текста письма. Две задачи, две причины, вдвое больше риска сломать одно, пока правишь другое.

В PHP это правило относится к классам, их методам и целым файлам: каждый из них должен быть сосредоточен на одной задаче.


Слишком много задач в одном классе

Этот обработчик заказов работает — но он сохраняет заказ, составляет текст подтверждения и «отправляет» его, всё в одном методе. Протестировать только текст письма невозможно, а чтобы переиспользовать часть с хранением, придётся тащить за собой и код отправки письма.

Один класс, который делает всё

process() смешивает две задачи: хранение и уведомление. Любое изменение в любой из них означает правку — и повторное тестирование — этого же класса.

Prompt
Напишите PHP-скрипт с классом OrderProcessor, метод process которого выполняет сразу две задачи: печатает, что заказ сохранён в хранилище, и печатает текст письма-подтверждения для клиента. Обработайте один заказ, чтобы показать, что это работает, — как отправную точку для разговора о принципе единственной ответственности.
Вывод: PHP-скрипт

Одна задача на класс

Решение: по одному классу на задачу. OrderStore только сохраняет, EmailSender только отправляет. Небольшая функция их связывает.

Вывод тот же — но теперь каждую часть можно менять, тестировать и переиспользовать отдельно.

Разделение на два класса

То же поведение, но разделённое: хранилище ничего не знает о письмах, отправитель ничего не знает о хранении. Функция processOrder просто соединяет их.

Prompt
Разделите обработку заказа на два PHP-класса, у каждого — одна задача: OrderStore с методом save, который печатает шаг сохранения, и EmailSender с методом sendConfirmation, который печатает письмо. Добавьте функцию processOrder, вызывающую оба метода. Обработайте один заказ и покажите тот же вывод, что и раньше.
Вывод: PHP-скрипт

Выигрыш: переиспользование без страха

Поскольку отправитель — отдельный класс, он отправляет и уведомление об отправке — без участия кода хранения. А хранилище архивирует заказ, не составляя ни одного письма. Каждый класс вырос внутри своей одной задачи.

Prompt
Используя разделённые PHP-классы OrderStore и EmailSender, покажите выигрыш от единственной ответственности: отправьте уведомление об отправке тем же отправителем, не касаясь хранения, и заархивируйте заказ через store, не отправляя ни одного письма. Печатайте каждое действие.
Вывод: PHP-скрипт