Jaki jest najlepszy i najwygodniejszy sposób implementacji wzorca Singleton dla klasy w języku TypeScript? (Zarówno z leniwą inicjalizacją, jak i bez niej).
singleton
typescript
maja
źródło
źródło
export default new Singleton()
?Od TS 2.0 mamy możliwość definiowania modyfikatorów widoczności w konstruktorach , więc teraz możemy tworzyć pojedyncze elementy w TypeScript, tak jak jesteśmy przyzwyczajeni z innych języków.
Podany przykład:
Dziękuję @Drenai za wskazanie, że jeśli piszesz kod przy użyciu skompilowanego surowego javascript, nie będziesz mieć ochrony przed wielokrotnymi instancjami, ponieważ ograniczenia TS znikną, a konstruktor nie zostanie ukryty.
źródło
Najlepszy sposób, jaki znalazłem, to:
Oto jak go używasz:
https://codebelt.github.io/blog/typescript/typescript-singleton-pattern/
źródło
Poniższe podejście tworzy klasę Singleton, której można używać dokładnie tak, jak klasycznej klasy:
Każdy
new Singleton()
operacja zwróci to samo wystąpienie. Może to być jednak nieoczekiwane przez użytkownika.Poniższy przykład jest bardziej przejrzysty dla użytkownika, ale wymaga innego zastosowania:
Stosowanie:
var obj = Singleton.getInstance();
źródło
new Class(...)
składnię.Dziwię się, że nie widzę tutaj następującego wzoru, który w rzeczywistości wygląda bardzo prosto.
Stosowanie
źródło
Shout
klasyMożesz użyć do tego wyrażeń klasowych (od wersji 1.6, jak sądzę).
lub z nazwą, jeśli Twoja klasa potrzebuje wewnętrznego dostępu do jej typu
Inną opcją jest użycie lokalnej klasy wewnątrz singletona przy użyciu statycznych elementów członkowskich
źródło
Dodaj następujące 6 wierszy do dowolnej klasy, aby nadać jej nazwę „Singleton”.
Przykład testu:
[Edytuj]: Użyj odpowiedzi Alexa, jeśli wolisz uzyskać instancję za pomocą właściwości, a nie metody.
źródło
new MySingleton()
, powiedzmy 5 razy? czy twój kod rezerwuje pojedyncze wystąpienie?Myślę, że może użyć leków generycznych
jak używać
krok 1
krok 2
źródło
Możesz także skorzystać z funkcji Object.Freeze () . To proste i łatwe:
źródło
if (!this.instance)
konstruktorem? Czy to tylko dodatkowe zabezpieczenie na wypadek, gdyby utworzono wiele instancji przed eksportem?Znalazłem nową wersję tego, z którą kompilator Typescript jest całkowicie w porządku i myślę, że jest lepsza, ponieważ nie wymaga
getInstance()
ciągłego wywoływania metody.Ma to inną wadę. Jeśli
Singleton
masz jakieś właściwości, kompilator Typescript wykona dopasowanie, chyba że zainicjujesz je wartością. Dlatego dołączyłem_express
właściwość do mojej przykładowej klasy, ponieważ jeśli nie zainicjujesz jej wartością, nawet jeśli przypiszesz ją później w konstruktorze, Typescript pomyśli, że nie została zdefiniowana. Można to naprawić, wyłączając tryb ścisły, ale wolę tego nie robić, jeśli to możliwe. Jest jeszcze jedna wada tej metody, na którą powinienem zwrócić uwagę, ponieważ konstruktor jest faktycznie wywoływany, za każdym razem, gdy wykonuje inną instancję, jest technicznie tworzona, ale niedostępna. Może to teoretycznie powodować wycieki pamięci.źródło
Jest to prawdopodobnie najdłuższy proces tworzenia singletona w maszynopisie, ale w większych aplikacjach jest to ten, który działał lepiej dla mnie.
Najpierw potrzebujesz klasy Singleton w, powiedzmy, „./utils/Singleton.ts” :
Teraz wyobraź sobie, że potrzebujesz singletona routera „./navigation/Router.ts” :
Świetnie !, teraz zainicjuj lub zaimportuj, gdziekolwiek potrzebujesz:
Zaletą robienia singletonów w ten sposób jest to, że nadal używasz całego piękna klas maszynopisu, daje to niezły intelizm, logika singletonów jest w jakiś sposób oddzielona i można ją łatwo usunąć w razie potrzeby.
źródło
Moje rozwiązanie:
źródło
return Modal._instance
. W ten sposób, jeśli masznew
tę klasę, otrzymasz istniejący obiekt, a nie nowy.W przypadku maszynopisu niekoniecznie trzeba przestrzegać
new instance()
metodologii Singleton. Zaimportowana klasa statyczna bez konstruktora może również działać równie dobrze.Rozważać:
Możesz zaimportować klasę i odnosić się do niej
YourSingleton.doThing()
w dowolnej innej klasie. Ale pamiętaj, ponieważ jest to klasa statyczna, nie ma konstruktora, więc zazwyczaj używamintialise()
metody, która jest wywoływana z klasy importującej Singleton:Nie zapominaj, że w klasie statycznej każda metoda i zmienna również musi być statyczna, więc zamiast
this
ciebie należy użyć pełnej nazwy klasyYourSingleton
.źródło
Oto kolejny sposób na zrobienie tego z bardziej konwencjonalnym podejściem javascript przy użyciu IFFE :
Zobacz demo
źródło
Instance
zmiennej? Możesz po prostu umieścić zmienną i funkcje bezpośrednio podApp.Counter
.Inną opcją jest użycie symboli w module. W ten sposób możesz chronić swoją klasę, również jeśli końcowy użytkownik twojego API używa normalnego Javascript:
Stosowanie:
Jeśli użytkownik używa Twojego skompilowanego pliku js API, również otrzyma błąd, jeśli spróbuje ręcznie utworzyć instancję Twojej klasy:
źródło
Nie jest to czysty singleton (inicjalizacja może nie być leniwa), ale podobny wzór za pomocą
namespace
s.Dostęp do obiektu Singleton:
źródło
To jest najprostszy sposób
źródło
W ten sposób możemy zastosować interfejs, w przeciwieństwie do zaakceptowanej odpowiedzi Ryana Cavanaugha.
źródło
Po przejrzeniu tego wątku i zabawie wszystkimi powyższymi opcjami - zdecydowałem się na Singletona, który można stworzyć za pomocą odpowiednich konstruktorów:
Wymagałoby to wstępnej konfiguracji (w
main.ts
lubindex.ts
), którą można łatwo zaimplementować za pomocąnew Singleton(/* PARAMS */)
Następnie, w dowolnym miejscu kodu, po prostu zadzwoń
Singleton.instnace
; w takim przypadku, żebywork
skończyć, zadzwonięSingleton.instance.work()
źródło