Frage

Edit:    Aus einer anderen Frage zur Verfügung gestellt ich eine Antwort, die Links zu einer Menge von Fragen / Antworten zu Singletons hat: mehr Infos über Singletons hier:

Also ich habe den Faden Singletons: gutes Design oder eine Krücke
Und das Argument noch tobt.

Ich sehe Singletons als Entwurfsmuster (gut und schlecht).
Das Problem mit Singleton ist nicht das Muster, sondern die Benutzer (sorry jedermann). Jeder und ihr Vater denken, dass sie eine richtig umsetzen können (und von den vielen Interviews, die ich getan habe, die meisten Menschen nicht). Auch, weil jeder denkt, dass sie eine korrekte Singleton implementieren können sie missbrauchen die Muster und verwenden Sie es in Situationen, die nicht geeignet sind (als Ersatz für globale Variablen mit Singletons!).

So sind die wichtigsten Fragen, die beantwortet werden müssen, sind:

  • Wann sollten Sie einen Singleton
  • verwenden
  • Wie setzen Sie einen Singleton richtig

Meine Hoffnung für diesen Artikel ist, dass wir an einem einzigen Ort sammeln können zusammen (anstatt mehrere Standorte Google und sucht) eine maßgebliche Quelle, wann (und dann wie) richtig einen Singleton zu verwenden. Auch geeignet wäre eine Liste von Anti-Verbräuche und gemeinsamen schlechter Implementierungen zu erklären, warum sie nicht funktionieren und für eine gute Implementierungen ihrer Schwächen.


also erhalten Sie den Ball ins Rollen:
Ich werde meine Hand nach oben und sagen halten das ist, was ich aber wahrscheinlich hat Probleme.
Ich mag "Scott Myers" Umgang mit dem Thema in seine Büchern "Effective C ++"

  

Gute Situationen zu verwenden Singletons (nicht viele):

     
      
  • Logging Frameworks
  •   
  • Themen-Recycling-Pools
  •   
/*
 * C++ Singleton
 * Limitation: Single Threaded Design
 * See: http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf
 *      For problems associated with locking in multi threaded applications
 *
 * Limitation:
 * If you use this Singleton (A) within a destructor of another Singleton (B)
 * This Singleton (A) must be fully constructed before the constructor of (B)
 * is called.
 */
class MySingleton
{
    private:
        // Private Constructor
        MySingleton();
        // Stop the compiler generating methods of copy the object
        MySingleton(MySingleton const& copy);            // Not Implemented
        MySingleton& operator=(MySingleton const& copy); // Not Implemented

    public:
        static MySingleton& getInstance()
        {
            // The only instance
            // Guaranteed to be lazy initialized
            // Guaranteed that it will be destroyed correctly
            static MySingleton instance;
            return instance;
        }
};

OK. Lässt zusammen einige Kritik und andere Implementierungen bekommen.
: -)

War es hilfreich?

Lösung

Alle Sie sind falsch. Lies die Frage. Antwort:

ein Singleton verwenden, wenn:

  • Sie benötigen einen haben und nur ein Objekt eines Typs in System

Sie einen Singleton nicht verwenden, wenn:

  • Sie wollen Speicher speichern
  • Sie wollen etwas Neues versuchen
  • Sie wollen zeigen, wie viel Sie wissen
  • Da alle anderen es tut (Siehe Cargo-Kult-Programmierer in wikipedia)
  • In Benutzeroberfläche Widgets
  • Es soll ein Cache
  • sein
  • In Strings
  • In Sitzungen
  • Ich kann den ganzen Tag lang gehen

Wie die besten Singleton erstellen:

  • Je kleiner, desto besser. Ich bin ein Minimalist
  • Stellen Sie sicher, dass es Thread-sicher
  • ist
  • Stellen Sie sicher, dass es nie null
  • Stellen Sie sicher, es wird nur einmal erstellt
  • Faule oder System-Initialisierung? Bis zu Ihren Anforderungen
  • Manchmal erzeugt das Betriebssystem oder die JVM Singletons für Sie (zum Beispiel in Java jede Klassendefinition ist ein Singleton)
  • Geben Sie eine destructor oder irgendwie herauszufinden, wie Ressourcen verfügen
  • Verwenden Sie wenig Speicher

