Предположим, у нас есть следующий класс Boy
, который пытается договориться о свидании с Girl
, анализируя ее расписание (пример на Java):
public class Boy {
public boolean tryArrangeDate(Girl girl, Date time) {
boolean success = true;
for (GirlRoutine routine : girl.getSchedule()) {
if (routine.happensAt(time)) {
success = false;
break;
}
}
return success;
}
}
Метод Boy.tryArrangeDate()
явно нарушает Закон Деметры из-за вызова routine.happensAt()
. Один из способов решить эту проблему — перенести анализ расписания непосредственно в Girl
и избежать зависимости от GirlRoutine
. Вероятно, это было бы одним из лучших решений в данном случае. RFC для класса Boy
будет сокращен.
Но предположим, что мы выбираем другое направление для устранения нарушений Закона Деметры и меняем код таким образом:
public class Boy {
public boolean tryArrangeDate(Girl girl, Date time) {
return isFree(girl.getSchedule(), time);
}
private boolean isFree(List<GirlRoutine> schedule, Date time) {
boolean free = true;
for (GirlRoutine routine : schedule) {
if (happensAt(routine, time)) {
free = false;
break;
}
}
return free;
}
private boolean happensAt(GirlRoutine routine, Date time) {
return routine.happensAt(time);
}
}
Добавлены два частных метода, которые просто делегируют вызовы Girl
и ее расписанию/процедурам.
Каждый метод, взятый по отдельности, кажется, не нарушает Закон Деметры (для простоты будем рассматривать извлечение элемента из коллекции как примитивную операцию без вызова метода). Но в целом мы не уменьшили RFC для этого класса, не улучшили связность и фактически увеличили WMC. Принцип Расскажи, не спрашивай не сохраняется. Итак, закон Деметры удовлетворен, но дизайн все еще хлипкий.
Вопрос: Правда ли, что (формально) второй фрагмент кода не нарушает Закон Деметры?
ПРИМЕЧАНИЕ. Цель вопроса НЕ в том, чтобы найти альтернативные решения, а в том, чтобы подтвердить/опровергнуть, что решение соответствует Закону Деметры
Boy
что-то меняет. Вы воспринимаете вещи слишком буквально. Если (и это теоретически, если) вы хотите улучшить эту сторону вещей, вы должны переместить методisFree
в классGirl
, чтобыtryArrangeDate
сталreturn girl.isFree(date)
, как вы упомянули. - person Jon   schedule 07.09.2013isFree
в классGirl
- это нормальный способ обработки вещей. Это мне понятно и это описано в формулировке вопроса. Все, что я хочу, это проверить, нарушает ли второй фрагмент кода Закон Деметры или нет, вот и все! - person Volodymyr Tsukur   schedule 07.09.2013