2010-03-27 12 views
6

Haben Sie gefunden Zend_Registry nützlich?Zend_Registry: reale Beispiele

Für welche Aufgaben sollte es verwendet werden? Für welche nicht?

Der globale Status für Variablen ist keine gute Methode. Hauptobjekte können über $front->setParam('paramName', $object), globalen Status injiziert haben, also was ist der Zweck von Zend_Registry ?.

+3

Sie sollten 'Zend_Registry' von der 'Zend_Registry :: getInstance()' -singelton unterscheiden. Die Klasse selbst wird intern in ZF verwendet, ohne global zu sein, also 'Zend_Registry'! = Global. – chelmertz

Antwort

9

Zitiert PoEAA on Registry Pattern:

Wenn Sie ein Objekt finden Sie in der Regel mit einem anderen Objekt starten, die eine Verbindung zu ihm hat, und verwenden Sie den Verein, um es zu navigieren. Wenn Sie also alle Aufträge für einen Kunden finden möchten, beginnen Sie mit dem Kundenobjekt und verwenden eine Methode, um die Aufträge zu erhalten. In einigen Fällen haben Sie jedoch kein geeignetes Objekt, mit dem Sie beginnen können. Sie kennen vielleicht die ID-Nummer des Kunden, haben aber keine Referenz. In diesem Fall brauchen Sie eine Art Lookup-Methode - einen Finder - aber die Frage bleibt: Wie gelangen Sie zum Finder?

Der Hauptgrund, warum ich die Registrierung verwende (wenn ich es verwenden) ist, weil es einen leicht zugänglichen Anwendungsbereich schafft. Mit der Registrierung muss ich keine Objekte über den gesamten globalen Geltungsbereich verstreuen; nur die Registrierung selbst ist global. Es ist bequem zu Lookup, was ich in die Registry von überall her geworfen haben, darunter das Modell:

  • Zend_Cache, Zend_Translate, wichtige Anwendungen Pfade, etc

Aber genau wie mit Singletons, Registry ist oft verpönt. Hier ist ein article by Brandon Savage with some thought about why not to use the Registry. Die Hauptargumente gegen das Register sind

  • es macht Komponententests härter
  • unerfahrene Programmierer könnte zu viel hineinwerfen und kümmern sich nicht um die richtige Gestaltung

Diejenigen, die gegen das Register stimmen in der Regel befürworten die Verwendung von Dependency Injection, obwohl es sollte beachtet werden, dass Sie auch die Registrierung injizieren können, sobald Sie eine Instanz davon haben. Sie haben Inversion of Control dann aber nicht, weil das using-Objekt zieht, was es von der Registrierung braucht. Die Verwendung der Registrierung als Service Locator ist jedoch ein gültiger Ansatz.

Siehe hierzu article by Martin Fowler about ServiceLocator vs. Dependency Injection.

Wie in den Kommentaren auf Ihre Frage hingewiesen, Zend_Registry ist kein strenger Singleton. Sie können mehrere Instanzen neben der globalen Instanz, die Sie mit Zend_Registry::getInstance() erhalten, auch an einer Stelle instanziieren. So können Objekte ihre eigene Registrierung haben. Aber wenn man Registry auf diese Weise benutzt, ist es im Grunde nur ein verklärtes ArrayObject.

Schlussbemerkung: Verwenden Sie es wie bei allen Design Patterns, wenn es für Ihr Problem geeignet ist.

10

Wenn Sie $front->setParam verwenden, definieren Sie einen Parameter im Front Controller.

Aber dieser Parameter ist nicht verfügbar in (oder sollte nicht verwendet werden) andere Schichten der Anwendung, wie das Modell.

Zend_Registry ist wie jede andere globale Variable von überall in Ihrer Anwendung verfügbar - auch im Modell.

Aber ein Registry statt einer Reihe von globalen Variablen sichert Ihnen nicht viele globale Variablen überall haben: selbst wenn ein Registry mit einigen globalen Zustand impliziert (was nicht so gut ist, sollte man sagen), es ist besser, alles an einem Ort zu haben.


Ein paar Beispiele aus der Praxis sein könnte:

  • Speichern Sie die Verbindung zur Datenbank, die in der bootsreap hergestellt ist, aber in den Modellen
  • Global speichert einen Adapter (oder verwendet irgendeinen Mechanismus), der verwendet wird, um Übersetzungen/Lokalisierung in allen Schichten Ihrer Anwendung zu machen - Zend Framework selbst tut das.


Am Ende finde ich Zend_Registry nützlich?

Nun, wenn es darum geht, einen globalen Zustand zu haben, ja, es ist nützlich.

Aber wenn es Nutzung ist vermieden werden kann, könnte es besser sein: vom Konzept her gesehen, nicht mit Ihren Klassen hängen von jedem globalen Zustand ist besser: leichter wiederverwenden, einfacher zu testen, ...
über das, Vielleicht möchten Sie einen Blick darauf werfen, was Dependency Injection ist.

+0

Ist $ front-> setParam die Abhängigkeitsinjektion nicht? Was ist mit den Zend Anwendungsressourcen? – takeshin

4

Ich stimme zu Pascal MARTIN. Ich habe gerade angefangen mich an Dependency Injection zu gewöhnen. Aber ich habe keine Möglichkeit gefunden, Objekte in Controller zu injizieren. Was ich kürzlich getan habe, war de Registry zu verwenden, um auf einen Dienst im Controller zuzugreifen. In einem aktuellen Projekt mache ich folgendes:

Bootstrap:

// simple DI without an IoC container, and what have you 
$dbAdapter = Zend_Db::factory(/* bla bla */); 
$mediaService = new Service_Media(new Repository_Media_Db($dbAdapter)); 
$registry  = Zend_Registry::getInstance(); 
$registry->mediaService = $mediaService; 

... dann in einem Controller:

public function init() 
{ 
    $this->_mediaService = Zend_Registry::get('mediaService'); 
} 

public function listAction() 
{ 
    // simplified 
    $this->view->media = $this->_mediaService->listAllUploadedVideos(); 
} 

Hoffentlich ist dies ein gutes Beispiel für Sie.

+0

Wird eine Registrierung wirklich benötigt? Action-Helfer wäre nicht genug? – takeshin

+0

Was ich normalerweise mache: _initMediaService() {return $ service;} ;, dann im Action Controller: $ front-> getParam ('mediaService'); – takeshin

+0

Aktion Helfer ist auch eine gute Option, denke ich. Das ist ... solange es nur in einem Controller benötigt wird. Möglicherweise haben Sie jedoch eine Situation, in der dieser Service auch in einem anderen Service- oder Business-Layer benötigt wird. Obwohl das durch die Konstruktorinjektion wieder in Ordnung gebracht werden könnte, denke ich. Hmm ..Ich habe noch nicht wirklich zu viel darüber nachgedacht, wie Sie sehen können. Bis jetzt ist dieses Beispiel für meine Zwecke geeignet. Ich denke, es gibt viele Möglichkeiten, eine Aufgabe zu erfüllen. Alles hängt davon ab, wie viel Puristen Sie angehen, nehme ich an. Sobald ich etwas mehr in DI gegraben habe, werde ich wahrscheinlich diesen Ansatz aufgeben. –