Andere Tipps

Singletons geben Ihnen die Möglichkeit, zwei schlechte Eigenschaften in einer Klasse zu kombinieren. Das ist falsch in so ziemlich jeder Hinsicht.

A Singleton gibt Ihnen:

  1. Globaler Zugriff auf ein Objekt, und
  2. Eine Garantie, dass nicht mehr als ein Objekt dieses Typs kann jemals erstellt werden

Die Nummer eins ist einfach. Globals sind in der Regel schlecht. Wir sollten niemals Objekte global zugänglich machen, wenn wir nicht wirklich es brauchen.

Nummer zwei klingt wie es Sinn macht, aber wir darüber nachdenken. Wann war das letzte Mal ** versehentlich * ein neues Objekt statt Referenzierung eines bestehenden erstellt? Da diese C ++ markiert ist, fangen sie von dieser Sprache ein Beispiel. Sie schreiben oft versehentlich

std::ostream os;
os << "hello world\n";

Wenn Sie beabsichtigt zu schreiben

std::cout << "hello world\n";

Natürlich nicht. Wir brauchen keinen Schutz vor diesen Fehler, weil diese Art von Fehler einfach nicht passieren. Ist dies der Fall, die richtige Antwort ist für 12-20 Stunden nach Hause und schlafen zu gehen und hoffen, dass Sie sich besser fühlen.

Wenn nur ein Objekt benötigt wird, erstellen Sie einfach eine Instanz. Wenn ein Objekt sollte global zugänglich sein, macht es zu einem global. Aber das bedeutet nicht, dass es unmöglich sein sollte, andere Instanzen davon zu erstellen.

Die „nur eine Instanz ist möglich“ Einschränkung schützt nicht wirklich uns gegen wahrscheinlich Bugs. Aber es hat machen unseren Code sehr schwer zu Refactoring und zu pflegen. Weil wir sehr oft herausfinden, später , die wir haben mehr als eine Instanz benötigen. Wir tun haben mehr als eine Datenbank, we tun haben mehr als eine Konfigurationsobjekt, wir mehrere Logger wollen. Unsere Unit-Tests wollen können in der Lage sein, diese Objekte jeden Test zu erstellen und neu erstellen, ein gängiges Beispiel zu nehmen.

So ein Singleton, wenn und sollten nur verwendet werden, wenn, müssen wir beide die Merkmale bietet: Wenn wir Notwendigkeit globalen Zugang (was selten ist, weil Globals im Allgemeinen sind mutlos) und wir Notwendigkeit jemand von zu verhindern, immer mehr als eine Instanz einer Klasse zu schaffen (die wie ein Design-Problem klingt für mich). Der einzige Grund, warum ich dafür sehen kann, ist, wenn zwei Instanzen zu schaffen verfälschen würde unser Anwendungszustand - wahrscheinlich, weil die Klasse eine Anzahl von statischen Elementen oder ähnlicher Albernheit enthält. In diesem Fall wird die offensichtliche Antwort ist, diese Klasse zu beheben. Es sollte nicht davon ab, die einzige Instanz sein.

Wenn Sie die globalen Zugriff auf ein Objekt benötigen, macht es zu einem globalen, wie std::cout. Aber beschränken nicht die Anzahl der Instanzen, die erstellt werden können.

Wenn Sie absolut positiv müssen die Anzahl der Instanzen einer Klasse beschränken, nur eine, und es gibt keine Möglichkeit, dass eine zweite Instanz zu schaffen jemals sicher gehandhabt werden kann, dann ist das erzwingen. Aber machen Sie nicht global zugängliches es auch.

Wenn Sie das tun, beide Züge benötigen, dann 1) es ein Singleton machen, und 2) lassen Sie mich wissen, was Sie brauchen, dass für, weil ich eine harte Zeit, einen solchen Fall vorstellen.

Das Problem mit Singletons ist nicht deren Umsetzung. Es ist, dass sie zwei verschiedene Konzepte conflate, von denen keiner offensichtlich wünschenswert ist.

