Frage

Wie implementieren man das Singleton-Entwurfsmuster in unterwegs Programmiersprache?

War es hilfreich?

Lösung

Abgesehen von der Argumentation, ob die Singletonmuster Umsetzung ist eine gute Idee, hier ist eine mögliche Implementierung:

package singleton

type single struct {
        O interface{};
}

var instantiated *single = nil

func New() *single {
        if instantiated == nil {
                instantiated = new(single);
        }
        return instantiated;
}

single und instantiated sind privat, aber New() ist öffentlich. So können Sie nicht direkt single instanziiert ohne durch New() zu gehen, und es verfolgt die Anzahl der Instanzen mit dem privaten boolean instantiated. Stellen Sie die Definition von single abschmecken.

Wie jedoch einige andere haben bemerkt , ist dies nicht Thread-sicher, es sei denn, Sie sind nur in init() Ihre Singleton initialisiert. Ein besserer Ansatz wäre sync.Once zu nutzen, die harte Arbeit für Sie tun:

package singleton

import "sync"

type single struct {
        O interface{};
}

var instantiated *single
var once sync.Once

func New() *single {
        once.Do(func() {
                instantiated = &single{}
        })
        return instantiated
}

Siehe auch Vorschlag der hasan j nur ein Paket zu denken wie ein Singleton. Und schließlich betrachten, was andere darauf hindeutet. Dass Singletons sind oft ein Indikator für eine problematische Umsetzung

Andere Tipps

Bevor Sie versuchen, einen Weg zu finden Gehen Sie zu Ihrem Willen zu beugen, könnten Sie einen Blick auf einige Artikel nehmen wollen:

Insgesamt im Laufe der Zeit Menschen Singletons haben festgestellt, weniger als optimal zu sein, und imho insbesondere , wenn Sie versuchen, jede Testgetriebene Entwicklung zu tun: auf vielen Ebenen sind sie so ziemlich so schlecht, wie globale Variablen.

[Disclaimer: Ich weiß, es ist nicht eine strenge Antwort auf Ihre Frage, aber es ist wirklich relevant]

Sie Ihre Variablen und Funktionen auf Paketebene setzen.

Siehe auch ähnliche Frage: Wie einen Singleton in Python machen

Ich denke, dass in einer gleichzeitigen Welt brauchen wir ein bisschen mehr darüber im Klaren sein, dass diese Zeilen nicht atomar ausgeführt werden:

if instantiated == nil {
    instantiated = new(single);
}

würde ich den Vorschlag von @marketer folgen und das Paket „sync“ verwenden

import "sync"

type MySingleton struct {

}

var _init_ctx sync.Once 
var _instance *MySingleton

func New() * MySingleton {
     _init_ctx.Do( func () { _instance = new(MySingleton) }  )
     return _instance 
}

Der beste Ansatz wird sein:

 package singleton

 import "sync"

 type singleton struct {
 }

 var instance *singleton
 var once sync.Once

 func GetInstance() *singleton {
     once.Do(func() {
         instance = &singleton{}
     })
     return instance
 }

Sie sollten lesen Sie Link-

Sie können die Initialisierung tun mit dem einmal Paket :

Dadurch wird sichergestellt, dass Ihre init Methoden nur einmal aufgerufen.

hat nur eine einzige statische, final, konstant, global, anwendungsweite Instanz des Objekts Sie wollen.

Dies ist jedoch im Widerspruch zu dem OO-Paradigma. Sein Gebrauch soll auf Primitiven und unveränderliche Objekte beschränkt werden, keine Gegenstände auf Mutable.

Sie sollten sich bewusst sein, dass Once.Do den Code über die Ausführung nur einmal ernst. Das bedeutet, dass der Code immer nur einmal ausgeführt, obwohl sie in Panik geraten könnten:

https://golang.org/pkg/sync/#Once.Do

  

Wenn f (Anmerkung: die einmal Logik) gerät in Panik, hält Do sie zurückgekehrt sein; zukünftige Anrufe von Do Rückkehr ohne f aufrufen.

Ich habe mutexes statt einzigartige Initialisierung eines globalen Konfigurationsvariable, um sicherzustellen, diese Einschränkung zu überwinden:

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top