Ponadto Singleton jest jednym z najczęściej używanych i nadużywanych wzorców projektowych w programowaniu OO.
ChaosPandion
3
@Fabiano: Ponieważ ma sposób na tworzenie połączeń, które nie mają sensu (jak mogę Xrozmawiać Y? Po prostu zrób Ysingleton!), Co z kolei prowadzi do trudności w testowaniu / debugowaniu i proceduralnym stylu programowania. Czasami konieczne są Singletony; przez większość czasu nie.
Aaronaught
3
To jedno z moich standardowych pytań do rozmowy telefonicznej. Prawidłowa odpowiedź to: nigdy.
jonnii
3
@jonnii to dobrze, pomaga ostrzec potencjalnych programistów, jaki jest szef!
Mr. Boy
Odpowiedzi:
144
Singleton to klasa, która pozwala na utworzenie tylko jednej instancji samego siebie - i daje prosty, łatwy dostęp do tej instancji. Założeniem singletonu jest wzorzec rozwoju oprogramowania.
Istnieje implementacja C # „Implementacja wzorca Singleton w C #” obejmująca większość tego, co musisz wiedzieć - w tym kilka dobrych rad dotyczących bezpieczeństwa wątków .
Szczerze mówiąc, bardzo rzadko trzeba wdrożyć singletona - moim zdaniem powinna to być jedna z tych rzeczy, o których powinieneś wiedzieć, nawet jeśli nie jest to używane zbyt często.
fajny samouczek, ale cholera, co zrobili z wcięciem kodu
Inspi
Oto bardziej bezpośredni link do tego, co uważam za idealną implementację w 2020 roku. To znaczy „ przy użyciu typu Lazy <T> .NET 4 ”, a także link do dokumentu Microsoft Doc dla Lazy<T> Class.
nie wątek bezpieczny. dwa wątki mogą wywoływać w tym samym czasie i mogą tworzyć dwa osobne obiekty.
Alagesan Palani,
5
@Alagesan Palani, rzeczywiście masz rację. Nie jestem biegły w szczegółach niskiego poziomu inicjalizacji na poziomie klasy, ale myślę, że wprowadzona przeze mnie zmiana rozwiązuje problem bezpieczeństwa wątków.
Chris Simmons,
3
jasne, NIE sugeruję, że się mylisz. daję wskazówkę czytelnikowi na temat bezpieczeństwa wątków, aby byli ostrożni, gdyby musieli sobie z tym poradzić.
Alagesan Palani,
9
Nie, myślę, że twój komentarz jest ważny. Biorąc pod uwagę, że singleton ma dostarczyć jeden - i tylko jeden - przypadek, warunki wyścigu tutaj otwierają możliwość dostarczenia więcej niż jednego. Zobacz teraz wersję ze statyczną inicjalizacją pola. Wierzę, że to rozwiązuje problem bezpieczeństwa wątków, jeśli poprawnie przeczytam dokumentację i odpowiedź SO .
Chris Simmons,
1
@AlagesanPalani, widzę, że stwierdziłeś, że kilka innych odpowiedzi nie jest bezpiecznych dla wątków. Czy chciałbyś zapewnić rozwiązanie, które jest bezpieczne dla wątków?
Bonez024,
39
Co to jest: Klasa, dla której istnieje tylko jedna, trwała instancja przez cały okres istnienia aplikacji. Zobacz Singleton Pattern .
Kiedy należy go używać: jak najmniej. Tylko wtedy, gdy masz absolutną pewność , że go potrzebujesz. Niechętnie mówię „nigdy”, ale zwykle istnieje lepsza alternatywa, taka jak Dependency Injection lub po prostu klasa statyczna.
Nie jestem pewien, czy klasa statyczna jest lepszą alternatywą niż singleton ... to naprawdę zależy od sytuacji i języka.
marcgg
5
Klasy statyczne nie zachowują się w taki sam sposób jak singleton, singleton można przekazać do metod jako parametr, podczas gdy klasa statyczna nie.
TabbyCool
4
Zgadzam się z marcgg - Nie widzę klasy statycznej jako dobrej alternatywy dla singletonów, ponieważ nadal masz problem z dostarczeniem zamiennika, np. Podczas testowania komponentu zależnego od tej klasy. Ale widzę też różne zastosowania, klasa statyczna byłaby zwykle używana do niezależnych funkcji narzędziowych, które są niezależne od stanu, gdzie singleton jest rzeczywistą instancją klasy i zwykle przechowuje stan. Całkowicie zgadzam się na użycie zamiast tego DI, a następnie mówię Twojemu kontenerowi DI, że chcesz używać tylko jednego wystąpienia tej klasy.
Pete
9
Głosowałem za odpowiedzią, ponieważ nie daje mi ona informacji o tym, kiedy jej użyć. „Tylko wtedy, gdy jest to potrzebne”, tak naprawdę nie daje mi żadnych informacji dla kogoś, kto jest singlem.
Sergio Tapia
9
@Adkins: DI oznacza Dependency Injection, czyli kiedy zależności klas są przekazywane przez (zwykle) konstruktor lub właściwość publiczną. Sam DI nie rozwiązuje problemu „odległości”, ale zwykle jest implementowany wraz z kontenerem Inversion-of-Control (IoC), który wie, jak automatycznie inicjować wszelkie zależności. Więc jeśli tworzysz Singletona w celu rozwiązania problemu „X nie wie, jak znaleźć / rozmawiać z Y”, połączenie DI i IoC może rozwiązać ten sam problem z luźniejszym sprzężeniem.
Aaronaught
27
inny sposób implementacji singletonu w języku c #, osobiście wolę ten sposób, ponieważ można uzyskać dostęp do instancji klasy singeton jako właściwość zamiast metody.
nie wątek bezpieczny. dwa wątki mogą wywoływać w tym samym czasie i mogą tworzyć dwa osobne obiekty.
Alagesan Palani,
11
using System;
using System.Collections.Generic;classMainApp{staticvoidMain(){LoadBalancer oldbalancer =null;for(int i =0; i <15; i++){LoadBalancer balancerNew =LoadBalancer.GetLoadBalancer();if(oldbalancer == balancerNew && oldbalancer !=null){Console.WriteLine("{0} SameInstance {1}", oldbalancer.Server, balancerNew.Server);}
oldbalancer = balancerNew;}Console.ReadKey();}}classLoadBalancer{privatestaticLoadBalancer _instance;privateList<string> _servers =newList<string>();privateRandom _random =newRandom();privatestaticobject syncLock =newobject();privateLoadBalancer(){
_servers.Add("ServerI");
_servers.Add("ServerII");
_servers.Add("ServerIII");
_servers.Add("ServerIV");
_servers.Add("ServerV");}publicstaticLoadBalancerGetLoadBalancer(){if(_instance ==null){lock(syncLock){if(_instance ==null){
_instance =newLoadBalancer();}}}return _instance;}publicstringServer{get{int r = _random.Next(_servers.Count);return _servers[r].ToString();}}}
Wziąłem kod z dofactory.com , nic nadzwyczajnego, ale uważam, że jest to tak dobre, jak przykłady z Foo i Barem, a dodatkowo książka Judith Bishop na temat C # 3.0 Design Patterns zawiera przykład aktywnej aplikacji w Mac Docku.
Jeśli spojrzysz na kod, w rzeczywistości budujemy nowe obiekty dla pętli for , więc tworzy nowy obiekt, ale wykorzystuje ponownie instancję, w wyniku czego oldbalancer i newbalancer mają tę samą instancję. Jak? ze względu na statyczne słowo kluczowe użyte w funkcji GetLoadBalancer () , mimo że ma inną wartość serwera, która jest losową listą, static w GetLoadBalancer () należy do samego typu, a nie do konkretnego obiektu.
Słowo kluczowe lock zapewnia, że jeden wątek nie wchodzi w krytyczną sekcję kodu, podczas gdy inny wątek znajduje się w sekcji krytycznej. Jeśli inny wątek spróbuje wprowadzić zablokowany kod, zaczeka, zablokuje, aż obiekt zostanie zwolniony.
więc za każdym razem wydawana jest blokada wzajemnego wykluczenia, nawet jeśli nie jest to konieczne, więc mamy kontrolę zerową.
Mam nadzieję, że pomoże to w oczyszczeniu więcej.
I proszę o komentarz, jeśli rozumiem, że źle kieruję.
Singleton (i to nie jest związane z C #, to wzorzec projektowy OO) ma miejsce, gdy chcesz zezwolić na utworzenie tylko jednej instancji klasy w całej aplikacji. Zastosowania zwykle obejmowałyby zasoby globalne, chociaż powiem z własnego doświadczenia, bardzo często są źródłem wielkiego bólu.
Chociaż może istnieć tylko jeden przypadek singletonu, nie jest to to samo, co klasa statyczna. Klasa statyczna może zawierać tylko metody statyczne i nigdy nie może być utworzona instancja, natomiast instancja singletonu może być używana w taki sam sposób, jak każdy inny obiekt.
Jest to wzorzec projektowy i nie jest specyficzny dla c #. Więcej o tym w całym Internecie i SO, tak jak w tym artykule na Wikipedii .
W inżynierii oprogramowania wzorzec singletonu jest wzorcem projektowym używanym do ograniczenia tworzenia instancji klasy do jednego obiektu. Jest to przydatne, gdy potrzebny jest dokładnie jeden obiekt do koordynowania działań w całym systemie. Pojęcie to jest czasem uogólnione na systemy, które działają wydajniej, gdy istnieje tylko jeden obiekt lub które ograniczają tworzenie instancji do określonej liczby obiektów (powiedzmy pięć). Niektórzy uważają, że jest to anty-wzorzec, sądząc, że jest nadużywany, wprowadza niepotrzebne ograniczenia w sytuacjach, w których jedna instancja klasy nie jest tak naprawdę wymagana, i wprowadza stan globalny do aplikacji.
Powinieneś go użyć, jeśli chcesz mieć klasę, którą można założyć tylko raz.
Co to jest singleton:
Jest to klasa, która pozwala na utworzenie tylko jednego wystąpienia i zwykle daje prosty dostęp do tego wystąpienia.
Kiedy należy używać:
To zależy od sytuacji.
Uwaga: nie używaj połączenia DB, aby uzyskać szczegółową odpowiedź, zapoznaj się z odpowiedzią @Chad Grant
Oto prosty przykład Singleton:
publicsealedclassSingleton{privatestaticreadonlySingleton instance =newSingleton();// Explicit static constructor to tell C# compiler// not to mark type as beforefieldinitstaticSingleton(){}privateSingleton(){}publicstaticSingletonInstance{get{return instance;}}}
Możesz także użyć Lazy<T>do utworzenia swojego Singleton.
Tutaj znajdziesz bardziej szczegółowy przykład użyciaLazy<T>
W tym artykule opisano, w jaki sposób możemy stworzyć bezpieczną dla wątków klasę singletonu, używając zmiennej tylko do odczytu i ich praktycznego zastosowania w aplikacjach.
EX Możesz użyć Singleton do globalnych informacji, które należy wstrzyknąć.
W moim przypadku zachowałem szczegóły zalogowanego użytkownika (nazwa użytkownika, uprawnienia itp.) W globalnej klasie statycznej. A kiedy próbowałem zaimplementować test jednostkowy, nie było mowy o wstrzyknięciu zależności do klas kontrolerów. W ten sposób zmieniłem wzór klasy statycznej na singleton.
Musimy użyć wzorca projektowego Singleton w języku C #, gdy musimy zapewnić, że zostanie utworzone tylko jedno wystąpienie określonej klasy, a następnie zapewnić prosty globalny dostęp do tego wystąpienia dla całej aplikacji.
Scenariusze w czasie rzeczywistym, w których można użyć wzorca projektowego Singleton: Proxy usług: jak wiemy, wywoływanie interfejsu API usługi jest rozległą operacją w aplikacji. Proces, który zajmuje większość czasu, polega na utworzeniu klienta usługi w celu wywołania interfejsu API usługi. Jeśli utworzysz serwer proxy usługi jako Singleton, poprawi to wydajność Twojej aplikacji.
Fasady: Możesz także utworzyć połączenia z bazą danych jako Singleton, co może poprawić wydajność aplikacji.
Dzienniki: w aplikacji wykonywanie operacji we / wy na pliku jest kosztowną operacją. Jeśli utworzysz Logger jako Singleton, poprawi to wydajność operacji I / O.
Udostępnianie danych: jeśli masz jakieś stałe wartości lub wartości konfiguracyjne, możesz zachować te wartości w Singleton, aby mogły być odczytane przez inne komponenty aplikacji.
Buforowanie: jak wiemy, pobieranie danych z bazy danych jest procesem czasochłonnym. W aplikacji możesz buforować wzorzec i konfigurację w pamięci, co pozwoli uniknąć wywołań DB. W takich sytuacjach klasa Singleton może być użyta do obsługi buforowania z synchronizacją wątków w efektywny sposób, co znacznie poprawia wydajność aplikacji.
Wady wzorca projektowego Singleton w C # Wady używania wzorca projektowego Singleton w C # są następujące:
Testowanie jednostkowe jest bardzo trudne, ponieważ wprowadza do aplikacji stan globalny. Zmniejsza to potencjał równoległości w programie, ponieważ aby uzyskać dostęp do instancji singletonu w środowisku wielowątkowym, należy serializować obiekt za pomocą blokowania.
X
rozmawiaćY
? Po prostu zróbY
singleton!), Co z kolei prowadzi do trudności w testowaniu / debugowaniu i proceduralnym stylu programowania. Czasami konieczne są Singletony; przez większość czasu nie.Odpowiedzi:
Singleton to klasa, która pozwala na utworzenie tylko jednej instancji samego siebie - i daje prosty, łatwy dostęp do tej instancji. Założeniem singletonu jest wzorzec rozwoju oprogramowania.
Istnieje implementacja C # „Implementacja wzorca Singleton w C #” obejmująca większość tego, co musisz wiedzieć - w tym kilka dobrych rad dotyczących bezpieczeństwa wątków .
Szczerze mówiąc, bardzo rzadko trzeba wdrożyć singletona - moim zdaniem powinna to być jedna z tych rzeczy, o których powinieneś wiedzieć, nawet jeśli nie jest to używane zbyt często.
źródło
Lazy<T> Class
.Poprosiłeś o C #. Trywialny przykład:
źródło
Co to jest: Klasa, dla której istnieje tylko jedna, trwała instancja przez cały okres istnienia aplikacji. Zobacz Singleton Pattern .
Kiedy należy go używać: jak najmniej. Tylko wtedy, gdy masz absolutną pewność , że go potrzebujesz. Niechętnie mówię „nigdy”, ale zwykle istnieje lepsza alternatywa, taka jak Dependency Injection lub po prostu klasa statyczna.
źródło
inny sposób implementacji singletonu w języku c #, osobiście wolę ten sposób, ponieważ można uzyskać dostęp do instancji klasy singeton jako właściwość zamiast metody.
ale cóż, o ile wiem, oba sposoby są uważane za „właściwe”, więc jest to kwestia osobistego smaku.
źródło
Wziąłem kod z dofactory.com , nic nadzwyczajnego, ale uważam, że jest to tak dobre, jak przykłady z Foo i Barem, a dodatkowo książka Judith Bishop na temat C # 3.0 Design Patterns zawiera przykład aktywnej aplikacji w Mac Docku.
Jeśli spojrzysz na kod, w rzeczywistości budujemy nowe obiekty dla pętli for , więc tworzy nowy obiekt, ale wykorzystuje ponownie instancję, w wyniku czego oldbalancer i newbalancer mają tę samą instancję. Jak? ze względu na statyczne słowo kluczowe użyte w funkcji GetLoadBalancer () , mimo że ma inną wartość serwera, która jest losową listą, static w GetLoadBalancer () należy do samego typu, a nie do konkretnego obiektu.
Dodatkowo jest tutaj blokada podwójnej kontroli
ponieważ z MSDN
więc za każdym razem wydawana jest blokada wzajemnego wykluczenia, nawet jeśli nie jest to konieczne, więc mamy kontrolę zerową.
Mam nadzieję, że pomoże to w oczyszczeniu więcej.
I proszę o komentarz, jeśli rozumiem, że źle kieruję.
źródło
Singleton (i to nie jest związane z C #, to wzorzec projektowy OO) ma miejsce, gdy chcesz zezwolić na utworzenie tylko jednej instancji klasy w całej aplikacji. Zastosowania zwykle obejmowałyby zasoby globalne, chociaż powiem z własnego doświadczenia, bardzo często są źródłem wielkiego bólu.
źródło
Chociaż może istnieć tylko jeden przypadek singletonu, nie jest to to samo, co klasa statyczna. Klasa statyczna może zawierać tylko metody statyczne i nigdy nie może być utworzona instancja, natomiast instancja singletonu może być używana w taki sam sposób, jak każdy inny obiekt.
źródło
Jest to wzorzec projektowy i nie jest specyficzny dla c #. Więcej o tym w całym Internecie i SO, tak jak w tym artykule na Wikipedii .
Powinieneś go użyć, jeśli chcesz mieć klasę, którą można założyć tylko raz.
źródło
Używam go do wyszukiwania danych. Załaduj raz z DB.
źródło
Co to jest singleton:
Jest to klasa, która pozwala na utworzenie tylko jednego wystąpienia i zwykle daje prosty dostęp do tego wystąpienia.
Kiedy należy używać:
To zależy od sytuacji.
Uwaga: nie używaj połączenia DB, aby uzyskać szczegółową odpowiedź, zapoznaj się z odpowiedzią @Chad Grant
Oto prosty przykład
Singleton
:Możesz także użyć
Lazy<T>
do utworzenia swojegoSingleton
.Tutaj znajdziesz bardziej szczegółowy przykład użycia
Lazy<T>
źródło
Oto czym jest singleton: http://en.wikipedia.org/wiki/Singleton_pattern
Nie znam C #, ale tak naprawdę jest to samo we wszystkich językach, różni się tylko implementacja.
Ogólnie należy unikać singletonu, gdy jest to możliwe, ale w niektórych sytuacjach jest to bardzo wygodne.
Przepraszam za mój angielski ;)
źródło
Klasa Singleton służy do utworzenia pojedynczego wystąpienia dla całej domeny aplikacji.
W tym artykule opisano, w jaki sposób możemy stworzyć bezpieczną dla wątków klasę singletonu, używając zmiennej tylko do odczytu i ich praktycznego zastosowania w aplikacjach.
źródło
Wiem, że jest bardzo późno, aby odpowiedzieć na pytanie, ale dzięki Auto-Property możesz zrobić coś takiego:
public static Singleton Instance { get; } = new Singleton();
Gdzie
Singleton
jest twoja klasa i może być przez, w tym przypadku własność tylko do odczytuInstance
.źródło
EX Możesz użyć Singleton do globalnych informacji, które należy wstrzyknąć.
W moim przypadku zachowałem szczegóły zalogowanego użytkownika (nazwa użytkownika, uprawnienia itp.) W globalnej klasie statycznej. A kiedy próbowałem zaimplementować test jednostkowy, nie było mowy o wstrzyknięciu zależności do klas kontrolerów. W ten sposób zmieniłem wzór klasy statycznej na singleton.
http://csharpindepth.com/Articles/General/Singleton.aspx#cctor
źródło
Musimy użyć wzorca projektowego Singleton w języku C #, gdy musimy zapewnić, że zostanie utworzone tylko jedno wystąpienie określonej klasy, a następnie zapewnić prosty globalny dostęp do tego wystąpienia dla całej aplikacji.
Scenariusze w czasie rzeczywistym, w których można użyć wzorca projektowego Singleton: Proxy usług: jak wiemy, wywoływanie interfejsu API usługi jest rozległą operacją w aplikacji. Proces, który zajmuje większość czasu, polega na utworzeniu klienta usługi w celu wywołania interfejsu API usługi. Jeśli utworzysz serwer proxy usługi jako Singleton, poprawi to wydajność Twojej aplikacji.
Fasady: Możesz także utworzyć połączenia z bazą danych jako Singleton, co może poprawić wydajność aplikacji.
Dzienniki: w aplikacji wykonywanie operacji we / wy na pliku jest kosztowną operacją. Jeśli utworzysz Logger jako Singleton, poprawi to wydajność operacji I / O.
Udostępnianie danych: jeśli masz jakieś stałe wartości lub wartości konfiguracyjne, możesz zachować te wartości w Singleton, aby mogły być odczytane przez inne komponenty aplikacji.
Buforowanie: jak wiemy, pobieranie danych z bazy danych jest procesem czasochłonnym. W aplikacji możesz buforować wzorzec i konfigurację w pamięci, co pozwoli uniknąć wywołań DB. W takich sytuacjach klasa Singleton może być użyta do obsługi buforowania z synchronizacją wątków w efektywny sposób, co znacznie poprawia wydajność aplikacji.
Wady wzorca projektowego Singleton w C # Wady używania wzorca projektowego Singleton w C # są następujące:
Testowanie jednostkowe jest bardzo trudne, ponieważ wprowadza do aplikacji stan globalny. Zmniejsza to potencjał równoległości w programie, ponieważ aby uzyskać dostęp do instancji singletonu w środowisku wielowątkowym, należy serializować obiekt za pomocą blokowania.
Wziąłem to z następującego artykułu.
https://dotnettutorials.net/lesson/singleton-design-pattern/
źródło
Wątek Bezpieczny Singleton bez użycia blokad i bez leniwej instancji.
Ta implementacja ma statycznego konstruktora, więc jest wykonywana tylko raz na domenę aplikacji.
źródło