如果你有一个创建某种新对象的工厂类,而那个工厂类是一个单例,如下所示:
class Database_Factory extends Base_Factory {
private static $factory;
private $objects = array();
public function __get($profile) {
// check for object and return it if it's created before
}
public static function getInstance(){
if (!self::$factory)
self::$factory = new self();
return self::$factory;
}
}
当某个对象需要自己的工厂时,相同的代码会在任何时候重复。所以我决定让这个工厂类抽象起来,只为每个工厂实现特定的例程。但是PHP不允许实例化抽象类。
abstract class Base_Factory {
public static function getInstance(){
if (!self::$factory)
self::$factory = new self();
return self::$factory;
}
}
致命错误:无法实例化抽象类Base_Factory
你怎么做?
发布于 2009-11-30 18:10:55
在PHP方法中,self
总是引用定义方法的类。从5.3.0版本开始,PHP支持“后期静态绑定”,可以使用static
关键字访问被覆盖的静态方法,以及使用函数get_called_class()
在静态上下文中获取派生类的名称。
但是,您的设计有一个主要缺陷:在Base_Factory
中定义的静态属性$factory
在所有派生类之间共享。因此,第一次创建单例并将其存储在此属性中时,无论使用哪个派生类,对getInstance()
的所有其他调用都将返回相同的对象。
您可以使用静态字典将类名映射到单例对象:
abstract class Base_Factory {
private static $_instances = array();
public static function getInstance() {
$class = get_called_class();
if (!isset(self::$_instances[$class])) {
self::$_instances[$class] = new $class();
}
return self::$_instances[$class];
}
}
哦,还有一件事:你正在为单例对象寻找重用代码的可能性,这可能是一个线索,表明你过度使用了单例设计模式!问问你自己,你计划作为单例实现的类是否真的是单例,以及是否没有你可能想要拥有特定类的多个实例的用例。
通常,只使用一个单例来表示当前的“应用程序上下文”要好得多,它为相对于该上下文是单例的对象提供访问器。
发布于 2010-01-20 23:26:58
PHP 5.3+
abstract class Singleton
{
/**
* Instance
*
* @var Singleton
*/
protected static $_instance;
/**
* Constructor
*
* @return void
*/
protected function __construct() {}
/**
* Get instance
*
* @return Singleton
*/
public final static function getInstance() {
if (null === static::$_instance) {
static::$_instance = new static();
}
return static::$_instance;
}
}
发布于 2009-11-30 17:59:33
仅PHP >= 5.3
abstract class Base_Factory {
protected static $factory;
public static function getInstance(){
if (!self::$factory) {
$class = get_called_class();
self::$factory = new $class();
}
return self::$factory;
}
}
https://stackoverflow.com/questions/1818765
复制相似问题