Коротко: DRY, KISS и YAGNI помогают не утонуть в сложности, но их часто доводят до абсурда; главное — понимать, когда они работают, а когда вредят.
DRY, KISS и YAGNI — три принципа, которые помогают не утонуть в сложности. Но их часто понимают буквально и доводят до абсурда. Коротко: не дублируй знание (DRY), держи решение простым (KISS), не делай того, что пока не нужно (YAGNI). Главное — понимать, когда они работают, а когда вредят.
DRY — Don't Repeat Yourself
Принцип: каждое знание в системе должно иметь одно авторитетное представление. Дублирование логики — это риск: поправил в одном месте, забыл в трёх других.
// плохо: правило расчёта скидки размазано по коду
$price1 = $sum - $sum * 0.1;
$price2 = $sum - $sum * 0.1;
// лучше: одно место правды
final class Discount {
public function apply(float $sum): float {
return $sum - $sum * self::RATE;
}
}
Когда DRY вредит
Опасность — преждевременное обобщение. Две строки кода выглядят одинаково, но это совпадение, а не общее знание. Если их «объединить», при первом же расхождении требований получится монстр с флагами if ($type === 'a'). Правило: дублирование кода — не то же самое, что дублирование знания. Сначала дублируйте, обобщайте, когда третий случай подтвердит общее правило (rule of three).
KISS — Keep It Simple, Stupid
Самое простое решение, которое работает, обычно лучшее: его легче читать, тестировать и менять. Сложность должна быть оправдана реальной потребностью, а не «вдруг пригодится».
// переусложнено: фабрика ради одного типа
$strategy = $factory->create($config)->resolve()->build();
// проще и понятнее
$result = (new TaxCalculator())->calculate($order);
Когда KISS вредит
«Просто» не значит «примитивно и без архитектуры». Если задача сложная по сути (платежи, конкурентность), упрощение до спагетти в одном методе — это не KISS, а технический долг. KISS — про отсутствие лишней сложности, а не про отказ от необходимой.
YAGNI — You Aren't Gonna Need It
Не реализуйте функциональность «на будущее», пока она реально не понадобилась. Код, написанный «на всякий случай», чаще всего: не используется, мешает рефакторингу и содержит баги, которые никто не ловит.
// YAGNI-нарушение: 5 уровней абстракции под единственного провайдера
interface PaymentGatewayFactoryProviderInterface { /* ... */ }
// по YAGNI: один класс, пока провайдер один; абстракцию добавим, когда появится второй
Когда YAGNI вредит
YAGNI — не повод игнорировать заведомо известные требования. Если в роадмапе через месяц мультивалютность, закладывать её точку расширения разумно. YAGNI против спекулятивных фич, а не против разумного проектирования под известное будущее.
Как они уживаются вместе
Принципы иногда тянут в разные стороны, и это нормально — они инструменты, а не догмы:
- YAGNI говорит «не абстрагируй заранее», DRY — «не дублируй». Баланс: дублируйте, пока не увидели настоящее общее правило (rule of three), тогда устраняйте дублирование.
- KISS подсказывает, какое из решений выбрать: самое простое из работающих.
Практический чек-лист
- Дублирование — это одно знание или случайное совпадение? Если совпадение — не объединяйте.
- Эта абстракция решает сегодняшнюю проблему? Если «на будущее» и будущее неточное — YAGNI.
- Можно ли проще без потери ясности и корректности? Если да — KISS.
- Сложность здесь сущностная (от задачи) или случайная (от кода)? Убираем только случайную.
Эти принципы — про здравый смысл и баланс, а не про слепое следование. Если хотите разобрать архитектуру конкретного проекта на предмет «где переусложнили, а где недо-» — это хорошая тема для консультации.


Комментарии