Programuję w Javie i zawsze tworzę konwertery w taki sposób:
public OtherObject MyObject2OtherObject(MyObject mo){
... Do the conversion
return otherObject;
}
W nowym miejscu pracy wzór jest następujący:
public void MyObject2OtherObject(MyObject mo, OtherObject oo){
... Do the conversion
}
Dla mnie jest to trochę śmierdzące, ponieważ przyzwyczaiłem się nie zmieniać przychodzących parametrów. Czy ta przychodząca zmiana parametru jest antypatternem, czy jest w porządku? Czy ma jakieś poważne wady?
java
clean-code
anti-patterns
CsBalazsHungary
źródło
źródło
oo
jest to obiekt przekazywany do metody, a nie wskaźnik ustawiony na nowy obiekt. Czy tak jest w tym przypadku? Jeśli jest to Java, prawdopodobnie tak jest, jeśli nie jest to C ++Odpowiedzi:
To nie jest antypattern, to zła praktyka.
Różnica między antypatternem a zwykłą złą praktyką jest tutaj: definicja anty-wzorca .
Nowy styl pracy, który pokazujesz, to zła praktyka , czas szczątkowy lub czas przed OOP, zgodnie z Clean Code wuja Boba.
źródło
OtherObject
interfejs? Tylko osoba dzwoniąca (miejmy nadzieję) wie, jaki konkretny typ chce.Cytując słynną książkę Roberta C. Martina „Clean Code”:
Drugi wzorzec narusza obie reguły, szczególnie „argument wyjściowy”. W tym sensie jest gorszy niż pierwszy wzór.
źródło
Drugi idiom może być szybszy, ponieważ program wywołujący może ponownie użyć jednej zmiennej w długiej pętli, zamiast każdej iteracji tworząc nową instancję.
Na ogół nie używałbym tego, ale np. w programowaniu gier ma swoje miejsce. Na przykład spójrz na wiele operacji Java3Mon Vector3f pozwala na przekazanie instancji, którą należy zmodyfikować i zwrócić jako wynik.
źródło
Nie sądzę, że są to dwa równoważne fragmenty kodu. W pierwszym przypadku musisz utworzyć
otherObject
. Możesz zmodyfikować istniejącą instancję w drugim. Oba mają swoje zastosowania. Zapach kodu wolałby jeden od drugiego.źródło
To naprawdę zależy od języka.
W Javie druga postać może być anty-wzorcem, ale niektóre języki traktują przekazywanie parametrów inaczej. Ada i VHDL na przykład, zamiast przejść obojętnie wartość lub przez odwołanie, parametry mogą mieć tryby
in
,out
alboin out
.Błędem jest zmodyfikowanie
in
parametru lub odczytanieout
parametru, ale wszelkie zmianyin out
parametru są przekazywane z powrotem do programu wywołującego.Tak więc dwie formy w Adzie (są to również legalne VHDL)
i
Oba mają swoje zastosowania; procedura może zwrócić wiele wartości w wielu
Out
parametrach, podczas gdy funkcja może zwrócić tylko jeden wynik. Ponieważ cel drugiego parametru jest jasno określony w deklaracji procedury, nie można wnieść sprzeciwu wobec tego formularza. Wolę tę funkcję ze względu na czytelność. ale będą przypadki, w których procedura jest lepsza, np. gdy obiekt wywołujący już utworzył obiekt.źródło
Rzeczywiście wydaje się śmierdzący i bez większego kontekstu nie można tego powiedzieć na pewno. Mogą to być dwa powody, chociaż istnieją alternatywy dla obu.
Po pierwsze, jest to zwięzły sposób na implementację częściowej konwersji lub pozostawienie wyniku z wartościami domyślnymi, jeśli konwersja się nie powiedzie. Oznacza to, że możesz mieć to:
Oczywiście zwykle odbywa się to za pomocą wyjątków. Jednak nawet jeśli z jakiegokolwiek powodu należy unikać wyjątków, istnieje na to lepszy sposób - wzorzec TryParse jest jedną z opcji.
Innym powodem może być czysta spójność, na przykład jest to część publicznego interfejsu API, w którym ta metoda jest używana do wszystkich funkcji konwersji z dowolnego powodu (takich jak inne funkcje konwersji posiadające wiele danych wyjściowych).
Java nie jest świetna w radzeniu sobie z wieloma wyjściami - nie może mieć parametrów tylko wyjściowych, takich jak niektóre języki, ani mieć wielu wartości zwracanych, jak inne - ale nawet można użyć obiektów zwracanych.
Powód spójności jest raczej kiepski, ale niestety może być najczęstszy.
źródło
Zaletą drugiego wzorca jest to, że zmusza on osobę dzwoniącą do przejęcia odpowiedzialności za utworzony obiekt. Nie ma wątpliwości, czy metoda utworzyła obiekt, czy pobrała go z puli wielokrotnego użytku. Dzwoniący wie, że jest odpowiedzialny za czas życia i utylizację nowego obiektu.
Wady tej metody to:
OtherObject
i musi go wcześniej zbudować.MyObject
.OtherObject
musi być możliwy do zbudowania bez wiedzy o nimMyObject
.Odpowiedź oparta jest na moim doświadczeniu w c #, mam nadzieję, że logika przełoży się na Javę.
źródło
Biorąc pod uwagę luźną semantykę -
myObjectToOtherObject
może również oznaczać, że przenosisz niektóre dane z pierwszego obiektu do drugiego lub że przekształcisz je całkowicie od nowa, druga metoda wydaje się bardziej odpowiednia.Gdyby jednak nazwa metody to
Convert
(co powinno być, jeśli spojrzymy na część „... wykonaj konwersję”), powiedziałbym, że druga metoda nie miałaby żadnego sensu. Nie zamieniasz wartości na inną wartość, która już istnieje, IMO.źródło