$P1 = new Player(array(
'name' => 'Player 1',
'strat' => new Strategy(&$this)
));
这或多或少都是我想要做的。对$ this的引用显然是错误的。完成这样的事情的最佳方法是什么?
基本上,新的Strategy对象需要知道它属于哪个Player。
当然,我可以这样做:
$P1 = new Player();
$P1->strat = new Strategy(&P1);
但这似乎并不简洁。
更新
我想不是在数组中传递新的策略对象,而是传递策略类的名称,然后在Player构造函数中实例化一个新对象。
答案 0 :(得分:3)
$P1->strat->owner =$P1;
这将足够好。
谈话正在进行中。
好的,如果我们从理论和概念的角度来看待这个问题,我们可以通过几种不同的方式解决隐含的问题。让我们考虑玩家的策略是什么。
顾名思义,策略基本上是一个驱动因素,可能会影响特定环境中的游戏行为。这进一步表明以下方法是有道理的:
$player->useStrategy($strategy);
此外,玩家最有可能在给定范围内行动,因此,它将使用$ strategy对象作为控制器,并将输入从满足条件的任何条件传递到战略行为控制器。那,鉴于玩家可以:
1)帮助确定要开展的活动
2)使用玩家界面来响应战略行为必须采取的任何行动
现在,我们可以假设可以有不同的策略,可以很容易地应用于任何Player,因为策略类实现了Strategy Interface。在这种情况下,战略,不需要知道任何关于玩家的事情。如果只是,有不同类型的玩家具有不同的接口,允许不同的控制组。但在这种情况下,为特定的播放器类设置扩展类以实现这些播放器提供的额外功能会更明智。
class Strategy {
private $player;
public usePlayer($player){
$this->player = $player;
}
public makeNextMove($input){
1) return array($a,$b);
2) return new Behavior_NextMove()->setTarget($a,$b);
3) $this->player->move($a, $b);
}
}
class Strategy_MegaPlayer extends Strategy {
public makeNextMove($input){
parent::makeNextMove($input);
$player->useMegaPlayerSpecialPower();
}
}
或者,可以有集中的策略对象,通过配置界面,基于玩家的类型决定适当的动作和策略,两者都基于玩家类型和其配置。
但似乎结构合理的战略支持课程对您最有利。
答案 1 :(得分:2)
你应该使用getter / setters:
$strategy = new Strategy();
$player = new Player('Player 1', $strategy);
$strategy->setPlayer($player);
使用&符号(&
)前缀是不必要的,因为对象通过引用传递。
答案 2 :(得分:1)
您可以让Player构造函数将$this
传递给通过调用Strategy
上的setter传入的Strategy
对象。
但是,您可能需要重新考虑Strategy
对象是否确实需要指向Player
对象,或者Player
对象是否确实需要指向Strategy
}宾语。如果这两个类紧密耦合,那就是代码味道。也许某些功能需要从一个功能移到另一个功能。