Zasada Tell Don't Ask mówi:
powinieneś starać się powiedzieć obiektom, co chcesz, aby zrobiły; nie zadawaj im pytań o ich stan, podejmuj decyzje, a następnie mów im, co mają robić.
Problem polega na tym, że jako osoba wywołująca nie powinna podejmować decyzji opartych na stanie wywoływanego obiektu, które powodują zmianę stanu obiektu. Logika, którą wdrażasz, jest prawdopodobnie odpowiedzialnością wywoływanego obiektu, a nie twoją. Podejmowanie decyzji poza obiektem narusza jego enkapsulację.
Prostym przykładem „Powiedz, nie pytaj” jest
Widget w = ...;
if (w.getParent() != null) {
Panel parent = w.getParent();
parent.remove(w);
}
a wersja tell to ...
Widget w = ...;
w.removeFromParent();
Ale co jeśli muszę znać wynik metody removeFromParent? Moja pierwsza reakcja polegała na zmianie metody removeFromParent na zwrócenie wartości logicznej oznaczającej, czy element nadrzędny został usunięty, czy nie.
Ale potem natknąłem się na wzorzec rozdzielania zapytań, który mówi NIE robić tego.
Stwierdza, że każda metoda powinna być albo komendą wykonującą akcję, albo zapytaniem zwracającym dane do dzwoniącego, ale nie jednym i drugim. Innymi słowy, zadanie pytania nie powinno zmienić odpowiedzi. Bardziej formalnie, metody powinny zwracać wartość tylko wtedy, gdy są referencyjnie przejrzyste, a zatem nie mają żadnych skutków ubocznych.
Czy te dwie rzeczy naprawdę są ze sobą sprzeczne i jak wybrać między nimi? Czy korzystam z tego w Pragmatic Programmer lub Bertrand Meyer?