1) Singletons einen globalen Zugriffsmechanismus auf ein Objekt. Obwohl sie geringfügig mehr THREAD sein könnten oder geringfügig zuverlässiger in Sprachen ohne eine wohldefinierte Initialisierungsreihenfolge, ist diese Nutzung noch das moralische Äquivalent einer globalen Variablen. Es ist eine globale Variable in einiger umständlich Syntax (foo :: get_instance () anstelle von g_foo, sagt) verkleidet, aber es dient den exakt gleichen Zweck (ein einzelnes Objekt zugänglich über das gesamte Programm) und hat exakt die gleichen Nachteile.

2) Singletons verhindern, dass mehrere Instanzen einer Klasse. Es ist selten, IME, dass diese Art von Funktion sollte in eine Klasse gebacken werden. Es ist normalerweise eine viel kontextuelle Sache; viele der Dinge, die als ein-und-nur-ein betrachtet werden, sind wirklich passiert sein-nur-ein einfach. IMO eine geeignetere Lösung ist, einfach nur eine Instanz erstellen -., Bis Sie erkennen, dass Sie mehr als eine Instanz benötigen

Eine Sache, mit Muster: generalisieren nicht . Sie haben alle Fälle, in denen sie sind nützlich, und wenn sie scheitern.

Singleton kann böse sein, wenn Sie auf Test Code. Sie sind im Allgemeinen mit einer Instanz der Klasse stecken, und zwischen Öffnung einer Tür in Konstruktor oder eine Methode wählen können, die den Zustand und so weiter zurückgesetzt werden.

Anderes Problem ist, dass die Singleton ist in der Tat nichts anderes als eine globale Variable in der Verkleidung. Wenn Sie zu viel globalen Shared-Zustand über Ihr Programm haben, neigen dazu, die Dinge wieder zu gehen, wir alle wissen es.

Es kann machen Abhängigkeit Tracking härter. Wenn alles auf dem Singleton abhängt, ist es schwieriger, es zu ändern, aufgeteilt auf zwei, usw. Sie sind mit ihm im Allgemeinen stecken. Dies behindert auch Flexibilität. Untersuchen Sie einige Dependency Injection Rahmen, um zu versuchen, dieses Problem zu lindern.

Singletons im Grunde können Sie komplexen globalen Zustand in Sprachen haben, die sonst nur schwer oder unmöglich machen komplexe globale Variablen haben.

Java insbesondere verwendet Singletons als Ersatz für globale Variablen müssen, da alles in einer Klasse enthalten sein. Die nächstgelegene es darum geht, globale Variablen sind öffentliche statische Variablen, die verwendet werden können, als ob sie mit import static global waren

C ++ tut globale Variablen, aber die Reihenfolge, in der Konstrukteurs der globalen Klassenvariablen aufgerufen wird, ist nicht definiert. Als solches kann ein Singleton können Sie die Schaffung einer globalen Variablen bis zum ersten Mal verschieben diese Variable benötigt wird.

Sprachen wie Python und Ruby verwenden Singletons sehr wenig, weil Sie stattdessen globale Variablen in einem Modul verwenden können.

Wenn also ist es gut / schlecht einen Singleton zu benutzen? So ziemlich genau, wenn es gut / schlecht wäre eine globale Variable zu verwenden.

Modern C ++ Design von Alexandrescu hat eine Thread-sichere, vererbbar generic Singletons.

Für meine 2p-wert, ich denke, es ist wichtig, definierte Lebensdauer für Ihre Singletons haben (wenn es absolut notwendig ist, sie zu benutzen). Ich normalerweise nicht zulassen, die statische get() Funktion etwas instanziiert, und lassen Sie Set-up und Zerstörung zu einem gewissen speziellen Bereich der Hauptanwendung. Dies hilft Highlight Abhängigkeiten zwischen Singletons -. Aber, wie oben betont, ist es am besten, nur um sie zu vermeiden, wenn möglich

  
      
  • Wie setzen Sie einen Singleton richtig
  •   

