Jaka jest prawdziwa (tj. Praktyczna) różnica między klasą statyczną a wzorem singletonu?
Oba mogą być wywoływane bez tworzenia instancji, oba zapewniają tylko jedno „wystąpienie” i żadne z nich nie jest bezpieczne dla wątków. Czy jest jakaś inna różnica?
design-patterns
static
singleton
Jorge Córdoba
źródło
źródło
getInstance()
metody za każdym razem, gdy chcesz jej użyć (chociaż prawdopodobnie w większości przypadków nie ma to znaczenia ).singleton
obiekt, w którymstatic
metody są tylko funkcjami, byt nie będący jednostką organizacyjną.Odpowiedzi:
Co sprawia, że mówisz, że metoda singletonowa lub statyczna nie jest bezpieczna dla wątków? Zwykle oba powinny być implementowane, aby były bezpieczne dla wątków.
Duża różnica między singletonem a garstką metod statycznych polega na tym, że singletony mogą implementować interfejsy (lub czerpać z użytecznych klas bazowych, choć z mojego doświadczenia jest to mniej powszechne), więc możesz ominąć singleton tak, jakby był „tylko kolejnym” " realizacja.
źródło
Foo
i masz metodę przyjmującąFoo
jako parametr. Przy takiej konfiguracji dzwoniący mogą wybrać użycie singletonu jako implementacji - lub mogą użyć innej implementacji. Metoda jest oddzielona od singletonu. Porównaj to z sytuacją, w której klasa ma tylko metody statyczne - każdy fragment kodu, który chce wywołać te metody, jest ściśle powiązany z klasą, ponieważ musi określić, która klasa zawiera metody statyczne.Prawdą jest odpowiedź Jona Skeeta na innym forum tutaj .
źródło
interface
klasę Singleton, ale metody statyczne klasy (lub np. C #static class
) nie mogą.źródło
Wzorzec Singleton ma kilka zalet w stosunku do klas statycznych. Po pierwsze, singleton może rozszerzać klasy i implementować interfejsy, podczas gdy klasa statyczna nie może (może rozszerzać klas, ale nie dziedziczy członków ich instancji). Singleton może być inicjowany leniwie lub asynchronicznie, podczas gdy klasa statyczna jest generalnie inicjalizowana podczas pierwszego ładowania, co prowadzi do potencjalnych problemów z modułem ładującym klasy. Jednak najważniejszą zaletą jest to, że singletony można przetwarzać polimorficznie, nie zmuszając ich użytkowników do założenia, że istnieje tylko jedna instancja.
źródło
static
klasy nie są dla niczego, co wymaga stanu. Jest to przydatne do łączenia wielu funkcji razemMath
( tj. (LubUtils
w projektach). Więc nazwa klasy daje nam jedynie wskazówkę, gdzie możemy znaleźć funkcje i nic więcej.Singleton
to mój ulubiony wzór i używam go do zarządzania czymś w jednym punkcie. Jest bardziej elastyczny niżstatic
klasy i może utrzymać swój stan. Może implementować interfejsy, dziedziczyć z innych klas i zezwalać na dziedziczenie.Moja zasada wyboru między
static
isingleton
:Jeśli jest kilka funkcji, które powinny być trzymane razem, to
static
jest wybór. Wszystko inne, co wymaga pojedynczego dostępu do niektórych zasobów, można zaimplementować jakosingleton
.źródło
State
jest kombinacją różnych właściwości obiektu, które zwykle zmieniają się w czasie. Możesz Google formalnie zdefiniować.Klasa statyczna: -
Nie można utworzyć wystąpienia klasy statycznej.
Ładowane automatycznie przez środowisko uruchomieniowe języka wspólnego (CLR) .NET Framework po załadowaniu programu lub przestrzeni nazw zawierającej klasę.
Klasa statyczna nie może mieć konstruktora.
Nie możemy przekazać klasy statycznej do metody.
Nie możemy dziedziczyć klasy statycznej na inną klasę statyczną w języku C #.
Klasa posiadająca wszystkie metody statyczne.
Lepsza wydajność (metody statyczne są powiązane w czasie kompilacji)
Singel:-
Możesz utworzyć jedną instancję obiektu i użyć go ponownie.
Instancja Singleton jest tworzona po raz pierwszy na żądanie użytkownika.
Klasa Singleton może mieć konstruktor.
Możesz utworzyć obiekt klasy singleton i przekazać go do metody.
Klasa Singleton nie mówi o żadnym ograniczeniu dziedziczenia.
Możemy pozbyć się obiektów klasy singleton, ale nie klasy statycznej.
Metody można zastąpić.
Może być ładowany leniwie, gdy jest to potrzebne (klasy statyczne są zawsze ładowane)
Możemy zaimplementować interfejs (klasa statyczna nie może zaimplementować interfejsu).
źródło
Klasa statyczna to taka, która ma tylko metody statyczne, dla których lepszym słowem byłyby „funkcje”. Styl projektowania zawarty w klasie statycznej jest czysto proceduralny.
Singleton jest natomiast wzorem charakterystycznym dla projektu OO. Jest to instancja obiektu (ze wszystkimi związanymi z tym możliwościami, takimi jak polimorfizm), z procedurą tworzenia, która zapewnia, że istnieje tylko jedna instancja tej konkretnej roli przez cały okres jej istnienia.
źródło
We wzorze singletonu możesz utworzyć singleton jako instancję typu pochodnego, nie możesz tego zrobić z klasą statyczną.
Szybki przykład:
źródło
Aby rozwinąć odpowiedź Jona Skeeta
Singletony są łatwiejsze w pracy, gdy jednostka testuje klasę. Za każdym razem, gdy przekazujesz singletony jako parametr (konstruktory, setery lub metody), możesz zamiast tego zastąpić fałszywą lub skrótową wersję singletonu.
źródło
MySingleton mockOfMySingleton = mock(MySingleton.class)
.new ClazzToTest(mockSingleton);
Oto dobry artykuł: http://javarevisited.blogspot.com.au/2013/03/difference-between-singleton-pattern-vs-static-class-java.html
Klasy statyczne
nie może przesłonić metod, ale może używać ukrywania metod. ( Co to jest metoda ukrywania w Javie? Nawet wyjaśnienie JavaDoc jest mylące )
Singel
Podsumowując, używałbym klas statycznych tylko do przechowywania metod util i używania Singleton do wszystkiego innego.
Edycje
klasy statyczne są również ładowane z opóźnieniem. Dzięki @jmoreno ( Kiedy następuje inicjalizacja klasy statycznej? )
ukrywanie metod dla klas statycznych. Dzięki @MaxPeng.
źródło
Animal animal = new Cat();
potemanimal.foo();
co się dzieje?Kolejną zaletą singletona jest to, że można go łatwo serializować, co może być konieczne, jeśli trzeba zapisać jego stan na dysku lub wysłać go gdzieś zdalnie.
źródło
Nie jestem wielkim teoretykiem OO, ale z tego co wiem, myślę, że jedyną cechą OO, której brakuje klas statycznych w porównaniu do Singletonów, jest polimorfizm. Ale jeśli go nie potrzebujesz, dzięki statycznej klasie możesz oczywiście dziedziczyć (nie jestem pewien co do implementacji interfejsu) oraz hermetyzować dane i funkcje.
Komentarz Morendila: „Styl projektowania ujęty w klasie statycznej jest czysto proceduralny” Mogę się mylić, ale się nie zgadzam. W metodach statycznych można uzyskać dostęp do elementów statycznych, które byłyby dokładnie takie same, jak metody singletonowe uzyskujące dostęp do elementów pojedynczej instancji.
edytuj:
Właściwie myślę teraz, że inną różnicą jest to, że klasa Statyczna jest tworzona przy starcie programu * i żyje przez cały okres życia programu, podczas gdy singleton jest wyraźnie tworzony w pewnym momencie i również może zostać zniszczony.
* lub może wystąpić przy pierwszym użyciu, zależnie od języka, tak myślę.
źródło
Aby zilustrować punkt Jona, co pokazano poniżej, nie można tego zrobić, jeśli Logger był klasą statyczną. Klasa
SomeClass
oczekuje, że instancjaILogger
implementacji zostanie przekazana do jej konstruktora.Klasa Singleton jest ważna, aby możliwe było wstrzyknięcie zależności.
źródło
Cóż, singleton jest zwykłą klasą, która jest instowana, ale tylko raz i pośrednio z kodu klienta. Klasa statyczna nie jest tworzona. O ile wiem metody statyczne (klasa statyczna musi mieć metody statyczne) są szybsze niż metody niestatyczne.
Edycja:
FxCop Opis reguły wydajności: „Metody, które nie uzyskują dostępu do danych instancji lub metod instancji wywołania, mogą być oznaczone jako statyczne (współużytkowane w VB). Po wykonaniu tej czynności kompilator wyśle do tych członków nie wirtualne witryny wywołujące, co zapobiegnie sprawdzanie w czasie wykonywania każdego wywołania, które zapewnia, że bieżący wskaźnik obiektu nie ma wartości zerowej. Może to spowodować wymierny wzrost wydajności kodu wrażliwego na wydajność. W niektórych przypadkach brak dostępu do bieżącej instancji obiektu oznacza problem z poprawnością. ”
Nie wiem, czy dotyczy to również metod statycznych w klasach statycznych.
źródło
Instancje Singletona są tworzone, to tylko jedna instancja kiedykolwiek stworzona, stąd singiel w Singleton.
Klasa statyczna nie może być utworzona przez nic innego niż siebie.
źródło
Główne różnice to:
źródło
Singleton jest lepszym podejściem z perspektywy testowania. W przeciwieństwie do klas statycznych, singleton może implementować interfejsy i można użyć próbnej instancji i wstrzyknąć je.
W poniższym przykładzie zilustruję to. Załóżmy, że masz metodę isGoodPrice (), która używa metody getPrice () i implementujesz getPrice () jako metodę w singletonie.
singleton zapewniający funkcjonalność getPrice:
Korzystanie z getPrice:
Ostateczne wdrożenie Singleton:
klasa testowa:
W przypadku, gdy skorzystamy z alternatywnej metody statycznej do implementacji metody getPrice (), trudno było naśladować metodę getPrice (). Można kpić z elektryczności statycznej, ale nie wszystkie produkty mogą z niego korzystać.
źródło
Zgadzam się z tą definicją:
Można znaleźć inne interesujące różnice dotyczące: Wzorca singletonu a klasy statycznej
źródło
Jedną zauważalną różnicą jest różna instancja, która pochodzi z Singletonów.
W przypadku klas statycznych jest on tworzony przez CLR i nie mamy nad nim kontroli. w przypadku singletonów obiekt jest tworzony w pierwszej instancji, do której próbowano uzyskać dostęp.
źródło
W wielu przypadkach te dwa nie mają praktycznej różnicy, szczególnie jeśli instancja singletonu nigdy się nie zmienia lub zmienia bardzo powoli, np. Konfiguracje utrzymywania.
Powiedziałbym, że największą różnicą jest to, że singleton jest nadal normalną Java Bean, w przeciwieństwie do wyspecjalizowanej klasy Java tylko statycznej. Z tego powodu singleton jest akceptowany w wielu innych sytuacjach; w rzeczywistości jest to domyślna strategia tworzenia instancji Spring Framework. Konsument może, ale nie musi wiedzieć, że jest to singleton przekazywany dookoła, po prostu traktuje to jak zwykłą fasolę Java. Jeśli zmieniają się wymagania, a singleton zamiast tego musi stać się prototypem, jak to często widzimy na wiosnę, można to zrobić całkowicie bezproblemowo, bez zmiany linii kodu dla konsumenta.
Ktoś inny wspomniał wcześniej, że klasa statyczna powinna mieć charakter czysto proceduralny, np. Java.lang.Math. Moim zdaniem, taka klasa nigdy nie powinna być przekazywana i nigdy nie powinna przyjmować niczego innego jak statyczny finał jako atrybuty. Do wszystkiego innego użyj singletona, ponieważ jest on znacznie bardziej elastyczny i łatwiejszy w utrzymaniu.
źródło
Dysponujemy strukturą DB, która zapewnia połączenia z zapleczem. Aby uniknąć brudnych odczytów u wielu użytkowników, użyliśmy wzorca singletonu, aby zapewnić dostępność pojedynczej instancji w dowolnym momencie.
W c # klasa statyczna nie może implementować interfejsu. Kiedy klasa pojedynczej instancji musi zaimplementować interfejs dla umów biznesowych lub celów IoC, tutaj używam wzorca Singleton bez klasy statycznej
Singleton zapewnia sposób na utrzymanie stanu w scenariuszach bezstanowych
Mam nadzieję, że to pomoże ..
źródło
źródło
za. Serializacja - członkowie statyczni należą do klasy i dlatego nie można ich serializować.
b. Chociaż ustawiliśmy konstruktor jako prywatny, statyczne zmienne składowe nadal będą przenoszone do podklasy.
do. Nie możemy wykonać leniwej inicjalizacji, ponieważ wszystko zostanie załadowane tylko podczas ładowania klasy.
źródło
Z perspektywy klienta zachowanie statyczne jest znane klientowi, ale zachowanie Singleton można wykonać ukryte przed klientem. Klient może nigdy nie wiedzieć, że jest tylko jedna instancja, z którą wciąż się bawi.
źródło
Przeczytałem następujące i myślę, że to też ma sens:
z książki Objected-Oriented Thought Process 4th Ed.
źródło
W artykule, który napisałem, opisałem swój punkt widzenia na temat tego, dlaczego singleton jest znacznie lepszy niż klasa statyczna:
źródło
Możemy stworzyć obiekt klasy singleton i przekazać go do metody.
Klasa Singleton nie ma żadnych ograniczeń dziedziczenia.
Nie możemy pozbywać się obiektów klasy statycznej, ale możemy singletonować.
źródło
Odróżnienie od klasy statycznej
JDK ma przykłady zarówno singletonu, jak i static, z jednej strony
java.lang.Math
jest klasą końcową z metodami static, z drugiej stronyjava.lang.Runtime
jest klasą singleton.Zalety singletonu
Jeśli potrzeba utrzymania stanu niż wzorca singletonu jest lepszym wyborem niż klasa statyczna, ponieważ utrzymanie stanu w klasie statycznej prowadzi do błędów, szczególnie w środowisku współbieżnym, które mogą prowadzić do warunków wyścigu bez odpowiedniej równoległej modyfikacji synchronizacji przez wiele wątków.
Klasa Singleton może być leniwie ładowana, jeśli jest ciężkim obiektem, ale klasa statyczna nie ma takich zalet i zawsze chętnie się ładuje.
Dzięki singletonowi możesz wykorzystać dziedziczenie i polimorfizm, aby rozszerzyć klasę bazową, zaimplementować interfejs i zapewnić różne implementacje.
Ponieważ metod statycznych w Javie nie można zastąpić, prowadzą one do nieelastyczności. Z drugiej strony możesz przesłonić metody zdefiniowane w klasie singleton, rozszerzając ją.
Wady klasy statycznej
Zalety klasy statycznej
Istnieje kilka realizacji wzoru singletonu, z których każdy ma zalety i wady.
Szczegółowy opis każdego z nich jest zbyt szczegółowy, więc po prostu umieszczam link do dobrego artykułu - Wszystko, co chcesz wiedzieć o Singleton
źródło
Istnieje ogromna różnica między pojedynczym wystąpieniem klasy statycznej (to znaczy pojedynczym wystąpieniem klasy, która okazuje się zmienną statyczną lub globalną) a pojedynczym wskaźnikiem statycznym do wystąpienia klasy na stercie:
Po zamknięciu aplikacji zostanie wywołany destruktor instancji klasy statycznej. Oznacza to, że jeśli użyłeś tego statycznego wystąpienia jako singletonu, twój singleton przestanie działać poprawnie. Jeśli nadal działa kod korzystający z tego singletonu, na przykład w innym wątku, kod może ulec awarii.
źródło
Różnica w mojej głowie polega na wdrażaniu programowania obiektowego (Singleton / Prototype) lub programowania funkcjonalnego (Static).
Jesteśmy zbyt skupieni na liczbie obiektów utworzonych przez wzorzec singletonu, kiedy powinniśmy się skupić na tym, że w końcu trzymamy obiekt. Jak inni już powiedzieli, można go rozszerzyć, przekazać jako parametr, ale co najważniejsze, jest on pełny.
Z drugiej strony statyczny służy do implementacji programowania funkcjonalnego. Elementy statyczne należą do klasy. Są bezpaństwowcami.
Nawiasem mówiąc, czy wiesz, że możesz tworzyć pojedyncze klasy statyczne :)
źródło