2010-02-09 20 views
11

Wolę używać zmiennych lokalnych zamiast wielu wywołań tej samej metody.Styl kodowania Java, zmienne lokalne a wielokrotne wywołania metod

/* 
* I prefer this 
*/ 
Vehicle vehicle = person.getVehicle() 
if (vehicle instanceof Car) { 
    Car car = (Car) vehicle; 
    car.openSunroof(); 
} else if (vehicle instanceof Bike) { 
    Bike bike = (Bike) vehicle; 
    bike.foldKickstand(); 
} 
/* 
* Rather than this 
*/ 
if (person.getVehicle() instanceof Car) { 
    Car car = (Car) person.getVehicle(); 
    car.openSunroof(); 
} else if (person.getVehicle() instanceof Bike) { 
    Bike bike = (Bike) person.getVehicle(); 
    bike.foldKickstand(); 
} 
  • wierzę, że pierwszy sposób ma zamiar wykonać odrobinę szybciej
  • myślę drugi sposób narusza DRY zasadę
  • znajdę Pierwszy sposób bardziej czytelny i łatwiejszy do debugowania (... OK pomijalne ponieważ mogłem krok nad)
  • nie chcę mieć do czynienia z możliwością państwa zmienił obiektu

Który wolisz i dlaczego?

Odpowiedz

3

Tak, pierwszy zdecydowanie lepszy. Nigdy nie wybrałbym drugiej metody. Ale powinieneś pomyśleć o użyciu polimorfizmu więcej. Poleganie na instanceof tak ciężko nie jest dobrym projektem OO.

+2

Niezły punkt, który mógłby uczynić go jeszcze czystszym. Ale wtedy możesz potrzebować wspólnego interfejsu, takiego jak prepareForJourney(), który może być oddzielnie przypisywany w każdej klasie. Jednak często pracujemy z klasami zewnętrznymi lub starszymi, które mogą nie zapewniać łatwego stosowania nowego interfejsu, ale przypuszczam, że można je zawinąć i zastosować interfejs do opakowania. – crowne

8

Preferuję pierwszą wersję ze wszystkich powodów, o których wspomniałeś. W szczególności (aby przeliterować czwarty punkt), oznacza to, że zdecydowanie uzyskasz spójne wyniki ... możesz uzyskać straszliwe paskudne wyniki w drugiej wersji, jeśli getVehicle() zwrócił Car przy pierwszym połączeniu, a następnie Bike na drugi ...

Strona wydajności nie przeszkadza mi (na przykład z przyjemnością nazywam List.size()), ale czytelność, spójność i brak powtarzania są o wiele ważniejsze. Zasadniczo pierwszy fragment przekazuje ideę "uzyskania wartości, a następnie jej użycia" o wiele skuteczniej niż druga.

Więc tak, jestem z tobą ... Czy ktoś poleca ci drugi formularz?

+1

Wierzę, że Martin Fowler zaleca drugi formularz, aby ułatwić refaktoryzację. (Moim zdaniem refaktoryzacja powinna uczynić kod łatwiejszym do naśladowania, a nie trudniejszym.) –

+0

@Jon, czy zrobiłbyś to samo z właściwością w C#? – finnw

+0

Widziałem zwolenników wywołań metod gettera w tym wątku http://stackoverflow.com/questions/1923795/java-method-invocation-vs-using-a-variable – crowne

1

Zgadzam się, ale staram się również ograniczyć użycie "instanceof" również na poziomie klasy.

1

Osobiście uważam, że pierwszy jest czystszy. Jednak pod warunkiem, że wywoływana metoda nie jest czymś intensywnym, nie ma znaczenia.

Prawdopodobnie drugi jest nieco szybszy (jeśli używasz Java 1.6), ponieważ w pierwszym przykładzie tworzysz kopię zmiennej, podczas gdy maszyna wirtualna Java będzie prawdopodobnie wstawiać wywołanie funkcji w obu przykładach. Oczywiście optymalizacja nigdy nie jest argumentem za takimi połączeniami. Kompilator wykonuje tak wiele optymalizacji, że nie powinniśmy się przejmować (często po prostu zmniejszy prędkość, ponieważ nie znamy go wystarczająco dobrze).

2

Zazwyczaj nie podoba mi się wprowadzenie dodatkowych zmiennych, ponieważ każda odrobina dodanego stanu sprawia, że ​​metoda jest bardziej złożona. Ale nawet powiedziałbym, że jest to uzasadnione w twoim przykładzie, ponieważ zmienna zastępuje 4 powtórzenia identycznego kodu.

Ale zmienna zdecydowanie powinna być final!

+1

+1 dla "końcowego". – uckelman

1

Jak wszyscy, którzy odpowiedzieli na to pytanie do tej pory, zdecydowanie wolę pierwszy styl. Może być jeszcze czystsze:

Vehicle vehicle = person.getVehicle() 
if (vehicle instanceof Car) { 
    ((Car) vehicle).openSunroof(); 
} else if (vehicle instanceof Bike) { 
    ((Bike) vehicle).foldKickstand(); 
} 
1

Oba przykłady wymagają trochę pracy. Spróbuj popchnąć to zachowanie w abstrakcyjną (lub chronioną) metodę w Pojeździe.Jeśli tego kodu nie można zmodyfikować, użyj składu, aby umieścić go w interfejsie w bazie kodu, aby nie trzeba było zanieczyszczać reszty kodu słabym wyglądem używanej biblioteki. To zdecydowanie jest zapach kodu. Zobacz "Zastąpienie warunkowe polimorfizmem" w książce Refowling Fowlera.