Da ist ein Problem, das ich habe noch nie, etwas, das ich in bei einem frühen Job lief erwähnt gesehen. Wir hatten C ++ Singletons, die zwischen DLLs geteilt wurden, und die übliche Mechanik von einer einzigen Instanz einer Klasse zu gewährleisten funktioniert einfach nicht. Das Problem ist, dass jeder DLL einen eigenen Satz von statischen Variablen erhält, zusammen mit der EXE-Datei. Wenn Ihre get_instance Funktion inline oder einen Teil einer statischen Bibliothek ist, wird jede DLL mit seiner eigenen Kopie der „Singletons“ aufzuwickeln.

Die Lösung ist sicher, dass der Singleton-Code zu machen nur in einer DLL oder EXE definiert ist, oder ein Singleton-Manager mit diesen Eigenschaften erstellen Instanzen parzellieren.

Das erste Beispiel ist nicht Thread-sicher - wenn zwei Threads getInstance gleichzeitig rufen, dass statische ein PITA sein wird. Irgendeine Form von Mutex helfen würde.

Wie andere erwähnt haben, große Nachteile zu Singletons gehören die Unfähigkeit, sie zu erweitern, und er verliert die Macht mehr als eine Instanz zu instanziiert, z.B. für Testzwecke.

Einige nützliche Aspekte der Singletons:

  1. faul oder Upfront Instanziierung
  2. praktisch für ein Objekt, das Setup und / oder Zustand
  3. erfordert

Allerdings müssen Sie nicht einen Singleton verwenden, um diese Vorteile zu erhalten. Sie können ein normales Objekt schreiben, das die Arbeit macht, und dann werden die Menschen es über eine Fabrik Zugang haben (ein separates Objekt). Die Fabrik kann Sorgen über nur eine Instanziierung und Wiederverwendung es usw., wenn nötig. Auch, wenn Sie auf eine Schnittstelle programmieren, anstatt eine konkrete Klasse, kann die Fabrik Strategien verwenden, das heißt Sie können in und aus verschiedenen Implementierungen der Schnittstelle wechseln.

Schließlich wird eine Fabrik bietet sich Injektionstechnologien wie Spring usw. Abhängigkeit.

Singletons sind praktisch, wenn Sie eine Menge Code zu seinen Lauf haben, wenn Sie initialisieren und Objekt. Zum Beispiel, wenn Sie iBatis verwenden, wenn Sie Setup ein Persistenz Objekt, um es alle configs zu lesen hat, analysiert die Karten, stellen Sie sicher, es ist alles richtig, etc .., bevor Sie den Code zu bekommen.

Wenn Sie dies jedes Mal, es täte, würde die Leistung viel abgebaut werden. Mit ihm in einem Singleton, nehmen Sie diesen Hit einmal und dann alle nachfolgenden Anrufe müssen es nicht tun.

Der eigentliche Sturz von Singletons ist, dass sie Erbe brechen. Sie können nicht eine neue Klasse ableiten Sie erweiterte Funktionalität geben, es sei denn, Sie Zugriff auf den Code, wo die Singleton verwiesen wird. Also, außer der Tatsache, die die Singleton Code macht eng gekoppelt (fixierbar durch ein Strategie-Muster ... Auch bekannt als Dependency Injection) wird es auch verhindern, dass Sie Absperren Abschnitte des Codes von Revision (shared libraries).

So auch die Beispiele von Loggern oder Thread-Pools sind ungültig und sollten durch Strategien ersetzt werden.

Die meisten Leute benutzen Singletons, wenn sie versuchen, sich gut fühlen, über eine globale Variable. Es gibt legitime Anwendungen, aber die meiste Zeit, wenn Menschen nutzen sie die Tatsache, dass es nur eine Instanz sein kann, ist nur eine triviale Tatsache, im Vergleich zu der Tatsache, dass es global zugänglich ist.

