2016-06-01 10 views
2

In Java haben wir den privaten KonstruktorWie erstellt man eine Klasse, die nicht extern in TypeScript instanziiert werden kann?

public class Singleton{ 
    private static volatile Singleton INSTANCE = null; 
    private Singleton(){ } 

    public static Singleton getInstance(){ 
     if(INSTANCE == null){ 
      synchronized(Singleton.class){ 
       if(INSTANCE == null){ 
        INSTANCE = new Singleton(); 
       } 
      } 
     } 
    return INSTANCE; 
    } 
} 

, die können eine Klasse macht nicht außerhalb der Klasse intantiated. Gibt es so etwas in TypeScript?

Antwort

2

So etwas sollte funktionieren:

class Singleton { 

    private static _instance:Singleton = new Singleton(); 

    constructor() { 
     if (Singleton._instance){ 
      throw new Error("Error: use getInstance()"); 
     } 
     Singleton._instance = this; 
    } 

    public static getInstance():Singleton { 
     return Singleton._instance; 
    } 

    ... 
} 

Auch in Java nicht notwendig ist, eine verzögerte Initialisierung zu verwenden, da die Singleton nicht initialisiert wird, wenn nicht verwendet. Ein besserer Ansatz:

public class Singleton { 
    private static Singleton INSTANCE = new Singleton(); 
    private Singleton() {} 

    public Singleton getInstance(){ 
     return INSTANCE; 
    } 
} 

zum Kommentar von Zhipeng zu beantworten, eine statische Initialisierung ist Thread-sicher, wie sie in der JLS bei 12.4.2 definiert:

Die Umsetzung der Java Virtual Machine ist verantwortlich für Synchronisation und rekursive Initialisierung unter Verwendung des folgenden Verfahrens die Pflege ...


Hinweis: Die Verwendung der faulen Implementierung ist nur dann sinnvoll, wenn eine statische Methode ohne getInstance() verwendet werden kann. In diesem Fall wird die Singleton-Klasse instanziiert, auch wenn sie niemals verwendet wird.


Eine vollständige Beschreibung auf Singleton auf Java Sie einen Blick auf einen Artikel nehmen kann ich für Dzone schrieb

+0

Aber was ist, wenn das Singleton in Multithreading-Umgebung (in Java) ist? Wird es abstürzen? –

+0

Die statische Initialisierung ist threadsicher, dies ist von Design –

+0

OK, danke. Kumpel. –

0

Werfen Sie einen Blick auf this issue für einige Ideen, wie Sie dies jetzt erreichen können, aber zur Kenntnis nehmen das TypeScript 2.0 wird private Konstruktoren haben und das wird sehr bald kommen. Für Vorerst empfehlen Schreibe ich den folgenden Code ...

class Singleton { 
    private static instance: Singleton = new Singleton(); 

    // todo: mark as private when TS 2.0 comes out 
    constructor() { 
    } 

    static getInstance() { 
     return this.instance; 
    } 
} 

... dann es um private ändern, sobald Typoskript 2.0 herauskommt.

2

Ich werde mit dem Java-Teil beginnen und wird eine zusätzliche Sache über hinzufügen, was @DavideLorenzoMARINO schrieb und das ist der volatile keyword:

class MySingleton { 
    private static volatile MySingleton instance; 

    private MySingleton() { 
     // do what ever 
    } 

    public static MySingleton getInstance() { 
     if (MySingleton.instance == null) { 
      MySingleton.instance = new MySingleton(); 
     } 

     return MySingleton.instance; 
    } 
} 

Wenn Sie wirklich sicherstellen möchten, dass dies in einer multi- arbeitet threaded Umgebung dann könnten Sie auch den „Double Checked Locking“ Ansatz berücksichtigen wollen:

class MySingleton { 
    private static volatile MySingleton instance; 

    private MySingleton() { 
     // do what ever 
    } 

    public static MySingleton getInstance() { 
     if (MySingleton.instance == null) { 
      synchronized (MySingleton.class) { 
       if (MySingleton.instance == null) { 
        MySingleton.instance = new MySingleton(); 
       } 
      } 
     } 

     return MySingleton.instance; 
    } 
} 

Was das Typoskript Teil, ich glaube nicht, dass dieses Muster auch in Typoskript arbeitet als im Gegensatz zu Java zur Laufzeit nichts verhindern eine weitere develo per instanziieren mehr als eine Instanz.

Wenn Sie den Entwicklern vertrauen, die mit dem Code arbeiten, dann ist das in Ordnung, aber wenn nicht, warum umgibt man nicht einfach die Instanz in einem Modul/Namespace, so dass die Implementierung ausgeblendet wird?

Etwas wie:

namespace MySingleton { 
    class MySingletonInstance { 
     echo(value: string): string { 
      console.log(value); 
      return value; 
     } 
    } 

    export var instance = new MySingletonInstance(); 
} 

Aber da Sie nur eine Instanz dieser Klasse werden mit, dann denke ich, dass in javascript es mehr Sinn macht überhaupt eine Klasse nicht zu verwenden, ist es nur Dinge machen Ausführlicher, und Sie können einfach:

namespace MySingleton { 
    export interface MySingletonInstance { 
     echo(value: string): string; 
    } 

    export var instance: MySingletonInstance = { 
     echo: value => { 
      console.log(value); 
      return value; 
     } 
    } 
} 
Verwandte Themen