Czy to zapach kodu, jeśli metoda prywatna wywołuje metodę publiczną?


25

Czy wywoływanie metody public w prywatnej metodzie tej samej instancji obiektu jest zapachem?


AAMOI czy masz konkretny przykład?
ocodo

Nie, nie obecnie. Właśnie zapamiętałem przypadek, który omówiłem z moimi kolegami. Chciałem też uzyskać tutaj opinie.
Eimantas

5
Zwykle mogę zrozumieć akronim na podstawie kontekstu, ale AAMOI zdecydowanie musiałem spojrzeć w górę
Carson Myers

@Carson - znalazłeś coś?
Eimantas,

4
Jako przedmiot zainteresowania
Carson Myers,

Odpowiedzi:


32

Nie niezły zapach. Może to być potrzebne, dlaczego podejrzewasz, że to źle? Metoda na poziomie atomowym to niezależna jednostka, która wykonuje zadanie. Tak długo, jak wykonuje zadanie, każdy, kto ma do niego dostęp, może do niego zadzwonić, aby wykonać zadanie.


Zgadzam się. Niektóre metody zapewniają funkcjonalność przydatną zarówno dla wewnętrznych, jak i zewnętrznych rozmówców. Czerwona flaga mogłaby być, gdyby metoda publiczna była bardzo specyficzna dla wewnętrznej implementacji, ale nawet wtedy nie każda klasa ma ukrywać swoje elementy wewnętrzne. Często mam na przykład warstwę „narzędzia” struktury danych pod warstwą typu abstrakcyjnego kontenera - w ten sposób mogę ponownie wykorzystać część kodu struktury danych dla innych struktur danych leżących u podstaw innych kontenerów.
Steve314,

19

Zapach kodowy? Tak, niezbyt zły, ale dobry wskaźnik, że klasa może mieć zbyt wiele obowiązków.

Weź to za znak, że klasa może wymagać podziału na różne obiekty, prywatne metody nie powinny tak naprawdę wywoływać publicznych metod tego samego obiektu, z pewnością w czystym projekcie OO.

Oczywiście po sprawdzeniu klasy i wyjaśnieniu przyczyn wywołania metody może być to całkowicie rozsądne zastosowanie, ogólnie można oczekiwać, że metody użytkowe będą prywatne, ale jeśli jedna jest wystarczająco użyteczna, aby być publiczne i wykorzystywane przez inne metody, ogólnie oczekiwałbym, że te metody będą również publiczne.

Podobnie jak w przypadku wszystkich zapachów kodu, jest to motywacja do dalszej kontroli kodu, racjonalizacji i może refaktoryzacji, ale nie jest to powodem do niepokoju.


5
+1 za „brak powodu do alarmu”. Zbyt wiele razy widzimy „zapach” i natychmiast przechodzimy w tryb refaktoryzacji bez zastanowienia.
Michael K

+1 dla SRP. Właśnie natrafiłem na przypadek, w którym dekorator nie działał, ponieważ dekorowana klasa nazywała swoją funkcję publiczną, omijając dekoratora. Rozwiązanie: podziel klasę na dwie części i wstrzyknij dekorowaną zależność.
Jon Hulka,

18

Może to prowadzić do nieprzyjemnych niespodzianek, jeśli ktoś, kto nie przeczytał kodu źródłowego tej klasy, spróbuje go podklasować i zastąpi metodę publiczną. To, czy jest to prawdziwy problem, oczywiście zależy od twojej sytuacji. Może powinieneś rozważyć uczynienie metody publicznej, a nawet ostatecznej klasy.


Czemu? Jeśli nadpisana metoda publiczna prowadzi do nieprzyjemnych niespodzianek, czy to naprawdę ma znaczenie, kto ją nazwał?
user281377,

4
Tak. Jeśli zastąpienie jednej metody publicznej spowoduje uszkodzenie innej metody publicznej, mogę również zastąpić tę inną metodę. Jeśli złamie metodę prywatną, mogę ...?
Kim

5
Nieprzyjemną niespodzianką wynikającą z zastąpienia metody publicznej jest sam zapach kodu. W rzeczywistości smród kodu.
Larry Coleman,

Kim: jeśli metoda jest publiczna, musisz założyć, że inne klasy równie dobrze wywołują tę metodę ...
user281377 12.01.11

@ Larry: Dokładnie! Metoda prywatna (która zwykle zawiera założenia specyficzne dla implementacji) wywołująca metodę publiczną zwiększa prawdopodobieństwo, że przesłonięcie metody publicznej spowoduje uszkodzenie.
Kim

5

Nie sądzę, że możemy genaryzować.

Wszystko zależy bardzo mocno od kontekstu.

Mogę mieć, powiedzmy, metodę użyteczności publicznej w klasie, która jest używana przez inne klasy, a także jakąś metodę prywatną w tej samej klasie.


5

Nie. Co jeszcze należy zrobić w takim przypadku? Czy ustawić metodę prywatną jako publiczną czy metodę prywatną? Skopiuj-Wklej kod z metody publicznej do prywatnej?


Lub może delegować metodę publiczną na (nową) metodę prywatną, która jest wywoływana przez inną metodę prywatną. Ale po co zawracać sobie głowę?
Lawrence Dol

4

NIE , tutaj nie ma nieprzyjemnego zapachu.

jeśli zaimplementujemy interfejs kolejki z Listą, czy nieprzyjemnym zapachem jest wywoływanie odpowiednich funkcji List w celu łatwego wdrożenia kolejki?

