Словарик философствующего информатика/Несвязность и закон Деметры: различия между версиями

Содержимое удалено Содержимое добавлено
м <source> -> <syntaxhighlight> (phab:T237267)
 
Строка 6:
 
Что произойдёт, если появятся модули, которые знают друг о друге? В принципе ничего — вы не должны впадать в паранойю, как шпионы или диссиденты. Однако, следует внимательно следить за тем, со сколькими другими модулями вы взаимодействуете. Это важнее, чем то, каким образом вы пришли к взаимодействию с ними. Предположим, вы занимаетесь перепланировкой своего дома или строите дом с нуля. Обычная организация включает «генерального подрядчика». Вы нанимаете подрядчика для выполнения работ, но подрядчик выполняет или не выполняет эти работы сам; работа может быть предложена разнообразным субподрядчикам. Но, будучи клиентом, вы не имеете дело с субподрядчиками напрямую, генеральный подрядчик берет от вашего имени эту головную боль на себя. Нам бы хотелось воспользоваться той же моделью в программном обеспечении. Когда мы запрашиваем у объекта определённую услугу, то мы хотим, чтобы эта услуга оказывалась от нашего имени. Мы не хотим, чтобы данный объект предоставлял нам еще какой-то объект, подготовленный третьей стороной, с которым нам придется иметь дело для получения необходимой услуги. Предположим, что вы пишете класс, генерирующий график по данным научного прибора. Научные приборы рассеяны по всему миру, каждый объект-прибор содержит объект-местоположение, который дает информацию о его расположении и часовом поясе. Вы хотите, чтобы ваши пользователи могли выбирать прибор и наносить его данные на график с отметкой часового пояса. Вы можете записать
<sourcesyntaxhighlight lang="cpp">public void plotDate(Date aDate, Selection aSelection) {
TimeZone tz = aSelection.getRecorder().getLocation().getTimeZone();
...
}</sourcesyntaxhighlight>
Но теперь подпрограмма построения графика без особой надобности связана с тремя классами — <code>Selection</code>, <code>Recorder</code> и <code>Location</code>. Этот стиль программирования резко увеличивает число классов, от которых зависит наш класс. Почему это плохо? Потому что при этом увеличивается риск того, что внесение несвязанного изменения в другой части системы затронет вашу программу. Например, если сотрудник по имени Фред вносит изменение в класс Location так, что он непосредственно более не содержит TimeZone, то вам придется внести изменения и в свою программу. Вместо того, чтобы продираться через иерархию самостоятельно, просто спросите напрямую о том, что вам нужно:
<sourcesyntaxhighlight lang="cpp">public void plotDate(Date aDate, TimeZone aTz) { ... }
plotDate(someDate, someSelection.getTimeZone());</sourcesyntaxhighlight>
Мы добавили метод к классу <code>Selection</code>, чтобы получить часовой пояс от своего имени; подпрограмме построения графика неважно, передается ли часовой пояс непосредственно из класса <code>Recorder</code>, от некоего объекта, содержащегося в <code>Recorder</code>, или же класс <code>Selection</code> сам составляет другой часовой пояс. В свою очередь, подпрограмма выбора должна запросить прибор о его часовом поясе, оставив прибору право получить его значение из содержащегося в нем объекта <code>Location</code>. Непосредственное пересечение отношений между объектами может быстро привести к комбинаторному взрыву отношений зависимости. Признаки этого явления можно наблюдать в ряде случаев:
# В крупномасштабных проектах на языках С или C++ , где команда компоновки процедуры тестирования длиннее, чем сама программа тестирования.