ConstructiCat Logo
CodeBust.
Browse section ▾

Действие на расстоянии (программирование).

Антипаттерн

Действие на расстоянии — это антипаттерн в информатике, при котором поведение в одной части программы резко меняется из-за трудно- или невозможно идентифицируемых операций в другой её части.

Способ избежать проблем, связанных с действием на расстоянии, — это грамотное проектирование, которое исключает глобальные переменные и изменяет данные только контролируемым и локальным образом, либо использование стиля чисто функционального программирования со ссылочной прозрачностью.

Термин основан на концепции действия на расстоянии в физике, которая может означать процесс, позволяющий объектам взаимодействовать без частицы-посредника, такой как глюон. В частности, Альберт Эйнштейн называл квантовую нелокальность «жутким действием на расстоянии».

Программные ошибки, вызванные действием на расстоянии, могут возникать оттого, что компонент программы делает что-то не вовремя или влияет на то, на что не должен. Однако очень трудно отследить, какой именно компонент за это отвечает. Побочные эффекты от безобидных действий могут привести программу в неизвестное состояние, так что локальные данные не обязательно остаются локальными. Решение в этом конкретном случае — определить, какие компоненты должны взаимодействовать с какими. Грамотное проектирование, которое точно определяет интерфейс между частями программы и исключает разделяемое состояние, способно во многом устранить проблемы, вызванные действием на расстоянии.

Пример

Этот пример на языке программирования Perl демонстрирует особенно серьёзный случай действия на расстоянии (обратите внимание, что переменная $[ была объявлена устаревшей в более поздних версиях Perl):

Индексы массива обычно начинаются с 0, потому что значение $[ обычно равно 0; если установить $[ в 1, то массивы начинаются с 1, что радует программистов на Fortran, и поэтому мы видим подобные примеры на man-странице perl(3):

foreach $num ($[ .. $#entry) {
    print "  $num\t'",$entry[$num],"'\n";
}

И, конечно, можно установить $[ в 17, чтобы массивы начинались с какого-нибудь случайного числа вроде 17 или 4 вместо 0 или 1. Это был отличный способ навредить авторам модулей.

К счастью, здравый смысл возобладал. Сейчас эти возможности признаны ошибками. В рассылке perl5-porters появилось крылатое выражение для таких возможностей: их называют «действием на расстоянии». Принцип таков: объявление в одной части программы не должно радикально и незаметно менять поведение какой-то другой её части.

Марк Джейсон Доминус, Sins of Perl Revisited

Действие на расстоянии между объектами

Грамотное объектно-ориентированное программирование предполагает принципы проектирования, которые исключают действие на расстоянии.

Закон Деметры гласит, что объект должен взаимодействовать только с близкими к себе объектами. Если требуется действие в удалённой части системы, оно должно реализовываться через распространение сообщения. Грамотное проектирование сильно ограничивает случаи действия на расстоянии, способствуя сопровождаемости программ. Стремление создать объектную оргию возникает из плохого проектирования интерфейсов, возможно, в форме божественного объекта, отсутствия настоящих объектов или пренебрежения законом Деметры.

Одно из преимуществ функционального программирования в том, что действие на расстоянии в нём отходит на второй план, иногда вплоть до того, что его вообще невозможно выразить в исходном языке.

Осознание опасности допущения действия на расстоянии в проекте и умение распознавать его наличие полезны при разработке программ, которые корректны, надёжны и сопровождаемы. Учитывая, что бо́льшая часть расходов на программу может приходиться на фазу сопровождения, а действие на расстоянии делает сопровождение трудным, дорогим и подверженным ошибкам, стоит приложить усилия на этапе проектирования, чтобы его избежать.