PHP singleton'ununu oluştururken I) bir soyut sınıf yerine özel bir __ construct (kullanabilir miyim?

4 Cevap php

PHP bir Singleton oluştururken, bunu takip yaparak örneği olamaz emin olun:

class Singleton {

    private function __construct() {}
    private function __clone() {}

    public static function getInstance() {}
}

Ancak, 'soyut' bir sınıf olarak tanımlayan bu örneği olamaz anlamına fark etti. Peki yerine aşağıdaki yapıyor yanlış bir şey var:

abstract class Singleton {

    public static function getInstance() {}
}

İkinci senaryo bana güzel olurdu kod az satırları yazmak için izin verir. (Aslında çok bir fark yapar değil.)

4 Cevap

PHP singleton'ununu oluştururken, ilan __construct ve özel sınıf instanciated olamaz sağlar gibi __clone from the outside: hala onun ilanından içeriden instanciated edilebilir .

Bir sınıf olarak bildirirken abstract, it can not be instanciated at all; bile ilanından içinden.

- Bu ilk durumda bunu olurken ikinci durumda, sizin getInstance() yöntemi sınıfını instanciate mümkün olmayacaktır: Bu çözüm işe yaramaz demektir.

Hayır, çünkü daha sonra bütün olarak sınıf başlatamazsınız (hatta statik getInstance yöntemi). Tekiz örnekte özel yapıcı, sadece aynı sınıftan sadece statik getInstance yöntem kurucu erişebilirsiniz, sağlar.

Singleton'ununu oluştururken Hayır, siz) bir soyut sınıf yerine özel bir __ construct (kullanamazsınız. Niyetinizi gelen uzatmak için bir Özet Singleton oluşturmaktır Ama eğer böyle yapabilirsiniz:

abstract class Singleton
{
   private static $_instances;
   public static function getInstance()
   {
      $className = get_called_class(); // As of PHP 5.3
      if(! isset(self::$_instances[$className] )) {
         self::$_instances[$className] = new $className();
      }
      return self::$_instances[$className];
   }
   protected function __construct( )  {}
   final private function __clone( )  {}
   final private function __wakeup( ) {}
}

Daha sonra bu gibi Singleton adlı uzatabilirsiniz:

class Foo extends Singleton {

    protected $_foo = 1;
    public function setFoo($i) { $this->_foo = $i; }
    public function getFoo() { return $this->_foo; }
}

ve

class Bar extends Singleton {

    protected $_foo = 1;
    public function setFoo($i) { $this->_foo = $i; }
    public function getFoo() { return $this->_foo; }
}

ve manipulating:

$foo1 = Foo::getInstance();
$foo1->setFoo(5);

$foo2 = Foo::getInstance();
var_dump($foo2); 

$bar1 = Bar::getInstance();
var_dump($bar1);

echo new ReflectionObject($foo2);
echo new ReflectionObject($bar1);

However, keep in mind that Singletons are very hard to unit-test ve should be avoided if possible. See my answer here for some background:

Lütfen Singleton::getInstance(), farklı bir sınıfın bir örneğini dönmek gerekiyordu eğer işe yarayabilir.

abstract class Singleton {
  public static function getInstance() {
    static $instance = null;
    if ( is_null($instance) ) {
      $instance = new StdClass; // a different class than 'abstract class Singleton'
      $instance->x = time();
    }
    return $instance;
  }
}

$obj = Singleton::getInstance();

Ama o kafa karıştırıcı bulurlar. Bir tekiz koltuk soyut bir fabrikanın karmaşıklığını birleştirmek için abstract kötüye gibi biraz.