Da nur ein Singleton eine Instanz erlaubt es geschaffen werden effektiv steuert Instanz Replikation. zum Beispiel würden Sie nicht mehrere Instanzen eines Lookup benötigen - eine morse Lookup Karte zum Beispiel, so dass es in einem Singletonklasse Einwickeln geeignet ist. Und nur weil Sie eine einzelne Instanz der Klasse haben, bedeutet nicht, dass Sie auch auf die Zahl der Verweise auf diese Instanz beschränkt sind. Sie können zum Beispiel Anrufe (zu vermeiden Threadingprobleme) Warteschlange und Effekt ändert notwendig. Ja, die allgemeine Form eines Singleton ist ein global Öffentlichkeit ein, können Sie sicherlich das Design ändern, um eine weitere Zugriffsbeschränkungen Singleton zu erstellen. Ich habe nicht müde dies vor, aber ich weiß, dass es möglich ist. Und für alle diejenigen, die Singletonmuster kommentierte sagen ganz böse ist, sollten Sie dies wissen: Ja, es ist schlecht, wenn Sie es nicht richtig verwenden oder in ihm Grenzen der effektiven Funktionalität und vorhersagbares Verhalten. Generalisieren nicht

Aber wenn ich so etwas wie ein Singleton benötigen, ich am Ende oft eine Schwarz Zähler es zu instanziiert.

Ich verwende Singletons als Interview-Test.

Wenn ich einen Entwickler fragen einige Design-Muster zu nennen, wenn alles, was sie benennen können Singleton ist, sind sie nicht eingestellt.

Im Folgenden ist der bessere Ansatz für einen Thread sicher Singletonmuster Implementierung des Speichers in destructor selbst mit Aufheben der Zuordnung. Aber ich denke, der destructor sollte eine optional sein, weil Singleton-Instanz wird automatisch zerstört, wenn das Programm beendet wird:

#include<iostream>
#include<mutex>

using namespace std;
std::mutex mtx;

class MySingleton{
private:
    static MySingleton * singletonInstance;
    MySingleton();
    ~MySingleton();
public:
    static MySingleton* GetInstance();
    MySingleton(const MySingleton&) = delete;
    const MySingleton& operator=(const MySingleton&) = delete;
    MySingleton(MySingleton&& other) noexcept = delete;
    MySingleton& operator=(MySingleton&& other) noexcept = delete;
};

MySingleton* MySingleton::singletonInstance = nullptr;
MySingleton::MySingleton(){ };
MySingleton::~MySingleton(){
    delete singletonInstance;
};

MySingleton* MySingleton::GetInstance(){
    if (singletonInstance == NULL){
        std::lock_guard<std::mutex> lock(mtx);
        if (singletonInstance == NULL)
            singletonInstance = new MySingleton();
    }
    return singletonInstance;
}

In Bezug auf die Situationen, in denen wir Singleton-Klassen verwenden müssen, können BE- Wenn wir wollen, um den Zustand der Instanz während der Ausführung des Programms halten Wenn wir in schriftlicher Form in Ausführungsprotokoll einer Anwendung beteiligt, bei denen nur einer Instanz der Datei notwendig verwendet werden .... und so weiter. Es wird spürbar, wenn jemand Optimierung in meinem obigen Code vorschlagen kann.

Anti-Verbrauch:

Ein großes Problem mit übermäßiger Singleton Nutzung ist, dass das Muster einfache Erweiterung und Austausch von alternativen Implementierungen verhindert. Der Klassenname ist hart codiert, wo der Singleton verwendet wird.

Ich denke, das ist die robusteste Version für C #:

using System;
using System.Collections;
using System.Threading;

namespace DoFactory.GangOfFour.Singleton.RealWorld
{

  // MainApp test application

  class MainApp
  {
    static void Main()
    {
      LoadBalancer b1 = LoadBalancer.GetLoadBalancer();
      LoadBalancer b2 = LoadBalancer.GetLoadBalancer();
      LoadBalancer b3 = LoadBalancer.GetLoadBalancer();
      LoadBalancer b4 = LoadBalancer.GetLoadBalancer();

      // Same instance?
      if (b1 == b2 && b2 == b3 && b3 == b4)
      {
        Console.WriteLine("Same instance\n");
      }

      // All are the same instance -- use b1 arbitrarily
      // Load balance 15 server requests
      for (int i = 0; i < 15; i++)
      {
        Console.WriteLine(b1.Server);
      }

      // Wait for user
      Console.Read();    
    }
  }

  // "Singleton"

