Niedawno przeprowadziłem refaktoryzację średniego projektu w Javie, aby wrócić i dodać testy jednostkowe. Kiedy zdałem sobie sprawę, jak trudny jest kpić z singletonów i statyki, w końcu „zrozumiałem” o nich przez cały ten czas. (Jestem jedną z tych osób, które muszą uczyć się z doświadczenia. No cóż.)
Teraz, kiedy używam Sprężyny do tworzenia obiektów i łączenia ich, pozbywam się static
słów kluczowych w lewo i w prawo. (Gdybym mógł potencjalnie chcieć się z niego kpić, to nie jest tak naprawdę statyczny w tym samym sensie, co Math.abs (), prawda?) Chodzi o to, że przyzwyczaiłem się używać static
do oznaczania, że metoda nie była oparta w dowolnym stanie obiektu. Na przykład:
//Before
import com.thirdparty.ThirdPartyLibrary.Thingy;
public class ThirdPartyLibraryWrapper {
public static Thingy newThingy(InputType input) {
new Thingy.Builder().withInput(input).alwaysFrobnicate().build();
}
}
//called as...
ThirdPartyLibraryWrapper.newThingy(input);
//After
public class ThirdPartyFactory {
public Thingy newThingy(InputType input) {
new Thingy.Builder().withInput(input).alwaysFrobnicate().build();
}
}
//called as...
thirdPartyFactoryInstance.newThingy(input);
Oto, gdzie robi się drażniąco. Podobał mi się stary sposób, ponieważ wielka litera powiedziała mi, że podobnie jak Math.sin (x), ThirdPartyLibraryWrapper.newThingy (x) za każdym razem robił to samo. Nie ma stanu obiektu, który mógłby zmienić sposób, w jaki obiekt robi to, o co go proszę. Oto kilka możliwych odpowiedzi, które rozważam.
- Nikt inny tak się nie czuje, więc coś jest ze mną nie tak. Może po prostu tak naprawdę nie zinternalizowałem sposobu robienia OO! Może piszę w Javie, ale myślę w FORTRAN lub coś takiego. (Co byłoby imponujące, ponieważ nigdy nie napisałem FORTRAN.)
- Może używam statyczności jako pewnego rodzaju proxy dla niezmienności dla celów rozumowania na temat kodu. Biorąc to pod uwagę, jakie wskazówki powinienem mieć w swoim kodzie, aby ktoś przybył, aby utrzymać go, aby wiedzieć, co jest stanowe, a co nie?
- Być może powinno to być darmowe, jeśli wybiorę dobre metafory obiektów? np.
thingyWrapper
nie wydaje się, że ma stan niezależny od owiniętego,Thingy
który sam może być zmienny. Podobnie,thingyFactory
dźwięki takie powinny być niezmienne, ale mogą mieć różne strategie wybrane spośród stworzenia.
Moim zdaniem to, co mówisz - wszystkie funkcje statyczne, które mają być nullipotentne - jest dobrym sposobem na pisanie kodu w większości przypadków, ale nie wierzę, że patrząc na funkcję statyczną, należy automatycznie założyć, że nie ma ona skutków ubocznych . Sytuacja może być bardziej złożona; weźmy na przykład funkcję,
Class.forName(String)
która wydaje się być bezstanowa, ale w rzeczywistości ładuje klasę do pamięci i ostatecznie tworzy instancję pól statycznych / uruchamia inicjalizator statyczny; jest to przykład funkcji idempotentnej (ewentualne wywołania po pierwszej nie mają znaczenia), ale nie jest to funkcja czysta (nie można powiedzieć, że nie ma skutków ubocznych). Jest to również dobry wybór, ale mogą zdarzyć się przypadki, w których trzy różne wywołania tej samej funkcji dadzą trzy różne wyniki; na przykład, jeśli zadzwoniszThread.currentThread()
w aplikacji wielowątkowej nie ma gwarancji, że za każdym razem otrzymasz ten sam wątek.Właściwym rozwiązaniem jest dokumentowanie (na przykład Javadoc); także z nazwy funkcji i jej działania można czasem wywnioskować, że funkcja statyczna jest funkcją czystą. Na przykład nie ma powodu, aby ktoś wierzył, że
Assert.assertTrue(boolean)
z JUnit zmieniłby gdzieś jakiś stan. Z drugiej strony, gdySystem.clearProperty(String)
wywoływana jest taka funkcja , jest całkiem oczywiste, że wystąpią skutki uboczne.źródło
Możesz ustawić je statycznie. FxCop w świecie C # popchnie cię do uczynienia rzeczy statycznymi, które nie powodują zmiennych elementów referencyjnych. Jest to właściwe postępowanie (zwykle).
Przeniesienie ich wszystkich do instancji może być niewłaściwe. Zamiast tego oddzielić zależności od metod statycznych od klas, które ich używają. Możesz przetestować metody statyczne w izolacji, a następnie zastąpić zależność od konsumentów, kiedy będą musieli zostać przetestowani.
źródło