2010-04-06 73 views
5

我用来创建一个单独的类像这样的实例:扩展单个类

$Singleton = SingletonClassName::GetInstance(); 

和非单例类:

$NonSingleton = new NonSingletonClassName; 

我认为我们不应该区分我们如何创造一个类的实例是否是单例。如果我看着其他班级的感知,我不在乎班级是否需要单身班。所以,我仍然不熟悉php如何对待单身课程。我想,我总是想写:

$Singleton = new SingletonClassName; 

只是另一个非单身类,有没有解决这个问题?

+1

Tthis不是问题 - 你抱怨说你不喜欢一个模式是如何完成的。 -1 – 2010-04-06 12:57:06

+1

这是一个非常合理的问题。 +1,因为-1不是:P – Leo 2010-04-06 12:59:06

+2

不要使用PHP? – Kevin 2010-04-06 12:59:36

回答

2

我不会推荐它,因为它会使你的代码更加难于理解(人们认为新指一个全新的对象)。但是,我不会重新使用单身人士。

此代码的基本思想是围绕单例包装。通过该包装器访问的所有函数和变量实际上都会影响单例。如下面的代码没有实现很多的魔术方法和SPL的接口,但它们可以根据需要

代码

/** 
* Superclass for a wrapper around a singleton implementation 
* 
* This class provides all the required functionality and avoids having to copy and 
* paste code for multiple singletons. 
*/ 
class SingletonWrapper{ 
    private $_instance; 
    /** 
    * Ensures only derived classes can be constructed 
    * 
    * @param string $c The name of the singleton implementation class 
    */ 
    protected function __construct($c){ 
     $this->_instance = &call_user_func(array($c, 'getInstance')); 
    } 
    public function __call($name, $args){ 
     call_user_func_array(array($this->_instance, $name), $args); 
    } 
    public function __get($name){ 
     return $this->_instance->{$name}; 
    } 
    public function __set($name, $value){ 
     $this->_instance->{$name} = $value; 
    } 
} 

/** 
* A test singleton implementation. This shouldn't be constructed and getInstance shouldn't 
* be used except by the MySingleton wrapper class. 
*/ 
class MySingletonImpl{ 
    private static $instance = null; 
    public function &getInstance(){ 
     if (self::$instance === null){ 
      self::$instance = new self(); 
     } 
     return self::$instance; 
    } 

    //test functions 
    public $foo = 1; 
    public function bar(){ 
     static $var = 1; 
     echo $var++; 
    } 
} 

/** 
* A wrapper around the MySingletonImpl class 
*/ 
class MySingleton extends SingletonWrapper{ 
    public function __construct(){ 
     parent::__construct('MySingletonImpl'); 
    } 
} 

例子

$s1 = new MySingleton(); 
echo $s1->foo; //1 
$s1->foo = 2; 

$s2 = new MySingleton(); 
echo $s2->foo; //2 

$s1->bar(); //1 
$s2->bar(); //2 
中添加它不是完美的
+0

哇,这很酷。非常感谢你 ! – cakyus 2010-04-08 10:08:35

3

它最好是周围的其他方式 - 提供非单身一factory-method,并使用获得它们的实例:

$NonSingleton = NonSingletonClassName::createInstance(); 

这是对Java(在Effective Java)建议的最佳实践,但它适用到大多数面向对象的语言。

1

不能像常规类实例一样创建Singleton。 new将始终返回一个新的实例,因此您必须使构造函数非公共,因此您必须有不同的方法从类中调用它。

您可以在所有类上都有工厂方法,例如总是做getInstance()像在另一个答案中所示。另一种选择是使用知道是否返回什么的Service LocatorDependency Injection Framework

1

根据什么new关键字意味着所有你想要的是无关紧要的。 new创建新的类实例,这就是为什么它命名为 :-)

+0

哈哈..你是绝对正确的:-) – cakyus 2010-04-08 10:17:17