什么是与Singleton交互的最有效方式?

时间:2009-07-26 10:05:52

标签: php oop

为了自己的利益,我一直在为自己的小框架工作一段时间,在我学习新东西的过程中不断回头看代码。正如您所料,我有一个几乎所有其他对象都使用的Registry对象。

目前,最基本的对象(AFObject)设置有点像这样

absract class AFObject {

    var $_registry;

    function __construct(){
        $this->_registry = AFRegistry::getInstance();
    }

}

因此,每个对象现在都包含对注册表的本地引用。因此,如果我有一次实例化数百个对象,那就是数百个对单例的引用。但总是像这样直接引用注册表会有多少或多少效率......

class AFRouter extends AFObject {

    function someMethod( $bar ){
        AFRegistry::$foo = $bar;
    }

}

3 个答案:

答案 0 :(得分:2)

在我看来,“注册表”类型的类smells

既然你提到你这样做是为了学习和变得更好,你有没有考虑完全根除你的注册表类并采取另一种方法?也许将所需的数据推送到类构造函数而不是从类的内部拉出来?

我省略了选项1(抽象基类),因为那时你的所有类都依赖于其他一些类......

如果您希望保留注册表设置,那么在我看来,使用像Yngve Sneen这样的静态类是最好的方法。

像: registry :: set('var1',$ var1); $ var1 = registry :: get('var1');

答案 1 :(得分:1)

考虑一下:

class AFRouter extends AFObject {
  function someMethod($bar) {
    global $af_registry;
    $af_registry->setFoo($bar);
  }
}

甚至:

class AFRouter extends AFObject {
  function someMethod($bar) {
    af_registry_set('foo', $bar);
  }
}

禁止语法,这与您当前的解决方案之间基本没有区别。

是的,这意味着您的注册表本质上是一个全局变量。是的,全局变量存在问题。更好的选择是pass in the dependencies

答案 2 :(得分:0)

我不认为你应该考虑这种情况下的效率(因为100个引用确实不是问题,并且有点过早优化)。但请考虑代码中最优雅的内容。另外,考虑一下你是否需要一个单例(它可以实现为静态类吗?)。我可能会选择使用你的第二种情况,因为这会使你的代码更加明显(至少我认为是这样)。

在那种情况下,它将是

class AFRouter extends AFObject {

    function someMethod( $bar ){
        AFRegistry::getInstance()->$foo = $bar;
    }

}

或者如果你封装你的财产:

class AFRouter extends AFObject {

    function someMethod( $bar ){
        AFRegistry::getInstance()->setFoo($bar);
    }

}