Przeglądając napisany przeze mnie kod, natknąłem się na następującą konstrukcję, która skłoniła mnie do myślenia. Na pierwszy rzut oka wydaje się wystarczająco czysty. Tak, w rzeczywistym kodzie getLocation()
metoda ma nieco bardziej konkretną nazwę, która lepiej opisuje dokładnie, jaką lokalizację otrzymuje.
service.setLocation(this.configuration.getLocation().toString());
W tym przypadku service
jest to zmienna instancji znanego typu, zadeklarowana w ramach metody. this.configuration
pochodzi z przekazania do konstruktora klasy i jest instancją klasy implementującej określony interfejs (która nakazuje getLocation()
metodę publiczną ). Dlatego this.configuration.getLocation()
znany jest typ zwracanego wyrażenia ; szczególnie w tym przypadku jest to java.net.URL
, podczas gdy service.setLocation()
chce String
. Ponieważ oba typy String i URL nie są bezpośrednio kompatybilne, wymagana jest pewna konwersja, aby dopasować kwadratowy kołek do okrągłego otworu.
Jednakże , zgodnie z prawem Demetry jak cytowane w czystego kodu , metoda A F w klasie C powinien wywołać tylko metody, na C , przedmiotów wytworzonych lub przekazywane jako argumenty f i obiektów odbywa się w zmiennych instancji C . Cokolwiek poza tym (ostatni toString()
w moim szczególnym przypadku powyżej, chyba że weźmiesz pod uwagę obiekt tymczasowy stworzony w wyniku samej inwokacji metody, w którym to przypadku całe Prawo wydaje się być dyskusyjne) jest niedozwolone.
Czy istnieje uzasadnione powód, dla którego połączenie takie jak powyższe, biorąc pod uwagę wymienione ograniczenia, powinno być zniechęcone, a nawet zabronione? A może po prostu jestem zbyt złośliwy?
Gdybym wdrożyć metodę URLToString()
, która po prostu wywołuje toString()
na URL
obiekt (taki jak ten zwrócony przez getLocation()
), przekazanym mu jako parametr i zwraca wynik, mogę zawinąć getLocation()
wywołanie w to, aby osiągnąć dokładnie ten sam wynik; skutecznie przesunąłbym konwersję o jeden krok na zewnątrz. Czy to w jakiś sposób sprawi, że będzie to do przyjęcia? ( Wydaje mi się intuicyjnie, że nie powinno to robić żadnej różnicy, ponieważ wszystko to trochę przesuwa. Jednak, zgodnie z cytowaną literą Prawa Demeter, byłoby to do przyjęcia, ponieważ ja wtedy działałby bezpośrednio na parametrze funkcji).
Czy miałoby to jakąkolwiek różnicę, gdyby chodziło o coś nieco bardziej egzotycznego niż wywołanie toString()
standardowego typu?
Odpowiadając, pamiętaj, że zmiana zachowania lub interfejsu API typu, którego service
jest zmienna, nie jest praktyczna. Ponadto, ze względu na argument, powiedzmy, że zmiana typu zwracanego getLocation()
jest również niepraktyczna.