2010-07-18 11 views
8

Ich habe in letzter Zeit etwas über das Singleton-Muster gelesen. Wenn es die technischen Aspekte davon liest, scheint es ideal geeignet zu sein, um einen Datenbank-Handler oder dergleichen zu verwalten. Aber nach dem Lesen von breiteren Ressourcen scheint es, dass die Entwicklergemeinschaft das Muster wirklich nicht favorisiert.Singleton PHP - Datenbank-Handler

Ich habe Mühe, eine bessere Lösung für ein solches Problem zu finden - d. H. Nur ein einzelner Handler kann initialisiert werden - warum also ist das Muster so schlecht? Ist es überstrapaziert oder nur grundlegend fehlerhaft?

PHP ist die Sprache, die ich verwende.

Antwort

2

Einige Leute folgen diesem Mantra, dass Singletons böse sind, weil sie wie globale Variablen sind und Ihren Code härter und schwieriger zu testen machen.

Ich für den einen glaube nicht, dass es so eine schlechte Idee ist, und ich denke, ein Singleton funktioniert ziemlich gut für einen Datenbank-Handler. Es ist einfach, intuitiv und Sie haben mehr Kontrolle über eine Singleton-Instanz als eine globale Variable.

8

Singletons are glorified global variables. Das Entwurfsmuster wurde für Sprachen erstellt, in denen globale Variablen schwierig oder unmöglich sind oder wo sie als schlechte Praxis angesehen werden. (Tatsächlich sind die meisten gängigen Entwurfsmuster für restriktive Sprachen ausgelegt. Eine große Anzahl von ihnen ist in anderen Sprachen einfach unnötig.)

PHP hat globale Variablen. PHP globale Variablen sind in der Regel eine schlechte Übung, aber sie existieren, wenn Sie sie verwenden müssen.

Es gibt jedoch ein paar Gründe, warum Sie ein Singleton in PHP möchten.

Singletons sind nützlich, wenn der Aufruf an getInstance (der kanonische Name für die Methode, die die einzelne Instanz des Singleton zurückgibt) an irgendeinem Punkt im Skript vorgenommen werden konnte. Bis zu diesem Punkt muss das Objekt nicht existieren. Wenn das Objekt stattdessen eine globale Variable wäre, müsste es entweder bereits existieren oder der Code, der versucht, auf das Objekt zu verweisen, müsste es zuerst instanziieren. In der Tat, überall wo es verwendet werden könnte, müsste es korrekt instanziiert werden. Durch die Zentralisierung der Erstellung des einzelnen Objekts in getInstance vermeiden Sie jedes Mal, wenn Sie das Objekt referenzieren müssen, das Kopieren und Einfügen.

Datenbankobjekte in der Regel werden sehr früh in der Anfrage Lebensdauer erstellt, so dass bestimmte Vorteile von Singleton-Ness verschwendet werden würde.

Es gibt andere Alternativen zu Singleton, die die Arbeit auf andere Weise erledigen können. Ein Beispiel ist dependency injection, ein phantastischer Begriff für das Übergeben externer Objekte, von denen ein neues Objekt (zum Beispiel ein Datenbank-Handle) an das Objekt zur Konstruktionszeit abhängen würde. Dies kann jedoch kompliziert oder ärgerlich sein. Wenn Sie es richtig machen, können Sie jedes Mal ein Los derselben Objekte injizieren.

Eine andere Alternative ist die Registry pattern, die effektiv ein Container für Dinge ist, die sonst global sein würden. Wenn Sie globale Variablen nicht mögen, aber nichts dagegen haben, dass sie effektiv Namespaced sind, wäre dies eine Lösung, die Sie möchten.

Am Ende, wählen Sie einen Weg, um es zu tun, und bleiben Sie mit dieser einen Weg in Ihrer Codebasis. Persönlich bin ich ein Fan des Datenbankobjekts, das global ist.

+0

Wenn Sie einige Cache verwenden, kann es die Datenbankverbindung vorkommen, dass nicht erforderlich ist. Da das Singleton in einer Klasse verwendet wird, ist es auch möglich, das Autoload zu verwenden. Ich glaube nicht, dass Singleton schlecht für die Datenbankverarbeitung in PHP ist. – Savageman

+0

