DRY, KISS, YAGNI, GRASP, Law of Demeter
↑ 8.1 Принципы и паттерны проектирования в C♯ · ← Предыдущая · → Следующая
Зачем это на собесе
Общие принципы разработки: важно знать и границы их применимости.
Объяснение
| Принцип | Формулировка | Ловушка |
|---|---|---|
| DRY | не дублируй знание | преждевременная абстракция ради «похожего» кода |
| KISS | делай проще | «слишком просто» без учёта требований |
| YAGNI | не делай то, что не нужно сейчас | игнорирование очевидных ближайших требований |
| Law of Demeter | говори только с непосредственными соседями: a.b.c.d() — плохо | цепочки вызовов, знание внутреннего устройства |
| Composition over inheritance | предпочитай композицию | глубокие иерархии |
| Separation of Concerns | разделяй ответственность | |
| Fail fast | обнаруживай ошибки как можно раньше | |
| Principle of least astonishment | код ведёт себя ожидаемо | |
| Tell, Don’t Ask | вызывай поведение, а не запрашивай данные и решай снаружи | анемичная модель |
GRASP — принципы распределения ответственности между объектами:
| Шаблон | Смысл |
|---|---|
| Information Expert | ответственность у того, кто владеет данными |
| Creator | создаёт объект тот, кто его содержит/использует |
| Controller | обработку системного события принимает координатор |
| Low Coupling / High Cohesion | слабая связанность, высокая связность |
| Polymorphism | различия по типам — через полиморфизм |
| Pure Fabrication | искусственный класс для чистоты дизайна (репозиторий) |
| Indirection | посредник для развязки |
| Protected Variations | скрывайте точки изменения за интерфейсом |
// Tell, Don't Ask
if (order.Status == Status.Paid && order.Items.All(i => i.InStock)) order.Status = Status.Shipped; // логика снаружи
order.Ship(); // логика внутри агрегатаDRY относится к знанию (бизнес-правилу), а не к текстуальному сходству кода: два одинаковых фрагмента с разной причиной изменения дублировать допустимо.
Нюансы и подводные камни
- «Rule of three»: абстрагируйте после третьего повторения.
- Слепой DRY создаёт связанность между несвязанными модулями.
- Демeтер не про «одну точку»: fluent API и LINQ допустимы.
- YAGNI не отменяет продумывание архитектуры.
Практика
- Найдите дублирование знания (одинаковое правило в двух местах).
- Перепишите цепочку
a.B.C.D()в метод у владельца данных. - Проверьте, где абстракция появилась «на всякий случай».
Вопросы с ответами
Когда дублирование лучше абстракции?
Когда фрагменты похожи случайно и меняются по разным причинам.
Что такое Tell, Don't Ask?
Вызывать методы объекта с поведением, а не запрашивать его данные и принимать решения снаружи.
Связанные темы
- [[be-8-1-1-solid-v-csharp-s-primerami|SOLID в C# с примерами]]
- Порождающие паттерны: Factory Method, Abstract Factory, Builder, Singleton (фабрика отчётов)