为了自己的利益,我一直在为自己的小框架工作一段时间,在我学习新东西的过程中不断回头看代码。正如您所料,我有一个几乎所有其他对象都使用的Registry对象。
目前,最基本的对象(AFObject)设置有点像这样
absract class AFObject {
var $_registry;
function __construct(){
$this->_registry = AFRegistry::getInstance();
}
}
因此,每个对象现在都包含对注册表的本地引用。因此,如果我有一次实例化数百个对象,那就是数百个对单例的引用。但总是像这样直接引用注册表会有多少或多少效率......
class AFRouter extends AFObject {
function someMethod( $bar ){
AFRegistry::$foo = $bar;
}
}
答案 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);
}
}