Sehr wahr. Wenn Sie zwischen Ihrem Code und Ihrer Datenbank eine umfassende Caching-Ebene haben, ist es sehr wahrscheinlich, dass Sie möglicherweise nicht einmal eine Verbindung mindestens zeitweise öffnen müssen. – Charles

+0

Der Punkt über das Testen ist sehr gültig. Das Hauptproblem mit Singleton besteht darin, dass es nicht nur auf eine einzelne Instanz beschränkt ist (wie wäre es mit zwei separaten db-Verbindungen, um dbs zu trennen), sondern auch auf eine bestimmte Implementierung. Wenn Sie testen möchten, müssen Sie Ihre DB-Verbindung durch etwas anderes ersetzen. Abstraktion wird schwieriger, weil es nicht möglich ist, dein Singleton zu verlängern. Die Registrierung behebt viele dieser Probleme. – igorw

0

Es gibt nichts falsch mit dem Singleton-Muster, ich benutze es die ganze Zeit.

Wie Sie sagen, ist es ideal für Ressourcen, die Sie nur eine Instanz haben sollten und die für die Anwendung global sind.

Ich denke, einige Entwickler mögen es nicht wegen Abhängigkeiten, die mit dieser Methode erstellt werden können. Lerne Dependency Injection nach, weil ich denke, dass es erklärt, warum Singletons schlecht sind, aber ich kann mich nicht genau erinnern.

0

Ich verwende einen Singleton-Datenbank-Handler für die meisten meiner kleineren Web-Anwendungen. Wenn es mit einer externen Konfigurationsdatei und PDO als Methode des Datenbankzugriffs gekoppelt ist, kann es immer noch sehr flexibel von Projekt zu Projekt verschoben werden, solange die Methoden nicht anwendungsmodellspezifisch sind (zB getRow oder getAll anstelle von getThing oder getBreakfast) . Ich versuche einfach, sicherzustellen, dass alle meine Zugriffskonstanten separat definiert sind.

Ein Großteil des Leids für Singletons stammt hauptsächlich aus Sprachen, die komplexer sind als PHP.

+0

Ich bin daran interessiert, wie Sie dies mit einer Konfigurationsdatei verknüpfen. – Bill

+0

@Bill - Die meisten Anwendungen, die ich entwerfe, tendieren zum Muster der Front Controller http://www.oreillynet.com/pub/a/php/2004/07/08/ front_controller.html - Im Grunde genommen kann ich eine config.php-Datei hinzufügen, die zahlreiche define-Anweisungen enthält, um Konstanten aus den Zugriffsrechten der Datenbank herauszufiltern, sobald der Front-Controller geladen wird.Dann sind alle Modelle (der Datenbank-Handler selbst) enthalten, so dass ich überall in der App meine Datenbankabfragen mit diesem Handler durchführen kann, da alle Teile der App von diesem einen Einstiegspunkt abstammen. – DeaconDesperado

0

Abgesehen von der globalen Variablen Sache mag die Gemeinschaft Singletons, weil schließlich die Chance besteht, dass Sie eine zusätzliche Instanz der Klasse benötigen. Zum Beispiel können Sie ein Singleton für Ihre Datenbankverbindung verwenden und es funktioniert großartig bis zu dem Moment, wenn Sie wie einmal mit 2 Datenbanken verbinden möchten. An diesem Punkt refaktorieren Sie entweder Ihre gesamte App oder Sie kopieren den Singleton in eine neue Klasse und verwenden diesen. Wie auch immer, du bist auf einem bestimmten Bach ohne Paddel.

Das Singleton-Muster ist jedoch ein Entwurfsmuster, keine Implementierung. Niemand hat gesagt, dass der Code, der Sie auf eine Instanz beschränkt, innerhalb der Klasse sein muss. Ich habe festgestellt, dass Sie die Singleton-Implementierung in die Factory-Methode einfügen können, wenn Sie die Klasse über eine Factory-Methode instanziieren. Wenn Sie eines Tages eine neue Instanz benötigen, können Sie eine neue Factory-Methode hinzufügen, da die Klasse selbst keine Einschränkungen hat. Der Preis dafür ist natürlich, dass Sie Ihren Singleton immer über eine Fabrik und nicht direkt instanziieren.