Wolisz członków klasy lub przekazywanie argumentów między metodami wewnętrznymi?

39

Załóżmy, że w prywatnej części klasy istnieje wartość, która jest wykorzystywana przez wiele prywatnych metod. Czy ludzie wolą zdefiniować tę zmienną jako zmienną składową klasy lub przekazać ją jako argument każdej z metod - i dlaczego?

Z jednej strony widziałem argument, że należy zredukować stan (tj. Zmienne składowe) w klasie, co jest ogólnie dobrą rzeczą, chociaż jeśli ta sama wartość jest wielokrotnie wykorzystywana w metodach klasy, wydaje się, że byłaby idealna kandydat do reprezentacji jako stan, aby klasa uczyniła kod wyraźnie widocznym, jeśli nic więcej.

Edytować:

Aby wyjaśnić niektóre z podniesionych komentarzy / pytań, nie mówię o stałych i nie odnosi się to do żadnego konkretnego przypadku, a jedynie hipotetyczny, o którym rozmawiałem z innymi ludźmi.

Ignorując przez chwilę kąt OOP, szczególny przypadek użycia, o którym myślałem, był następujący (załóżmy, że przekazujemy referencję tylko po to, aby pseudokod był czystszy)

int x
doSomething(x)
doAnotherThing(x)
doYetAnotherThing(x)
doSomethingElse(x)

Mam na myśli to, że istnieje pewna zmienna, która jest wspólna dla wielu funkcji - w moim przypadku było to spowodowane łańcuchem mniejszych funkcji. W systemie OOP, jeśli byłyby to wszystkie metody klasy (powiedzmy z powodu refaktoryzacji poprzez wyodrębnienie metod z dużej metody), zmienna ta mogłaby zostać przekazana wokół nich wszystkich lub mogłaby być członkiem klasy.

geoffjentry
źródło
1
Jak używana jest ta wartość? To jest stałe? Czy to się zmienia Czy podlega zmianom między kompilacjami?
Oded
Kiedy rzeczy są automatycznie określane jako takie same, łatwiej jest myśleć, że to nie ma znaczenia. Co jeśli masz funkcję, która wymagała skorygowanej wartości (x), takiej jak x-1?
JeffO,

Odpowiedzi:

15

Jeśli wartość jest własnością klasy, trzymaj ją w klasie, w przeciwnym razie trzymaj ją na zewnątrz. Najpierw nie projektujesz metod klasy, najpierw projektujesz jej właściwości. Jeśli nie pomyślałeś o umieszczeniu tej własności w klasie na pierwszym miejscu, prawdopodobnie istnieje ku temu powód.

Najgorsze, co możesz zrobić, jeśli chodzi o skalowalność, to zmiana kodu dla wygody. Wcześniej, a nie później, zauważysz, że Twój kod jest rozdęty i zduplikowany. Jednak muszę przyznać, że czasami łamię tę zasadę ... Wygoda jest tak cholernie pociągająca.

AJC
źródło
1
Zgadzam się - oryginalny projekt / cel klasy powinien powiedzieć, czy powinna być zmienną składową, czy argumentem. Warto również pomyśleć o kącie wtrysku zależności.
Martijn Verburg
14

Jeśli tak naprawdę nie musisz utrzymywać stanu między wywołaniami (a najwyraźniej nie, lub nie zadajesz pytania), wolałbym, aby wartość była argumentem, a nie zmienną składową, ponieważ szybki rzut oka przy podpisie metody mówi, że używa argumentu, podczas gdy nieco trudniej jest od razu powiedzieć, jakie zmienne składowe są używane przez metodę. Nie zawsze jest również szybkie określenie, dla jakich zmiennych prywatnych członków.

Tak więc normalnie nie zgodziłbym się, że kod wykorzystujący zmienne składowe jest wyraźnie czystszy, ale jeśli sygnatury metod wymykają się spod kontroli, mogę zrobić wyjątek. To jest interesujące pytanie, ale nie jest to coś, na czym projekt będzie się opierał.

psr
źródło
10

Dzięki, że zadałeś pytanie, ja też chciałem to zadać.

Kiedy o tym myślałem, jest kilka zalet, dla których warto podawać to jako argument

  • łatwiej przetestować -> łatwiej utrzymać (związany z ostatnim punktem)
  • nie ma skutków ubocznych
  • łatwiej to zrozumieć

Na przykład jasno rozumiem twój punkt widzenia - jednym z nich jest parsowanie dokumentu Excela (na przykład przy użyciu biblioteki POI) i zamiast przekazywania instancji wiersza do każdej metody, która musi pracować z tym wierszem, autor ma zmienną składową currentRowi współpracuje z nią.

Powiedziałbym, że powinna istnieć nazwa tego anty-wzoru, prawda? (nie wymienione tutaj )

Betlista
źródło
Który anty-wzór masz na myśli?
Vahid Ghadiri
Krótko mówiąc, aby mieć zmienną składową tylko po to, aby współdzielić parametr między dwoma (lub więcej) wywołaniami funkcji ...
Betlista,
1

Być może powinieneś wyodrębnić nową klasę zawierającą wszystkie metody dzielące tę wartość. Oczywiście metoda najwyższego poziomu będzie publiczna w nowej klasie. Pomocne może być ujawnienie tej metody testowania.

Jeśli masz dwa lub więcej elementów tymczasowych, które są zawsze przekazywane razem, prawie na pewno powinieneś wyodrębnić nową klasę.

Kevin Cline
źródło
1

Czy ludzie wolą zdefiniować tę zmienną jako zmienną składową klasy lub przekazać ją jako argument każdej z metod - i dlaczego?

Jeśli rozumiem, o co pytasz: metody w klasie są z definicji wtajemniczone w szczegóły implementacji, więc nie miałbym żadnych wątpliwości co do używania dowolnego członka bezpośrednio z dowolnej metody.

Z jednej strony widziałem argument, że należy zredukować stan (tj. Zmienne składowe) w klasie na ogół dobrze ...

Nie ma nic złego w deklarowaniu a w private static finalcelu zdefiniowania stałych. Kompilator będzie mógł wykorzystać tę wartość do rozważenia pewnych optymalizacji, a ponieważ jest stałymi, tak naprawdę nie dodaje stanu do klasy.

chociaż jeśli ta sama wartość jest wielokrotnie używana w metodach klas ...

Możliwość symbolicznego odwoływania się do niego (np. BLRFL_DURATION) I brak konieczności dodawania dodatkowych argumentów do metod sprawi, że kod będzie bardziej czytelny, a zatem łatwiejszy w utrzymaniu.

Blrfl
źródło
0

jeśli wartość się nie zmienia, to z definicji jest stała i powinna być zawarta w klasie. W takim przypadku nie uważa się, aby wpływał na stan obiektu. Nie znam twojego przypadku, ale myślę o czymś takim jak PI w trygonometrii. Jeśli spróbujesz przekazać argument takiej stałej, możesz narazić wynik na błąd, jeśli klient przekaże niepoprawną wartość lub wartość nie z taką samą dokładnością, jakiej oczekują metody.

Bez szans
źródło