Статьи

Скажи, не спрашивай

о правилах и принципах

Некоторое время назад я писал о Законе Деметры , о преимуществах следования этому закону. Сегодня я хотел бы написать о
Принцип «говори, не спрашивай» . Принцип, который, по крайней мере, на мой взгляд, является отправной точкой для упомянутого закона. Следование LoD является одним из последствий применения принципа TDA.

Хорошо, но что мы должны сказать и о чем не должны спрашивать?

спрашивать результат, а не данные

Вкратце, принцип TDA говорит нам, что вместо того, чтобы запрашивать данные у объектов, мы должны сообщать им, что следует делать, а затем ждать результата операции.

Что означает, что вместо ::

1
2
3
4
Age age = sebastian.getAge();
if (age >= 18) {
    letDoTheThingsThatAdultsDoes(sebastian);
}

Мы должны написать что-то вроде этого:

1
2
3
if (sebastian.isAdult()) {
    letDoTheThingsThatAdultsDoes(sebastian);
}

Теперь лучше? Это легче читать? Чтобы понять смысл кода?

К сожалению, не всегда очевидно, какое решение лучше.

чем больше вы говорите, тем большие объекты могут стать …

Приведенный выше пример очень хорошо показывает, что принцип TDA должен защищать. Я говорю об инкапсуляции.

Мы не вытаскиваем данные из объекта. Мы не позволяем им быть известными внешнему миру. Мы не работаем над ними напрямую. Вместо этого мы говорим объекту, что нужно сделать, и ждем результата.

В конце концов, разве это не обязанность объекта работать со своими собственными атрибутами?

Тем не менее, вы не можете быть слишком нетерпеливым. Инкапсуляция важна, но для объекта также важно иметь соответствующий API. API, который позволяет комфортно работать.

Можете ли вы представить, что произойдет, если мы запретим создание метода, который будет извлекать данные из объекта? Что произойдет, если мы изменим этот принцип в закон?

ты всегда должен «говорить»?

Каждая дополнительная операция — это другая строка кода. Это еще одна ответственность.

Эти обязанности организованы вокруг одного конкретного контекста (конкретного объекта), но … не слишком ли это для отдельного объекта?

Если вы написали свой код строго следуя принципу TDA, вы можете столкнуться с двумя основными проблемами.

Во-первых, классы начинают расти и расти, и в результате они становятся действительно огромными. Если инкапсуляция любой ценой становится вашей паранойей, вы можете оказаться в таком месте, где количество строк кода классов будет подавляющим, и ваш код станет трудным для понимания.

Во-вторых, увеличение числа зависимостей и обязанностей часто идет рука об руку с большими классами. Да, код организован вокруг атрибутов конкретного объекта, но многие из его методов не имеют никакой общей части.

Вот почему вам нужно заботиться о размере вашего объекта и делать объекты как можно меньше. Хорошо иметь объекты, которые обеспечивают поведение и защищают данные. Но вы должны помнить, что слишком много поведения ведет к слишком большому количеству обязанностей. И это напрямую влияет на сложность ваших классов и приложений.

когда есть больше чем один …

А что в ситуации, когда для конкретной операции требуются данные от нескольких разных объектов разного типа?

Давайте даже упростим проблему! Давайте поговорим о вычислениях, которые требуют данных из разных объектов одного и того же класса. Простым примером может служить подсчет среднего возраста в группе людей, где каждый человек является отдельным объектом.

Как мы должны это сделать?

Должны ли мы спросить о возрасте:

1
2
3
4
5
6
7
Age totalAge = Age.NEWLY_BIRTH;
 
for (Person person : persons) {
    totalAge = totalAge.add(person.getAge());
}
 
return totalAge.divide(persons.size());

Или, может быть, мы должны начать думать, как решить эту проблему, говоря объектам, чего мы хотим?

резюме

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

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

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

Ссылка: Скажите, не спрашивайте у нашего партнера по JCG Себастьяна Малаки в блоге « Давай поговорим о Java» .