我曾经创建过像这样的单例类的实例:
$Singleton = SingletonClassName::GetInstance();
和非单身人士课程:
$NonSingleton = new NonSingletonClassName;
我认为我们不应该区分我们如何创建类的实例,无论这是否是单例。如果我看到其他班级的感知,我不在乎班级是否需要单身人士班级。所以,我仍然不满意php如何处理单例类。我想,我总是想写:
$Singleton = new SingletonClassName;
只是另一个非单身人士类,是否有解决这个问题的方法?
答案 0 :(得分:3)
最好是另一种方式 - 为非单身人士提供factory-method,并使用以下方式获取他们的实例:
$NonSingleton = NonSingletonClassName::createInstance();
这是Java的推荐最佳实践(在Effective Java中),但它适用于大多数面向对象的语言。
答案 1 :(得分: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
答案 2 :(得分:1)
您不能以与常规类实例相同的方式创建Singleton。 new
将始终返回一个新实例,因此您必须使构造函数非公共,因此您必须使用不同的方法从类中调用它。
您可以在所有类上使用工厂方法,例如总是做getInstance()
,如另一个答案所示。另一种选择是使用知道是否返回的Service Locator和Dependency Injection Framework。
答案 3 :(得分:1)
根据new
关键字的含义,您想要的只是无关紧要。 new
创建了一个新的类实例,这就是为什么它命名为 new : - )
答案 4 :(得分:1)
我知道这是一个非常古老的帖子,但我在下面的链接的帮助下更好地理解了Factory模式。
所以,如果它有助于未来徘徊。 。 。 。这里去了
http://www.devshed.com/c/a/PHP/Design-Patterns-in-PHP-Factory-Method-and-Abstract-Factory/1/
掌握和理解基本实现非常简单。