  class LoadBalancer
  {
    private static LoadBalancer instance;
    private ArrayList servers = new ArrayList();

    private Random random = new Random();

    // Lock synchronization object
    private static object syncLock = new object();

    // Constructor (protected)
    protected LoadBalancer()
    {
      // List of available servers
      servers.Add("ServerI");
      servers.Add("ServerII");
      servers.Add("ServerIII");
      servers.Add("ServerIV");
      servers.Add("ServerV");
    }

    public static LoadBalancer GetLoadBalancer()
    {
      // Support multithreaded applications through
      // 'Double checked locking' pattern which (once
      // the instance exists) avoids locking each
      // time the method is invoked
      if (instance == null)
      {
        lock (syncLock)
        {
          if (instance == null)
          {
            instance = new LoadBalancer();
          }
        }
      }

      return instance;
    }

    // Simple, but effective random load balancer

    public string Server
    {
      get
      {
        int r = random.Next(servers.Count);
        return servers[r].ToString();
      }
    }
  }
}

Hier ist die .NET-optimierte Version :

using System;
using System.Collections;

namespace DoFactory.GangOfFour.Singleton.NETOptimized
{

  // MainApp test application

  class MainApp
  {

    static void Main()
    {
      LoadBalancer b1 = LoadBalancer.GetLoadBalancer();
      LoadBalancer b2 = LoadBalancer.GetLoadBalancer();
      LoadBalancer b3 = LoadBalancer.GetLoadBalancer();
      LoadBalancer b4 = LoadBalancer.GetLoadBalancer();

      // Confirm these are the same instance
      if (b1 == b2 && b2 == b3 && b3 == b4)
      {
        Console.WriteLine("Same instance\n");
      }

      // All are the same instance -- use b1 arbitrarily
      // Load balance 15 requests for a server
      for (int i = 0; i < 15; i++)
      {
        Console.WriteLine(b1.Server);
      }

      // Wait for user
      Console.Read();    
    }
  }

  // Singleton

  sealed class LoadBalancer
  {
    // Static members are lazily initialized.
    // .NET guarantees thread safety for static initialization
    private static readonly LoadBalancer instance =
      new LoadBalancer();

    private ArrayList servers = new ArrayList();
    private Random random = new Random();

    // Note: constructor is private.
    private LoadBalancer()
    {
      // List of available servers
      servers.Add("ServerI");
      servers.Add("ServerII");
      servers.Add("ServerIII");
      servers.Add("ServerIV");
      servers.Add("ServerV");
    }

    public static LoadBalancer GetLoadBalancer()
    {
      return instance;
    }

    // Simple, but effective load balancer
    public string Server
    {
      get
      {
        int r = random.Next(servers.Count);
        return servers[r].ToString();
      }
    }
  }
}

Sie können diese Muster finden Sie unter dotfactory.com .

Die Meyers Singletonmuster funktioniert gut genug für die meisten der Zeit, und bei den Gelegenheiten es macht es nicht unbedingt besser bezahlt für nichts zu suchen. Solange der Konstruktor wird nie und es gibt keine Abhängigkeiten zwischen Singletons.

Ein Singleton ist eine Implementierung für ein global zugängliches Objekt (GAO von jetzt an), obwohl nicht alle Gaos Singletons sind.

Loggern selbst nicht Singletons sein sollte, aber die Mittel optimal zu protokollieren sollte global zugänglich sein, zu entkoppeln, wo die Log-Nachricht, von wo aus oder erzeugt wird, wie es angemeldet wird.

Lazy-Laden / lazy evaluation ist ein anderes Konzept und Singleton implementiert in der Regel auch. Es kommt mit einer Menge ihrer eigenen Probleme, insbesondere Thread-Sicherheit und Fragen, wenn es mit Ausnahmen, nicht das, was wie eine gute Idee schien die Zeit gar nicht so groß zu sein, stellt sich heraus. (Ein bisschen wie COW Implementierung in Strings).

Mit dem im Verstand, können globale Rahmenverträge wie folgt initialisiert werden:

namespace {

T1 * pt1 = NULL;
T2 * pt2 = NULL;
T3 * pt3 = NULL;
T4 * pt4 = NULL;

}

