---
title: "Действие на расстоянии (программирование)"
type: "antipattern"
slug: "action-at-a-distance"
url: "http://localhost:3000/ru/antipatterns/action-at-a-distance.md"
description: "Антипаттерн"
---
# Действие на расстоянии (программирование)

> Антипаттерн

**Действие на расстоянии** — это [антипаттерн](https://en.wikipedia.org/wiki/Anti-pattern "Anti-pattern") в [информатике](https://en.wikipedia.org/wiki/Computer%5Fscience "Computer science"), при котором поведение в одной части [программы](https://en.wikipedia.org/wiki/Computer%5Fprogram "Computer program") резко меняется из-за трудно- или невозможно идентифицируемых [операций](https://en.wikipedia.org/wiki/Instruction%5F%28computer%5Fscience%29 "Instruction (computer science)") в другой её части.

Способ избежать проблем, связанных с действием на расстоянии, — это грамотное проектирование, которое исключает [глобальные переменные](https://en.wikipedia.org/wiki/Global%5Fvariable "Global variable") и изменяет данные только контролируемым и [локальным](https://en.wikipedia.org/wiki/Subprogram#Local%5Fvariables,%5Frecursion%5Fand%5Freentrancy "Subprogram") образом, либо использование стиля [чисто функционального программирования](https://en.wikipedia.org/wiki/Pure%5Ffunctional%5Fprogramming "Pure functional programming") со [ссылочной прозрачностью](https://en.wikipedia.org/wiki/Referential%5Ftransparency "Referential transparency").

Термин основан на концепции [действия на расстоянии](https://en.wikipedia.org/wiki/Action%5Fat%5Fa%5Fdistance "Action at a distance") в физике, которая может означать процесс, позволяющий объектам взаимодействовать без частицы-посредника, такой как [глюон](https://en.wikipedia.org/wiki/Gluon "Gluon"). В частности, [Альберт Эйнштейн](https://en.wikipedia.org/wiki/Albert%5FEinstein "Albert Einstein") называл [квантовую нелокальность](https://en.wikipedia.org/wiki/Quantum%5Fnonlocality "Quantum nonlocality") «жутким действием на расстоянии».

[Программные ошибки](https://en.wikipedia.org/wiki/Software%5Fbug "Software bug"), вызванные действием на расстоянии, могут возникать оттого, что компонент программы делает что-то не вовремя или влияет на то, на что не должен. Однако очень трудно отследить, какой именно компонент за это отвечает. [Побочные эффекты](https://en.wikipedia.org/wiki/Side%5Feffect%5F%28computer%5Fscience%29 "Side effect (computer science)") от безобидных действий могут привести программу в неизвестное состояние, так что локальные данные не обязательно остаются локальными. Решение в этом конкретном случае — определить, какие компоненты должны взаимодействовать с какими. Грамотное проектирование, которое точно определяет интерфейс между частями программы и исключает разделяемое состояние, способно во многом устранить проблемы, вызванные действием на расстоянии.

## Пример

Этот пример на языке программирования [Perl](https://en.wikipedia.org/wiki/Perl "Perl") демонстрирует особенно серьёзный случай действия на расстоянии (обратите внимание, что переменная `$[` была [объявлена устаревшей](https://en.wikipedia.org/wiki/Deprecation "Deprecation") в более поздних версиях Perl):

> Индексы [массива](https://en.wikipedia.org/wiki/Array%5Fdata%5Ftype "Array data type") обычно начинаются с 0, потому что значение `$[` обычно равно 0; если установить `$[` в 1, то массивы начинаются с 1, что радует [программистов на Fortran](https://en.wikipedia.org/wiki/Fortran "Fortran"), и поэтому мы видим подобные примеры на [man-странице](https://en.wikipedia.org/wiki/Man%5Fpage "Man page") `perl(3)`:
>
> foreach $num ($[ .. $#entry) {
>    print "  $num\t'",$entry[$num],"'\n";
> }
>
> И, конечно, можно установить `$[` в 17, чтобы массивы начинались с какого-нибудь случайного числа вроде 17 или 4 вместо 0 или 1\. Это был отличный способ навредить авторам модулей.
>
> К счастью, здравый смысл возобладал. Сейчас эти возможности признаны ошибками. В рассылке perl5-porters появилось крылатое выражение для таких возможностей: их называют «действием на расстоянии». Принцип таков: объявление в одной части программы не должно радикально и незаметно менять поведение какой-то другой её части.

— [Марк Джейсон Доминус](https://en.wikipedia.org/wiki/Mark%5FJason%5FDominus "Mark Jason Dominus"), Sins of Perl Revisited

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

Грамотное [объектно-ориентированное программирование](https://en.wikipedia.org/wiki/Object-oriented%5Fprogramming "Object-oriented programming") предполагает принципы проектирования, которые исключают действие на расстоянии.

[Закон Деметры](https://en.wikipedia.org/wiki/Law%5Fof%5FDemeter "Law of Demeter") гласит, что объект должен взаимодействовать только с близкими к себе объектами. Если требуется действие в удалённой части системы, оно должно реализовываться через распространение сообщения. Грамотное проектирование сильно ограничивает случаи действия на расстоянии, способствуя сопровождаемости программ. Стремление создать [объектную оргию](https://en.wikipedia.org/wiki/Object%5Forgy "Object orgy") возникает из плохого проектирования интерфейсов, возможно, в форме [божественного объекта](https://en.wikipedia.org/wiki/God%5Fobject "God object"), отсутствия настоящих объектов или пренебрежения законом Деметры.

Одно из преимуществ [функционального программирования](https://en.wikipedia.org/wiki/Functional%5Fprogramming "Functional programming") в том, что действие на расстоянии в нём отходит на второй план, иногда вплоть до того, что его вообще невозможно выразить в исходном языке.

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