Один з інструментів DRY або єдиний дозволений copy/paste
Багато технічних співбесід показують, що розробники або не використовують трейти зовсім, або роблять це без розуміння практичного сенсу. Часто їх просто бояться — мовляв, поведінка трейту може бути неочевидною або ж спричинити баги, які складно відслідкувати.
Але суть в тому, що трейти — це всього лише інструмент, який треба застосовувати там, де від нього буде найбільше користі.
І найчастіше це не сервісні класи (хоча є ситуації, коли і тут вони будуть доречні), а обʼєктні структури: сутності, DTO, VO, event'и тощо. Саме там трейти — ідеальний інструмент для роздачі типової поведінки без зайвої ієрархії і порушення DRY.
Гарний приклад — бібліотека knplabs/doctrine-behaviors. Своїми інтерфейсами вона надає вашим сутностям типову поведінку (наприклад, Timestampable, SoftDeletable, Translatable тощо), але замість того, щоб реалізовувати інтерфейси в кожному класі, ви просто додаєте реалізацію — підключаючи відповідний трейт. Ніяких милиць у вигляді абстрактних батьківських класів, які «надають поведінку», тільки чистий код, лаконічний use TraitName і ніякого copy/paste.
Хоча справедливості заради варто визнати: copy/paste все одно відбувається, просто не в коді, а на рівні інтерпретатора.
Висновок
Трейти — це спосіб дотримуватися DRY і не лізти в спадкування там, де воно недоречне. Це дуже потужний інструмент, якщо використовувати його правильно і там, де треба.
Порада: як зробити, щоб трейт гарантовано працював в будь-якому класі без помилок?
Ніколи не звертайтесь всередині трейту до властивостей або методів класу, в який трейт підключено. Трейт не знає, куди його вставлять — і тому контекст будь-якого трейту має бути самообмеженим. Це головна умова, щоб ваш трейт працював стабільно і не викликав помилки.
Погано:
trait BadTrait {
public function generateUniqueId(): void
{
$this->id = uniqid();
}
}
Добре:
trait GoodTrait {
protected string $id;
public function generateUniqueId(): void
{
$this->id = uniqid();
}
}
Вперше опубліковано в Telegram-каналі «Створений щоб помирати» 26.06.2025.