Принцип « Говори, а не спрашивай» гласит:
вы должны стараться рассказать объектам, что вы хотите, чтобы они делали; не задавайте им вопросов об их состоянии, примите решение, а затем скажите им, что делать.
Проблема заключается в том, что, как вызывающая сторона, вы не должны принимать решения, основанные на состоянии вызываемого объекта, в результате чего вы затем меняете состояние объекта. Логика, которую вы реализуете, вероятно, является ответственностью вызываемого объекта, а не вашей. Для вас принятие решений вне объекта нарушает его инкапсуляцию.
Простой пример «Скажи, не проси» является
Widget w = ...;
if (w.getParent() != null) {
Panel parent = w.getParent();
parent.remove(w);
}
и сказать версию ...
Widget w = ...;
w.removeFromParent();
Но что, если мне нужно узнать результат от метода removeFromParent? Моя первая реакция состояла в том, чтобы просто изменить removeFromParent, чтобы он возвращал логическое значение, обозначающее, был ли удален родитель или нет.
Но потом я наткнулся на шаблон разделения командных запросов, который говорит НЕ делать этого.
В нем говорится, что каждый метод должен быть либо командой, выполняющей действие, либо запросом, который возвращает данные вызывающей стороне, но не обоими. Другими словами, задание вопроса не должно изменить ответ. Более формально, методы должны возвращать значение, только если они прозрачны по ссылкам и, следовательно, не имеют побочных эффектов.
Эти два действительно противоречат друг другу, и как я могу выбрать между этими двумя? Я согласен с прагматичным программистом или Бертраном Мейером?