Skip to content

Latest commit

 

History

History
83 lines (62 loc) · 2.94 KB

File metadata and controls

83 lines (62 loc) · 2.94 KB

Говори, а не спрашивай

В предыдущем примере где мы разбирали длинный метод, проблема в том, что нет действующего лица. Кот написан в процедурном стиле знакомым со школьной скамьи или университета, когда программа описывается серией последовательных инструкций: «сделай 1, сделай 2, сделай 3».

public function handle() 
{
    $this->load();
    $this->validate();
    $this->transform();
    $this->generateReport();
    // И ещё десяток шагов...
    $this->sendMail();
}

Что бы такого не было У него должно быть действующее лицо - объект. Но сразу же встает важный выбор: кто должен принимать решения? И в какой форме объекты должны взаимодействовать друг с другом?

Это один из важных принципов, который помогает сделать код объектов лаконичными, звучит так:

"Не спрашивай объект о его данных, чтобы принять решение — скажи объекту, что делать."

Что не так со "спрашивающим" кодом?

Когда ты спрашиваешь у объекта какие-то данные, а затем на основе этих данных принимаешь решение — ты, по сути, берёшь на себя его ответственность.

Вот пример:

// Плохо ❌
if ($invoice->isPaid()) {
    $this->sendThankYouEmail($invoice->user);
}

Выглядит безобидно. Но ответственность размыта. Кто решает, нужно ли отправить письмо? Внешний код. А должен — сам счёт.

Скажи объекту, что ты хочешь, а не спрашивай у него, что он знает.

// Хорошо ✅
$invoice->sendThankYouIfPaid();
// Плохо ❌
if ($user->isAdmin() || $user->hasRole('manager')) {
    $invoice->send();
}
// Хорошо ✅
if ($user->canSend($invoice)) {
    $invoice->send();
}

Теперь вся логика прав находится в объекте пользователя. У тебя появляется единая точка принятия решений — легко тестировать и изменять.


Изменение состояния

// Плохо ❌
if (! $invoice->isEmpty()) {
    $invoice->checkout();
}
// Хорошо ✅
$invoice->checkout(); // пусть сам решает, можно ли оформляться