Закон Деметры ( англ. Law of Demeter, LoD) - правило дизайна при разработке программного обеспечения, в частности объектно-ориентированных программ. Обобщенно, Закон Деметры является специфическим случаем слабой связности. Правило было изобретено в северовосточном Университете (Бостон, Массачусетс, США) в конце 1987 и может быть сформулированным одним из следующих способов:
-
Каждый модуль должен обладать ограниченным знанием о других модули: только о модулях, которые имеют «близкое» отношение к данному модулю.
-
Каждый модуль имеет разговаривать только со своими друзьями, не разговаривать с незнакомцами.
-
Обращаться только к непосредственным друзей
Фундаментальной идеей является то, что объект должен иметь как можно меньше представления о структуре и свойствах чего угодно (включая собственные подкомпонент). Название взято из проекта «Деметра», который использовал идеи аспект-ориентированного и адаптивного программирования. Проект был назван в честь Деметры, греческой богини земледелия, чтобы подчеркнуть достоинства философии программирования "снизу-вверх".
В объектно-ориентированном программировании
В контексте объектно-ориентированного программирования, Закон Деметры более точно называть «Закон Деметры для функций \ методов». В этом случае, объект А может использовать сервис (вызвать метод) объекта B, и объект А не может «через» объект В доступа к другому объекту, С, и использовать его сервисы. Если бы это было возможно, это значило бы, что объект А явно требует большего знания о внутренней структуре объекта В. Вместо этого, интерфейс В должна быть изменена, если необходимо, таким образом, чтобы напрямую обрабатывать запросы объекта А, передавая их соответствующим пидкомпонетам. Как альтернатива, А может иметь прямую ссылку на объект С и вызывать методы непосредственно с него. Если следовать закону, только объект В знает свою внутреннюю структуру.
Более формально, Закон Деметры для функций требует, что метод М объекта О должна вызывать методы только следующих типов объектов:
-
собственно самого О
-
параметров М
-
других объектов, созданных в рамках М
-
прямых компонентных объектов О
-
глобальных переменных, доступных О, в пределах М
Практически, объект-клиент должен избегать вызовов методов объектов, внутренних членов, возвращенных методом объекта-сервиса. Для многих современных объектно-ориентированных языков программирования, использующих точку, как квалификатор члена класса, закон может быть перефразированная как «Используйте только одну точку». Таким образом, код abMethod() нарушает Закон Деметры, а код a.Method() является корректным.
Преимущества и недостатки
Преимуществами Закона Деметры является то, что разработанное программное обеспечение является менее сложным при поддержке и большие возможности повторного использования кода. Так как объекты являются менее зависимыми от внутренней структуры других объектов, контейнеры объектов могут быть изменены без модификации вызывающих объектов (клиентов).
Недостатком Закона Деметры является то, что иногда требует создания большого количества малых методов-адаптеров (делегатов), для передачи вызовов метода к внутренних компонентов. Более того, интерфейс класса может стать перегруженным, так как содержит методы внутренних классов, что нарушает принцип высокой связности. И это также может быть сигналом плохого объектно-ориентированного дизайна.
Многоярусная архитектура может рассматриваться, как пример имплементации Закона Деметры в программной системе. В такой архитектуре код каждого из ярусов может вызвать только код своего яруса и код с низшего яруса. Вызов «через ярус» является нарушением многоярусной архитектуры.