OOP

Это мини-серия статей по написанию поддерживаемого объектно-ориентированного кода без лишней нервотрепки. 

Предыдущие части: Часть 1

 

Единственный закон в программировании — это отсутствие законов. А закон Деметры — это, скорее, рекомендации, а не свод правил по работе с кодом. Он позволяет уменьшить связанность между компонентами.

Train Wrecks в функциях

Всем нам знакомы длинные цепочки функций, которые выглядят примерно так:

obj.getX()
      .getY()
        .getZ()
          .doSomething();

Мы спрашиваем, спрашиваем, спрашиваем, а лишь затем что-то говорим. Ведь так намного лучше?

obj.doSomething();

ВызовdoSomething()распространяется до достижения Z. Эти длинные цепочки запросов называются «train wrecks» и нарушают принципы так называемого закона Деметры.

Закон Деметры

Закон Деметры говорит о том, что плохо, когда простые функции знают всю навигационную структуру системы.

Представьте себе, сколько информации сокрыто в строке obj.getX().getY().getZ().doSomething(). Она знает, что в objесть X, в Xесть Y, в Y есть Z, и Z может что-то делать. Это колоссальный объем данных для одной строки. А сама строка связана с функцией, которая содержит слишком много информации обо всей системе.

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

В объектно-ориентированных приложениях закон Деметры формализует принцип «Говори — не спрашивай» (Tell Don’t Ask) со следующим набором правил:

Вы можете вызывать методы объектов, которые:
1. передаются как аргументы;
2. были созданы локально;
3. являются экземплярами переменных;
4. являются глобальными переменными.

Пример

 

Здесь account.getPlan().getPrice() нарушает закон Деметры. Самое очевидное решение — делегировать/сказать:

 

Заключение

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

Придерживаться данного правила довольно сложно. Поэтому иногда его называют предложением Деметры — из-за того, с какой легкостью его можно нарушить. Но плюсы очевидны: любая функция, которая следует данному правилу и «говорит» вместо того, чтобы «спрашивать», отделяется от своих «соседей».

Биологические системы являются отличной иллюстрацией подобных систем. Клетки не задают друг другу вопросов. Они говорят, что именно нужно делать. Мы — примеры системы «Говори — Не спрашивай». И внутри нас преобладает закон Деметры.

 

Перевод статьи Arun SasidharanObject Oriented Tricks: #2 Law of Demeter