Что такое закон Деметры?
Смежные принципы проектирования
Закон Деметры (принцип минимального знания): метод общается только с «ближайшими друзьями», а не со знакомыми своих знакомых.
Формально
Метод m объекта O вызывает методы только у:
- самого
Oи его полей; - параметров
m; - объектов, созданных внутри
m.
Сформулирован в 1987 году в Северо-Восточном университете, в проекте Demeter (Ян Холланд, Карл Либерхерр).
Нарушение
order.getCustomer().getWallet().getBalance() >= order.total — код знает устройство Customer и Wallet. Переезд баланса в отдельный сервис ломает все такие цепочки — их называют «крушением поезда» (train wreck). Лучше передать покупателя параметром и спросить customer.canPay(order.total): навигацию по внутренностям знает только владелец данных.
Чем это не является
- Не «правило одной точки»: fluent-интерфейсы и билдеры (
query.where().orderBy()) возвращают объект того же уровня — нарушения нет. - Цепочки по структурам данных (
config.db.host, DTO) иarray.map().filter()тоже не про Деметру: у данных нет поведения, которое стоит прятать.
Цена
Слепое следование плодит методы-прокладки getCustomerWalletBalance(). Если их много, ответственность, скорее всего, лежит не в том классе.
Коротко для собеседования
Объект обращается только к своим полям, параметрам и тому, что создал сам, а не ходит по цепочкам чужих внутренностей. Вместо a.getB().getC().value просят владельца данных выполнить действие; при этом fluent-API и доступ к полям DTO нарушением не считаются.