# 14. Общие практики (DRY, KISS, YAGNI, Закон Деметры)
[← Оглавление](./index.md)
---
## DRY — не дублируйте код (как минимум, в одном модуле)
**ПЛОХО — ОДНА И ТА ЖЕ ЛОГИКА В ДВУХ МЕСТАХ**
```php
// В компоненте A:
$lead = \Bitrix\Crm\LeadTable::getByPrimary($id)->fetchObject();
if (!$lead) {
throw new \Exception('Лид не найден');
}
// В компоненте B:
$lead = \Bitrix\Crm\LeadTable::getByPrimary($id)->fetchObject();
if (!$lead) {
throw new \Exception('Лид не найден');
}
```
**ХОРОШО — ОБЩАЯ ЛОГИКА В LEADPROVIDER**
```php
class LeadProvider {
public function getById(int $id): \Bitrix\Crm\Item {
$lead = \Bitrix\Crm\LeadTable::getByPrimary($id)->fetchObject();
if (!$lead) {
throw new \Bitrix\Main\ObjectNotFoundException("Лид #{$id} не найден");
}
return $lead;
}
}
```
---
## Закон Деметры — не разговаривай с незнакомцами
**ПЛОХО — ЦЕПОЧКА ЧЕРЕЗ ГРАНИЦЫ ОБЪЕКТОВ**
```php
$city = $deal->getContact()->getCompany()->getAddress()->getCity();
```
**ХОРОШО — ДЕЛЕГИРУЮЩИЙ МЕТОД В DEAL**
```php
// Вызов:
$city = $deal->getContactCompanyCity();
// Реализация внутри класса Deal:
public function getContactCompanyCity(): ?string {
return $this->getContact()?->getCompany()?->getCity();
}
```
### Практическое правило
> Считай точки в цепочке. **Больше одной точки** — повод задуматься.
`$a->b()` — ок
`$a->b()->c()` — уже подозрительно
`$a->b()->c()->d()` — точно нарушение
*(Исключение: Fluent Interface / Builder, где `$query->select()->where()->limit()` — это один объект, возвращающий сам себя)*
---
## KISS — простое решение лучше сложного
Не усложняйте без необходимости. Если задачу можно решить тремя строками — не пишите тридцать.
---
## YAGNI — не добавляйте функциональность «на будущее»
Реализуйте только то, что требуется прямо сейчас. Код, написанный «на перспективу», часто не используется и засоряет проект.