В основных навыках для гибкого разработчика, в потребностях и интерфейсе возможностей, глава 12, я пытаюсь понять основное решение, предложенное для задачи применения ЗАКОНА DEMETER, которое автор упомянул к концу этого глава.
Чтобы сделать рассказ коротким.
Начнем со следующего случая:
public class City {
public string name{};
public City twinCity{};
public Street[] streets{};
}
public class Street {
public string name{};
public House[] houses{};
}
public class House {
public int number{};
public Color color{};
}
Если автор утверждает, что:
Модели, подобные этому, побуждают нас раскрывать, а не инкапсулировать. Если ваш код имеет ссылку на конкретный экземпляр города, скажем, тот, который карты Сиэтла, и вы хотели, чтобы цвет дома в 1374 году Улица, то вы можете сделать что-то вроде следующего:
public Foo() {
Color c = Seattle.streets()["Main"].
houses()[1374].
color();
}
Проблема, если это делается как общая практика, заключается в том, что система везде разрабатывает зависимости, а изменение любой части этого модель может влиять вверх и вниз по цепочке этих зависимостей. Вот где Закон Деметры, в котором говорится: "Не разговаривай с чужих". Это формализовано в объектных системах, как Закон Деметры для функций/методов. Способ M объекта O может вызывать методы следующих видов объектов:
- Os
- Параметры Ms
- Любые объекты, созданные в M
- Объекты прямого компонента Os
- Любые глобальные переменные, доступные O
и предположим, что при применении ЗАКОНА DEMTER мы должны стремиться к чему-то вроде
public Foo() {
Color c = Seattle.ColorOfHouseInStreet("Main",1374);
}
и быстро предупреждает следующее:
Хотя это, казалось бы, было бы разумной политикой изначально, она может быстро выйти из-под контроля, поскольку можно ожидать, что интерфейс любого объекта чтобы обеспечить буквально все, к чему это относится. Эти интерфейсы имеют тенденцию раздувается со временем, и на самом деле, похоже, почти нет конца количество общедоступных методов, которые может оказать конкретное стекло.
Затем после быстрого обхода объяснения проблемы связи и зависимости, где он упоминает о важности разделения клиента и его обслуживания интерфейсом службы и, возможно, кроме того, отделяя клиентский интерфейс "потребности" от "интерфейс возможностей обслуживания" с использованием адаптера как нечто идеальное, но не обязательно практическое;
он предлагает, чтобы исправить эту проблему, мы могли бы объединить ЗАКОН DEMETER и разделение потребностей/возможностей с использованием шаблона фасада, как показано ниже:
Из исходной зависимости
При применении закона деметатора и разделения интерфейса потребностей/возможностей мы должны сначала получить:
Но, учитывая, что это просто непрактично, особенно с точки зрения насмешек, мы могли бы сделать что-то более простое с фасадом:
Проблема в том, что я просто не вижу, как это точно решает проблему не нарушать Закон Деметры. Я думаю, что он поддерживает закон между первоначальным клиентом и оригинальным сервисом. Но это просто переместило нарушение в FACADE.