jeśli coś masz i chcesz go przekonwertować na coś innego (np. opakowanie), to nie jest to nieprzyjemny zapach, jego ponowne użycie kodu z wzorcem projektowym działało na poziomie funkcji (czy funkcja jest obiektem?)


2

Wiem, że to stary post, ale debatuję w pracy. Uważam to za zapach kodu i nie mogę zrozumieć, dlaczego miałbyś chcieć to zrobić. Jeśli metoda prywatna musi wywołać metodę publiczną, wówczas treść metody publicznej powinna zostać pobrana i umieszczona w metodzie prywatnej, którą następnie obie metody mogą wywołać. Czemu?

  1. Metoda publiczna może zawierać testy, które nie są konieczne po wewnętrznym wykonaniu kodu. Może otrzymać UserObj i na przykład chcieć przetestować uprawnienia użytkownika.

  2. Po publicznym wywołaniu może być konieczne zablokowanie obiektu, jeśli używasz wątków, więc wewnętrznie nie będziesz chciał odwoływać się do metody publicznej.

  3. Moim zdaniem bardziej prawdopodobne jest wprowadzanie błędów okrągłych i nieskończonych pętli oraz wyjątków od memów.

  4. Prosty i prosty, zły projekt i „leniwy”. Metody publiczne zapewniają dostęp do świata zewnętrznego. Nie ma powodu, aby wracać na zewnątrz, gdy już jesteś w środku.


1
Co jeśli istniejąca metoda publiczna jest wywoływana przez wiele innych klas? Uczynienie tego prywatnym to złamie. Pamiętaj, że metody publiczne są wywoływane przez inne klasy z innych powodów, nie tylko tej klasy. dlaczego istnieją metody publiczne.
Michael Durrant

Stwierdziłem, że „treść metody publicznej powinna zostać wzięta i umieszczona w metodzie prywatnej ...” Metoda publiczna pozostanie, ale wywoła nową metodę prywatną. Podobnie jak inne prywatne metody, które muszą ponownie korzystać z tej samej funkcjonalności.
Mark Graham

Więc dodajesz inną metodę bez żadnego innego powodu niż - cóż, ponieważ zadeklarowałeś to jako „zapach kodu”. Bezcelowe metody to gorszy zapach kodu.
gnasher729

Przepraszam, ale czy nie wymieniłem tylko kilku powodów powyżej. Wiele kodu, który piszę, dotyczy systemów biznesowych, wiele klas jest ograniczona do użytkowników na podstawie roli. Wiele metod publicznych testuje uprawnienia użytkownika i parametry. Dlaczego, u licha, miałbym chcieć odwoływać się do tej samej metody publicznej, aby ponownie użyć jej funkcjonalności i ponownie przetestować uprawnienia użytkownika?
Mark Graham

Nigdy w życiu nie potrzebowałem nazywać metody publicznej od prywatnej. Po prostu wydaje mi się i czuję się bardzo źle. Jestem naprawdę zaskoczony, że większość ludzi uważa, że ​​jest w porządku.
Pułapka

2

Wyobraź sobie coś przeciwnego. Jesteś w prywatnej metody i trzeba funkcjonalność w sposób publiczny Co zrobić, jeśli nie mógł wywołać tę metodę publicznego z prywatnym jeden. Co byś zrobił?

  • Utworzyć zduplikowaną metodę prywatną? Nie
  • Stworzyć specjalną metodę publiczną na tę okazję? Nie
  • Wywołać specjalną metodę prywatną, która może wywoływać metody publiczne? Nie
  • Jakiś super, który może to zrobić? Nie

Odpowiedź jest jednoznaczna: jeśli chcesz mieć funkcjonalność w metodzie publicznej, powinieneś być w stanie wywołać tę metodę z metod tej klasy lub z innych klas.


1

W moim kodzie często tworzę leniwe moduły ładujące, co oznacza, że ​​obiekt jest inicjowany przy pierwszym żądaniu, a następnie ponownie wykorzystuje ten sam obiekt instancji. Jednak obiekt utworzony przy użyciu leniwego obciążenia sugeruje, że niekoniecznie musi zostać utworzony w dowolnym punkcie. Zamiast owijać głowę wokół sekwencji wywołań, tak że wiem, że ten obiekt jest już utworzony lub powtarzam ten sam kod leniwego obciążenia w innej metodzie, po prostu wywołuję leniwy moduł ładujący, gdy tylko potrzebuję tego obiektu.

Tak jak możesz inteligentnie korzystać z publicznych metod, możesz ich również używać niepoprawnie. Przykładem może być metoda publiczna, która przetwarza parametry przed wywołaniem innej metody prywatnej. Błędem byłoby wywoływanie tej publicznej metody zwyczajnie po prostu dlatego, że masz te same parametry. Błąd jest subtelny, ale jest to błąd projektowy bardziej niż cokolwiek innego i wymaga, abyś nauczył się radzić sobie z parametrami metody wewnętrznej, a nie parametrami metody publicznej.

Aby odpowiedzieć na twoje pytanie, z pewnością nie jest to zły kod, jeśli używasz go poprawnie.


1

Pytanie, które musisz sobie zadać, brzmi: dlaczego twoja klasa ma taką samą potrzebę jak jej klienci? Zazwyczaj klasa ma bardzo różne potrzeby od swoich klientów. Tak, to jest wskazówka, że ​​masz albo

(a) ujawnił publicznie coś, co powinno być prywatne; lub

(b) zachowanie klasy nie jest wystarczająco wąskie (pomyśl o zasadzie pojedynczej odpowiedzialności).

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.