int main( int argc, char* argv[])
{
   T1 t1(args1);
   T2 t2(args2);
   T3 t3(args3);
   T4 t4(args4);

   pt1 = &t1;
   pt2 = &t2;
   pt3 = &t3;
   pt4 = &t4;

   dostuff();

}

T1& getT1()
{
   return *pt1;
}

T2& getT2()
{
   return *pt2;
}

T3& getT3()
{
  return *pt3;
}

T4& getT4()
{
  return *pt4;
}

Es braucht nicht so primitiv wie das getan werden, und deutlich in einer geladenen Bibliothek, die ein anderer Mechanismus Objekte, die Sie wollen wahrscheinlich enthält ihre Lebensdauer verwalten. (Setzen Sie sie in ein Objekt, das Sie erhalten, wenn Sie die Bibliothek laden).

Was, wenn ich Singletons verwenden? Ich habe sie für zwei Dinge - Eine Singleton-Tabelle, die was haben gibt Bibliotheken mit dlopen geladen - Eine Meldung Handler, der Logger abonnieren können und dass Sie können Nachrichten senden. Erforderlich speziell für Signal-Handler.

ich immer noch nicht erhalten, warum ein Singleton global sein muss.

Ich wollte einen Singleton produzieren, wo ich eine Datenbank innerhalb der Klasse als private Konstante statischer Variable versteckten und Klasse-Funktionen machen, die die Datenbank nutzen, ohne jemals die Datenbank für den Benutzer ausgesetzt wird.

Ich sehe nicht, warum diese Funktionalität schlecht sein würde.

Ich finde sie sinnvoll, wenn ich eine Klasse, die viel Speicher verkapselt. Zum Beispiel in einem aktuellen Spiel habe ich gearbeitet Ich habe eine Influence Map-Klasse, die eine Sammlung von sehr großen Arrays von zusammenhängenden Speicher enthält. Ich mag, dass alle beim Start zugewiesen, die alle beim Herunterfahren befreit und ich möchte auf jeden Fall nur eine Kopie davon. Ich muss es auch den Zugang von vielen Orten. Ich finde das Singletonmuster in diesem Fall sehr nützlich sein.

Ich bin sicher, es gibt auch andere Lösungen, aber ich finde dies eine sehr nützliche und einfach zu implementieren.

Wenn Sie sind derjenige, der die Singleton erstellt und wer es benutzt, nicht als Singleton machen (es macht keinen Sinn, weil Sie die Einzigartigkeit des Objekts steuern kann, ohne sie zu Singleton machen), aber es macht Sinn, wenn Sie einen Entwickler einer Bibliothek und Sie nur ein Objekt für Ihre Benutzer liefern wollen (in diesem Fall, dass Sie die, die die Singleton erstellt, aber Sie sind nicht der Benutzer).

Singletons sind Objekte, so nutzen sie als Objekte, viele Menschen zu Singletons greift direkt durch Aufruf der Methode, die es gibt, aber das ist schädlich, weil Sie Ihren Code machen weiß, dass Objekt Singleton ist, ziehe ich Singletons als Objekte zu verwenden, ich gehe sie durch den Konstruktor und ich benutze sie als gewöhnliche Gegenstände, durch diese Art und Weise, Ihren Code nicht weiß, ob diese Objekte Singletons sind oder nicht, und das macht die Abhängigkeiten mehr klar, und es hilft, ein wenig für Refactoring ...

In Desktop-Anwendungen (ich weiß, nur wir Dinosaurier diese mehr schreiben!) Sie wesentlich sind für relativ unveränderliche globale Anwendungseinstellungen bekommen - die Benutzersprache, Pfad Dateien zu helfen, Benutzereinstellungen usw., die sonst in jede Klasse propagieren würden und jeder Dialog.

Bearbeiten - natürlich sollten diese nur gelesen werden

Eine weitere Implementierung

class Singleton
{
public:
    static Singleton& Instance()
    {
        // lazy initialize
        if (instance_ == NULL) instance_ = new Singleton();

        return *instance_;
    }

private:
    Singleton() {};

    static Singleton *instance_;
};
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top