Czy zgodnie z prawem Demeter klasa może zwrócić jednego ze swoich członków?
Tak, z pewnością tak jest.
Spójrzmy na główne punkty :
- Każda jednostka powinna mieć ograniczoną wiedzę na temat innych jednostek: tylko jednostki „ściśle” związane z bieżącą jednostką.
- Każda jednostka powinna rozmawiać tylko z przyjaciółmi; nie rozmawiaj z nieznajomymi.
- Rozmawiaj tylko z najbliższymi przyjaciółmi.
Wszystkie trzy pozostawiają ci pytanie: kto jest przyjacielem?
Podejmując decyzję o zwrocie, Prawo Demetera lub zasada najmniejszej wiedzy (LoD) nie nakazuje, abyś bronił się przed programistami, które nalegają na jego naruszenie. Wymaga to, abyś nie zmuszał programistów do naruszania go.
Zrozumienie tych jest właśnie powodem, dla którego tak wielu uważa, że rozgrywający musi zawsze powrócić do pustki. Nie. Musisz umożliwić sposób tworzenia zapytań (getterów), które nie zmieniają stanu systemu. To podstawowa separacja zapytań poleceń .
Czy to oznacza, że możesz zagłębić się w bazę kodu łączącą ze sobą, co tylko chcesz? Nie. Połącz razem tylko to, co miało być połączone razem. W przeciwnym razie łańcuch może się zmienić i nagle twoje rzeczy zostaną zerwane. To właśnie rozumieją przyjaciele.
Można zaprojektować długie łańcuchy. Płynne interfejsy, iDSL, duża część Java8 i stary dobry StringBuilder mają na celu budowanie długich łańcuchów. Nie naruszają LoD, ponieważ wszystko w łańcuchu ma współpracować i obiecało, że będzie dalej działać. Naruszasz demeter, gdy łączysz ze sobą rzeczy, o których nigdy się nie słyszeli. Przyjaciele to ci, którzy obiecali, że twój łańcuch będzie działał. Przyjaciele Przyjaciół nie.
Oprócz klas, które zostały specjalnie wyznaczone do zwracania obiektów - takich jak klasy fabryczne i konstrukcyjne - czy metoda jest w stanie zwrócić obiekt, np. Obiekt będący własnością jednej z właściwości klasy, czy też naruszałoby to prawo demeter (1) ?
To tylko stwarza okazję do naruszenia demeter. To nie jest naruszenie. To niekoniecznie jest złe.
A jeśli narusza prawo demeter, czy miałoby to znaczenie, czy zwracany obiekt jest niezmiennym obiektem, który reprezentuje kawałek danych i zawiera tylko getery dla tych danych (2)?
Niezmienne jest dobre, ale nie ma tu znaczenia. Poruszanie się po dłuższym łańcuchu nie poprawia sytuacji. Lepiej jest oddzielić pobieranie od używania. Jeśli używasz, zapytaj o to, czego potrzebujesz jako parametru. Nie poluj na nie, zagłębiając się w porywaczy nieznajomych.
W pseudokodzie:
Podejrzewam, że prawo Demetera zabrania takiego wzoru jak powyższy. Co mogę zrobić, aby wywołać funkcję doSomethingElse () bez naruszenia prawa (3)?
Zanim zacznę mówić o x.doSomethingElse(a)
zrozumieniu, że zasadniczo napisałeś
b.getA().doSomething()
Teraz LoD nie jest ćwiczeniem zliczania kropek . Ale kiedy tworzysz łańcuch, mówisz, że wiesz, jak zdobyć A
(używając B
) i wiesz, jak go użyć A
. Cóż, teraz A
i B
lepiej bądźcie bliskimi przyjaciółmi, ponieważ po prostu połączyłeś ich ze sobą.
Jeśli właśnie poprosił o coś do ręki ci A
jak coś można użyć A
i nie obchodziło, skąd pochodzi i B
mogli żyć szczęśliwie i wolne od swojej obsesji z uzyskaniem A
od B
.
Jeśli chodzi o x.doSomethingElse(a)
szczegóły bez x
źródła, LoD nie ma nic do powiedzenia na ten temat.
LoD może zachęcać do oddzielania użytkowania od konstrukcji . Ale zaznaczę, że jeśli religijnie traktujesz każdy obiekt jako nieprzyjazny, utkniesz w pisaniu kodu metodami statycznymi. Możesz w ten sposób zbudować cudownie złożony wykres obiektowy, ale ostatecznie musisz wywołać na nim metodę, aby rozpocząć pracę. Musisz po prostu zdecydować, kim są twoi przyjaciele. Nie da się od tego uciec.
Tak więc klasa może zwrócić jednego ze swoich członków na podstawie LoD. Kiedy to zrobisz, powinieneś wyjaśnić, czy ten członek jest przyjazny dla twojej klasy, ponieważ jeśli nie, jakiś klient może spróbować połączyć cię z tą klasą, używając ciebie, aby ją zdobyć przed użyciem. To ważne, ponieważ teraz to, co zwracasz, musi zawsze obsługiwać to użycie.
Istnieje wiele przypadków, w których po prostu nie stanowi to problemu. Kolekcje mogą to zignorować po prostu dlatego, że mają być przyjaciółmi ze wszystkim, co ich używa. Podobnie obiekty wartości są przyjazne dla wszystkich. Ale jeśli napisałeś narzędzie do sprawdzania poprawności adresu, które wymagało od obiektu pracownika, z którego wyodrębniał adres, a następnie po prostu poprosił o adres, lepiej miej nadzieję, że zarówno pracownik, jak i adres pochodzą z tej samej biblioteki.