2

A 类的一个实例实例化了几个其他对象,例如来自 B 类:

$foo = new B();

我想从 B 中的方法访问 A 的公共类变量。

除非我遗漏了什么,否则这样做的唯一方法是将当前对象传递给 B 的实例:

$foo = new B($this);

这是最佳做法还是有其他方法可以做到这一点?

4

4 回答 4

2

这对我来说看起来不错,我倾向于使用“维护这个的人会理解它吗?”的经验法则。这是一个易于理解的解决方案。

如果只有一个“A”,您可以考虑使用注册表模式,例如参见http://www.phppatterns.com/docs/design/the_registry

于 2008-09-15T11:56:50.853 回答
1

我会首先检查您是否使用了错误的模式:从您的应用程序逻辑来看,B 真的应该知道 A 吗?如果 B 需要了解 A,那么亲子关系似乎还不够。例如,A 可以是孩子,或者 A 的部分逻辑可以进入层次结构中“低于”B 的第三个对象(即不知道 B)。

也就是说,我建议你在 B 中有一个方法来将 A 注册为数据源,或者在 A 中创建一个方法来将 B 注册为观察者,并在 B 中创建一个匹配方法,A 用来通知 B 值更改。

于 2008-09-15T11:52:35.073 回答
0

与 Paul 所说的类似,如果只有一个 A,您可以将其实现为单例。然后,您可以将 A 的实例作为参数传递给构造函数(聚合),使用 setter 方法(本质上再次聚合),或者您可以直接在构造函数中设置此关系(组合)。

然而,虽然单例很强大,但要小心使用组合来实现它们。很高兴认为您可以这样做并摆脱构造函数参数,但这也使得在不重写代码的情况下无法用其他东西替换 A。就个人而言,我会坚持聚合,即使使用单例

$foo = new B( A::getInstance() );
于 2008-09-16T19:49:29.803 回答
0
$foo = new B($this);

不幸的是,这样的代码不符合我的需求。还有其他方法可以访问父对象属性吗?

我将尝试解释原因。我们编写了一个游戏软件,一些类具有非常“不寻常”的依赖关系,并以不同的方式相互影响。这就是为什么代码有时在每个实例中如果没有与父级的链接就几乎无法支持(有时甚至来自不同上下文的多个父级,即一个小队可能属于 Battle 和 User 等......)。

现在链接不满足我的原因。当我为客户端生成输出时,我使用 XML 中的一种序列化对象。它工作得非常好,直到它遇到递归引用,比如那些指向父母的链接。我可以使它们受到保护,但随后它们就失去了使用,即(虚拟示例)

$this->squad->battle->getTeam($tid)->getSquad($sqid)->damageCreature(...);

另一种方法 - 在每个可序列化类中实现序列化方法并在序列化器中调用它,如下所示:

$obj->toXML($node);
$this->appendChild($node);

但有很多东西要写和支持!有时我会动态地为序列化程序生成对象(更少的流量)。

我什至想到了一个技巧:“教”序列化程序忽略某些类中的某些属性))。呃……坏主意……

这是一个漫长的讨论,但相信我,Registry 和 Observer 不适合。还有其他想法吗?

于 2009-05-19T16:51:35.183 回答