Registry ou Singleton pattern en PHP?

je travaille avec des classes et des objets PHP maintenant. Dans cette question, les noms des champs et des méthodes sont inventés juste pour que vous ayez une idée de ce dont je parle.

Elle est liée à l'utilisation du singleton et le registre des modèles de conception.

permet maintenant de dire que j'ai besoin d'accéder à un objet de base de données, un objet Cache, un objet Core Settings, un objet Session dans presque toutes les autres classes que j'aurai besoin d'accéder à celles-ci. Donc j'utiliserais un registre pour conservez tous les 4 de ces objets dans un objet de classe de registre. Je pourrais alors easiyl juste passer dans mon 1 objet dans n'importe quel autre objet qui a besoin d'accéder à ceux-ci. Donc cela semble génial jusqu'à présent, mais que se passe-t-il si j'ai des classes qui n'ont pas besoin de tous les 4 de ces objets, et si j'ai seulement besoin d'accéder à l'objet base de données ou à L'objet Session dans certaines de mes autres classes? Pour perfromance serait-il préférable d'utiliser un singleton à l'intérieur de ces autres objets ou serait-il le même pour aller de l'avant et utiliser ma base de registre dans ces?

Je ne sais pas assez bien comment les objets fonctionnent en PHP pour savoir s'il y aurait une sorte de GAIN performnce (moins d'utilisation de la mémoire, de l'utilisation cpu, du temps de chargement).

donc n'importe qui avec de l'expérience dans ce peut-être peut me dire s'il y aurait un gain En utilisant l'un ou l'autre, je suis à l'étape où je peux aller plus loin sans que cela affecte le temps de production ou quoi que ce soit. Je voudrais utiliser la meilleure méthode si je peux maintenant.

10
demandé sur JasonDavis 2010-01-20 17:20:12

3 réponses

cela dépend de votre application. Si vous avez encore besoin de 3 des 4 classes, alors qu'il serait plus idéal pour utiliser le Registre de gérer les 3 indépendamment seulement parce que vous n'avez pas besoin d'un quatrième. Charger les classes paresseusement serait une approche pour réduire l'empreinte mémoire, mais alors vous devez donner des instructions au registre quand créer les objets et ce n'est pas très différent de manipuler des singletons. Alternativement, vous pouvez créer un constructeur n-Paramètre ou utiliser un tableau pour instruire votre registre quelles classes instancier pendant la construction.

class Registry {
    public $class1;
    public $class2;

    function __construct($uses) {
        foreach($uses as $class) {
            $this->{$class} = new {$class}();
        }
    }

}

instanciez ensuite votre registre en spécifiant les classes à instancier.

$reg = new Registry(array('class1'));

vous voudriez évidemment que votre constructeur gère les paramètres zéro pour tenir compte de l'instanciation de toutes les classes par défaut.

3
répondu Bret Kuhns 2010-01-20 14:33:53

vous pouvez implémenter le chargement paresseux pour ne charger que les objets dont vous avez vraiment besoin:

class Registry
{
    private static $database = null;

    private static function connectDatabase($key)
    {
        [... do connection stuff ...]
    }

    public static function getDatabase($key)
    {
        if (Registry::$database == null)
        {
            Registry::connectDatabase($key);
        }
        return Registry::$database;
    }
}

le code pour enregistrer les paramètres de connexion à la base de données est laissé comme exercice au lecteur.

4
répondu Morfildur 2010-01-20 14:24:39

peut-être que c'est le modèle de Registre unique approprié. OFC, vous pouvez mettre en œuvre différentes choses, SplFixedArray, ArrayAccess interface, et d'autres. En outre, il n'est pas mauvais d'ajouter la destruction et de détruire les objets intérieurs pour assurer aucune fuite possible.

class oRegistry{
   private static $instance = null;

   private $storage = array();

   private function __construct(){}

   private function __clone(){}

   public static function getInstance(){
      if( self::$instance === null ){
         self::$instance = new self();
      }
      return self::$instance;
   }

   public function attach($name, $o) {
      if( true === isset($this->storage[$name]) ) {
          throw new Exception('The instance with name '.$name.' already exists in registry.');
      }
      if( !empty( $name ) ) {
          $this->storage[ $name ] = $o;
      }
   }

   public function detach( $name ){
       if( isset( $this->storage[ $name ] ) ) {
           $this->storage[ $name ] = null;
           unset( $this->storage[ $name ] );
       }
   }

   public function get( $name ){
       if( false === isset( $this->storage[$name] ) ) {
           throw new Exception('Invalid instance requested');
       }
       return $this->storage[ $name ];
   }
}

// usage example
$storage = oRegistry::getInstance();
$obj = new stdClass;
$obj2 = new stdClass;
$obj->test1 = 'test';
$obj2->test2 = 't2';

$storage->attach( 'test1', $obj );
$storage->attach( 'test2', $obj2 );

$got = $storage->get( 'test2' );
var_dump($got); // object(stdClass)#3 (1) { ["test2"]=> string(2) "t2" }

$storage->detach( 'test2' );
$got = $storage->get( 'test2' );
var_dump($got); // bool(false)
1
répondu Valentin Rusk 2014-01-15 16:10:30