Kiedy i jak powinniśmy używać konstruktora
Foo bar = new Foo();
A kiedy i jak powinniśmy używać getInstance () (statyczne metody fabryczne)
Foo bar = Foo.getInstance();
Jaka jest różnica między tymi dwoma? Zawsze używałem konstruktora, ale kiedy powinienem użyć getInstance()
zamiast niego?
getInstance()
, czy może pisać metodę o nazwiegetInstance()
?Foo.newInstance()
.Foo.getInstance()
jest konwencją uzyskiwania pojedynczej instancji klasy. Powinieneś poprawić swój przykład i użyćFoo.newInstance()
zamiast tego.Odpowiedzi:
Wydaje się, że wszyscy skupiają się na singletonach, podczas gdy ja myślę, że tak naprawdę pytanie dotyczy konstruktora kontra statyczne metody fabryczne .
To jest rzeczywiście Pozycja 1: Rozważmy statycznych metod fabrycznych zamiast konstruktorów z Effective Java przez Joshua Bloch:
Zalety (cytując książkę):
Wady (nadal cytując książkę):
źródło
protected
umożliwiać tworzenie podklas, ale czy kod klienta uzyskuje jakąkolwiek rzeczywistą korzyść z tworzenia nowego obiektu i wywoływania jego konstruktora w porównaniu z wywołaniem statycznej metody fabrycznej? Wydaje mi się, że wywołanie konstruktora w łańcuchu jest semantycznie metodą instancji, podczas gdy sekwencja „utwórz obiekt zjednostkowany i wywołaj jego konstruktor” jest semantycznie równoważna wywołaniu metody statycznej fabryki.Masz dwa pytania: kiedy należy zadzwonić do
getInstance()
metody, i kiedy należy utworzyć jeden?Jeśli decydując czy zadzwonić
getInstance()
metoda, to proste. Wystarczy przeczytać dokumentację klasy, aby dowiedzieć się, kiedy należy to wywołać. Na przykład,NumberFormat
przewiduje konstruktora i wgetInstance()
sposób;getInstance()
metoda daje zlokalizowaneNumberFormat
. ZCalendar
drugiej strony konstruktor jest chroniony. Ty masz zadzwonićgetInstance()
, aby uzyskać jeden.Jeśli jesteś podejmowaniu decyzji, czy do tworzenia się
getInstance()
metodę, trzeba zdecydować, co chcesz osiągnąć. Albo nie chcesz, aby ludzie dzwonili do twojego konstruktora (tworzysz singleton lub fabrykę ), albo nie masz nic przeciwko (jakNumberFormat
powyżej, gdzie inicjują niektóre obiekty dla wygody wywołującego).Krótko mówiąc? Nie martw się o tworzenie
getInstance()
metod we własnym kodzie. Jeśli nadejdzie czas, kiedy będą przydatne, będziesz wiedział. A w ogóle, jeśli można wywołać konstruktora klasy jest, jesteś prawdopodobnie powinien tego robić, nawet jeśli klasa udostępniagetInstance()
metody.źródło
Zastosowania metod getInstance:
Ale przez większość czasu twój obiekt będzie prostym POJO, a użycie publicznych konstruktorów jest najbardziej praktycznym i oczywistym rozwiązaniem.
U1: getInstance z innej klasy
Aby zwrócić instancję innej klasy:
public class FooFactory { public static Foo getInstance() { return new Foo(); } }
NumberFormat.getInstance
metody robią to, ponieważ w rzeczywistości zwracają wystąpieniaDecimalFormat
.U2: Problemy singletonów
Wzorzec singleton ogranicza wiele zalet programowania obiektowego. Singletony generalnie mają prywatne konstruktory, dlatego nie można ich rozszerzać. Ponieważ będziesz uzyskiwać do niego dostęp za pomocą metody getInstance i nie będziesz odnosić się do żadnego interfejsu, nie będziesz mógł zamienić go na inną implementację.
źródło
Jeśli możesz użyć obu, to brzmi to jak źle zaimplementowany wzorzec singletona .
Użyj drugiej opcji, jeśli zamierzasz mieć tylko jedną instancję klasy w swoim systemie i ustaw konstruktor jako prywatny.
Użyj pierwszego, aby umożliwić zbudowanie kilku obiektów tej klasy.
ALE nie dawaj swojej klasie obu możliwości.
Uważaj, aby nie nadużywać singletonów, używaj ich tylko wtedy, gdy naprawdę ma istnieć tylko jedna instancja w systemie, w przeciwnym razie ograniczysz możliwości ponownego wykorzystania swojej klasy w innych projektach. Możliwość wywoływania getInstance z dowolnego miejsca w projekcie brzmi interesująco, ale nie jest jasne, kto faktycznie jest właścicielem tej instancji: nikt i / lub wszyscy. Jeśli masz dużo singletonów w projekcie, możesz się założyć, że system jest źle zaprojektowany (zazwyczaj). Singletonów należy używać ostrożnie, obowiązują te same rady, co w przypadku zmiennych globalnych.
źródło
Jednym z przypadków, w których zawsze wolę statyczną fabrykę od zwykłego konstruktora, jest sytuacja, gdy wiem, że budowa obiektu będzie powolna. Wykonuję prostą inicjalizację na konstruktorze, ale jeśli muszę stworzyć coś ciężkiego, użyję metody statycznej i udokumentuję zachowanie.
źródło
Singletony są złe. Problemy, które widziałem, nie dotyczą ponownego wykorzystania lub rozszerzalności systemu (chociaż mogłem zobaczyć, jak to może się zdarzyć), a tym bardziej, że nie mogę policzyć, ile razy widziałem niejasne błędy w system, który powstaje z singletonów.
Jeśli potrzebujesz użyć singletona, upewnij się, że jego zakres jest bardzo wąski, tj. Rozsądnie ogranicz liczbę innych obiektów w systemie, które o nim wiedzą.
źródło