Kayıt veya PHP Singleton deseni?

3 Cevap php

Şimdi PHP sınıfları ve nesneler ile çalışıyorum. Bu soruda alanları ve yöntemlerinin adları sadece bu yüzden bahsediyorum ben ne bir fikir olsun oluşur.

Bu tekil ve kayıt defteri tasarım kalıpları kullanarak ilgilidir.

Şimdi bir veritabanı nesnesi, Cache nesne, Çekirdek Settings nesnesini, Session hemen hemen her sınıf Ben bu erişimi olması gerekir nesneyi erişmek gerekir Diyelim ki. SO I 1 kayıt sınıf nesnesine içine bu nesnenin tüm 4 saklamak için bir kayıt defteri kullanmak istiyorsunuz. Ben o easiyl sadece bu erişmek için gereken başka herhangi bir nesne içine benim 1 nesne geçebileceği. Böylece bugüne kadar büyük geliyor ama ben bu nesnelerin tüm 4 gerekmez bazı sınıfları, ne sadece benim diğer sınıfların bazı veritabanı nesne veya Session nesnesi erişmek gerekiyorsa? Ne varsa Perfromance için sadece bu diğer nesneler içinde bir Singleton kullanmak için iyi olurdu ya da devam edin ve bu benim kayıt defteri kullanmak aynı olurdu?

Ben nesneleri performnce kazanç herhangi bir tür olacağını bilmek için PHP nasıl çalıştığını yeterince iyi bilmiyorum (daha az bellek kullanımı, cpu kullanımı, yük zaman).

Birini ya da diğer, ben bunu üretim zamanı ya da bir şey etkilemeden eter yol gidebilir aşamada duyuyorum kullanarak herhangi bir kazanç olacağını Yani bu deneyimi olan herkes belki bana söyleyebilir. Ben şimdi eğer iyi yöntemi kullanmak istiyorum.

3 Cevap

Bu sizin uygulamaya bağlıdır. Hala 4 sınıfların arasından 3 gerekiyorsa, o zaman işlemek için daha Registry kullanmak daha ideal olurdu 3 bağımsız Eğer dördüncü gerekmez çünkü. Tembel Sınıfları yüklerken bellek ayak izi azaltmak için bir yaklaşım olabilir, ama sonra ne zaman nesneleri oluşturmak için kayıt talimat gerekiyor ve bu singletons işleme daha çok farklı değil olurdu. Alternatif olarak, bir n-parametre kurucu oluşturmak veya sınıfların inşaat sırasında örneğini senin sicil talimat için bir dizi kullanabilirsiniz.

class Registry {
    public $class1;
    public $class2;

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

}

Sonra sınıflar örneğini hangi belirterek Kayıt örneğini.

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

Açıktır ki yapıcı varsayılan olarak tüm sınıfları başlatmasını için hesap sıfır parametreleri işlemek isterim.

Yalnızca gerçekten ihtiyacınız olan nesneleri yüklemek için tembel yükleme uygulayabilirsiniz:

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;
    }
}

Veritabanı bağlantı parametrelerini kaydetmek için kod okuyucuya alıştırma olarak bırakılmıştır.

Belki de bu doğru Singleton-Kayıt kalıptır. OFC, farklı şeyler, SplFixedArray, ArrayAccess arayüzü, ve diğerleri uygulayabilirsiniz. Ayrıca yoketmeyi eklemek ve olası herhangi bir sızıntı sağlamak için iç nesneleri yok etmek için kötü değil.

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)