首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >扩展抽象单例类

扩展抽象单例类
EN

Stack Overflow用户
提问于 2009-11-30 17:31:34
回答 6查看 16.1K关注 0票数 22

如果你有一个创建某种新对象的工厂类,而那个工厂类是一个单例,如下所示:

代码语言:javascript
复制
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不允许实例化抽象类。

代码语言:javascript
复制
abstract class Base_Factory {
    public static function getInstance(){
        if (!self::$factory)
            self::$factory = new self();
        return self::$factory;
    }
}

致命错误:无法实例化抽象类Base_Factory

你怎么做?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2009-11-30 18:10:55

在PHP方法中,self总是引用定义方法的类。从5.3.0版本开始,PHP支持“后期静态绑定”,可以使用static关键字访问被覆盖的静态方法,以及使用函数get_called_class()在静态上下文中获取派生类的名称。

但是,您的设计有一个主要缺陷:在Base_Factory中定义的静态属性$factory在所有派生类之间共享。因此,第一次创建单例并将其存储在此属性中时,无论使用哪个派生类,对getInstance()的所有其他调用都将返回相同的对象。

您可以使用静态字典将类名映射到单例对象:

代码语言:javascript
复制
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];
    }
}

哦,还有一件事:你正在为单例对象寻找重用代码的可能性,这可能是一个线索,表明你过度使用了单例设计模式!问问你自己,你计划作为单例实现的类是否真的是单例,以及是否没有你可能想要拥有特定类的多个实例的用例。

通常,只使用一个单例来表示当前的“应用程序上下文”要好得多,它为相对于该上下文是单例的对象提供访问器。

票数 38
EN

Stack Overflow用户

发布于 2010-01-20 23:26:58

PHP 5.3+

代码语言:javascript
复制
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;
    }
}
票数 9
EN

Stack Overflow用户

发布于 2009-11-30 17:59:33

仅PHP >= 5.3

代码语言:javascript
复制
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;
    }
}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1818765

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档