Один з інструментів DRY або єдиний дозволений copy/paste

← Один з інструментів DRY або єдиний дозволений copy/paste

Ashterix

docs: English JsonRpcBundle docs, REST and MCP Bundle sections, package cards

uk/articles/from-tg/php/traits.md новий файл +49 −0

1 + # Один з інструментів DRY або єдиний дозволений copy/paste
2 +
3 + Багато технічних співбесід показують, що розробники або не використовують трейти зовсім, або роблять це без розуміння практичного сенсу. Часто їх просто бояться — мовляв, поведінка трейту може бути неочевидною або ж спричинити баги, які складно відслідкувати.
4 +
5 + Але суть в тому, що трейти — це всього лише інструмент, який треба застосовувати там, де від нього буде найбільше користі.
6 +
7 + І найчастіше це не сервісні класи (хоча є ситуації, коли і тут вони будуть доречні), а обʼєктні структури: сутності, DTO, VO, event'и тощо. Саме там трейти — ідеальний інструмент для роздачі типової поведінки без зайвої ієрархії і порушення `DRY`.
8 +
9 + Гарний приклад — бібліотека [knplabs/doctrine-behaviors](https://packagist.org/packages/ufo-tech/doctrine-behaviors). Своїми інтерфейсами вона надає вашим сутностям типову поведінку (наприклад, Timestampable, SoftDeletable, Translatable тощо), але замість того, щоб реалізовувати інтерфейси в кожному класі, ви просто додаєте реалізацію — підключаючи відповідний трейт. Ніяких милиць у вигляді абстрактних батьківських класів, які «надають поведінку», тільки чистий код, лаконічний `use TraitName` і ніякого `copy/paste`.
10 +
11 + Хоча справедливості заради варто визнати: `copy/paste` все одно відбувається, просто не в коді, а на рівні інтерпретатора.
12 +
13 + ## Висновок
14 +
15 + > Трейти — це спосіб дотримуватися DRY і не лізти в спадкування там, де воно недоречне. Це дуже потужний інструмент, якщо використовувати його правильно і там, де треба.
16 +
17 + ## Порада: як зробити, щоб трейт гарантовано працював в будь-якому класі без помилок?
18 +
19 + :::tip
20 + Ніколи не звертайтесь всередині трейту до властивостей або методів класу, в який трейт підключено. Трейт не знає, куди його вставлять — і тому контекст будь-якого трейту має бути самообмеженим. Це головна умова, щоб ваш трейт працював стабільно і не викликав помилки.
21 + :::
22 +
23 + Погано:
24 +
25 + ```php
26 + trait BadTrait {
27 + public function generateUniqueId(): void
28 + {
29 + $this->id = uniqid();
30 + }
31 + }
32 + ```
33 +
34 + Добре:
35 +
36 + ```php
37 + trait GoodTrait {
38 + protected string $id;
39 +
40 + public function generateUniqueId(): void
41 + {
42 + $this->id = uniqid();
43 + }
44 + }
45 + ```
46 +
47 + ---
48 +
49 + *Вперше опубліковано в Telegram-каналі [«Створений щоб помирати»](https://t.me/php_while_true/49) 26.06.2025.*