Принцип Tell Don't Ask говорить:
ви повинні намагатися розповідати об’єктам, що ви хочете, щоб вони робили; не задавайте їм запитань про їх стан, прийміть рішення, а потім розкажіть, що їм робити.
Проблема полягає в тому, що, як абонент, ви не повинні приймати рішення, засновані на стані об'єкта, що викликається, в результаті чого ви змінюєте стан об'єкта. Логіка, яку ви реалізуєте, ймовірно, називається відповідальністю об'єкта, а не вашою. Для вас прийняття рішень поза об’єктом порушує його інкапсуляцію.
Простий приклад «Скажи, не проси» є
Widget w = ...;
if (w.getParent() != null) {
Panel parent = w.getParent();
parent.remove(w);
}
і версія Tell ...
Widget w = ...;
w.removeFromParent();
Але що робити, якщо мені потрібно знати результат методу removeFromParent? Моя перша реакція полягала лише в тому, щоб змінити файл RemoveFromParent, щоб повернути булеве значення, що позначає, чи було вилучено батьківське рішення чи ні.
Але потім я натрапив на шаблон поділу запитів команд, який говорить НЕ робити цього.
У ньому зазначається, що кожен метод повинен бути або командою, яка виконує дію, або запитом, який повертає дані абоненту, але не обидва. Іншими словами, запитання не повинно змінювати відповідь. Більш формально, методи повинні повертати значення лише в тому випадку, якщо вони референтно прозорі і, отже, не мають побічних ефектів.
Чи справді ці двоє суперечать один одному і як я вибираю між ними? Чи варто їхати з цим прагматичним програмістом чи Бертрандом Мейєром?