我尝试实现一个能够将参数传递给讲师的单例模式。对于单例模式,我想创建一个基类。这样做的主要问题是,并不是所有的派生类都有相同数量的参数。到目前为止,对于单例基类,我有以下内容:
abstract class Singleton
{
/**
* Function: __construct
* Description: the function which creates the object.
*/
protected function __construct()
{
}
private final function __clone()
{
}
public static function getInstance()
{
$args = func_get_args();
static $instance = null;
return $instance = $instance ? : new static();
}
}
到目前为止,这是有效的,但我不能用它将参数传递给构造函数。当然,我可以直接将$args数组传递给构造函数,但我不希望在派生类的每个构造函数中展开数组,我希望能够将参数作为普通参数传递。
我已经尝试了几种方法:我尝试使用call_user_func_array,但是我不知道如何使用这个函数构造对象(如果可能的话),我还尝试使用ReflectionClass。ReflectionClass的问题是这个类不能访问构造函数,因为构造函数是受保护的。
那么,有没有人有什么办法可以帮我解决这个问题呢?
ps。如果我表现得困难,我很抱歉,但我只是试图找到最佳解决方案(并理解该解决方案)。
发布于 2011-02-05 01:14:12
首先,最好使用静态成员变量。由于不能动态调用new
,因此只能使用init
函数。
我会怎么做:
abstract class Singleton
{
protected static $instances = array();
/**
* Function: __construct
* Description: the function which creates the object.
*/
private function __construct()
{
}
private final function __clone()
{
}
protected abstract function _init();
public static function getInstance()
{
$args = func_get_args();
$class = strtolower(get_called_class());
if (!isset(self::$instances[$class])) {
self::$instances[$class] = new $class();
call_user_func_array(
array(
self::$instances[$class],
'_init'
),
$args
);
}
return self::$instances[$class];
}
}
因此,您的扩展类将使用_init
而不是__construct
class foo extends Singleton {
protected function _init($foo) {
$this->foo = $foo;
}
}
请注意,Singleton::__construct
现在是私有的,以防止被滥用。
所有这一切都无法抵挡这样一个事实,即singletons是evil,should是avoided。所以如果你必须使用它们,你可以使用它们。但是找个更好的方法,因为他们真的那么糟糕。
发布于 2011-02-05 01:15:55
如果你想在你的实例中设置一些默认设置,你可以在子实例中设置一个私有设置数组:
class Simpleton extends Singleton
{
private $settings;
protected function __construct()
{
$this->settings = array(
//default settings here
);
}
}
不要试图将参数合并到单例中。如果你需要一个参数化的构造函数,那就别费心使用单例了。
单例应该有缺省值,然后是访问器/变更器,用于调整应该可调整的任何设置。
https://stackoverflow.com/questions/4900720
复制相似问题