2009-07-26 64 views
1

为了我自己的利益,我一直在为自己的小型框架工作,在学习新东西时不断回溯代码。正如你所期望的那样,我有一个几乎被其他所有对象使用的Registry对象。与Singleton交互的最有效方式是什么?

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

absract class AFObject { 

    var $_registry; 

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

} 

所以每一个对象现在将包含一个本地引用到注册表。所以如果我有一百个实例化的对象,那就是数百个对单例的引用。然而这是或多或少效率总是请参阅注册表直接像这样...

class AFRouter extends AFObject { 

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

} 
+2

你应该在php 5中使用public,protected或private来代替var关键字。 – 2009-07-26 10:20:02

回答

0

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

在这种情况下,将

class AFRouter extends AFObject { 

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

} 

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

class AFRouter extends AFObject { 

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

} 
2

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

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

我要离开了选项1(抽象基类),因为那时所有的类都变得依赖于一些其他类...

使用静态类像Yngve Sneen提到的将是最好的办法我意见如果你想保持注册表设置。

类似于: registry :: set('var1',$ var1); $ var1 = registry :: get('var1');

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