我是一名web开发人员(游戏开发人员作为业余爱好),我见过自己多次使用以下范例。(无论是在开发服务器架构方面,还是在视频游戏开发方面。)它看起来真的很难看,但我不知道该怎么做。我将在游戏开发中举一个例子,因为我最近在这里注意到了它。这是我一直在做的一个RPG。每次战斗开始时,CombatEngine都会创建两个战斗队伍。每个参赛者设置一个与给定参赛者相关联的ArtificialIntelligence对象,该对象负责为没有接收到明确命令的玩家口述移动:
public class Combatant {
ArtificialIntelligence ai = null;
public Combatant()
{
// Set other fields here.
this.ai = new ArtificialIntelligence(this);
}
}下面是我不喜欢的:内部字段(ArtificialIntelligence)在构造过程中需要一个Combatant,因为它需要一些Combatant字段来指示适当的操作。因此,为方便起见,我保留了对作为arg传递给ArtificialIntelligence对象的战斗对象的引用,但该对象包含对ai对象本身的引用!它创建了这种奇怪的递归,但我不知道如何解决它。AI对象需要大量特定于战斗人员的字段,这就是我传入整个对象的原因,但我不喜欢对象如何包含对覆盖战斗人员字段中包含的ai字段的引用,该字段包含在覆盖ai类中。这是不好的做法,还是我想得太多了?
发布于 2012-09-19 11:18:15
尽管这里没有“设计”问题--它只是你传递的一个引用--但一个重要的考虑因素是,在将this传递给另一个类之前,你应该初始化所有的字段。否则,另一个类将以可能不一致的状态访问this。这有时被称为让this从构造函数中“逃脱”。
别这么做..。
public class BadCombatant {
ArtificialIntelligence ai = null;
String someField;
public BadCombatant() {
this.ai = new ArtificialIntelligence(this);
// Don't do this - ArtificialIntelligence constructor saw someField as null
someField = "something";
}发布于 2012-09-19 15:31:20
我肯定会避免循环依赖。单一责任原则应运而生。您可以通过让ArtificialIntelligence在Combatant上操作来消除在Combatant中引用人工智能的需要。将Combatant中依赖于ArtificialIntelligence的所有代码移至ArtificialIntelligence。CombatEngine将执行以下操作:
或者,您可以创建一个名为CombatController的新类,它将传递一个Combatant和一个ArtificialIntelligence。CombatEngine将执行以下操作:
无论您使用上述哪种方法,都可以消除困扰您的循环依赖。
我很抱歉,我不能提供一个代码示例,因为我正在从我的手机上输入这个答案,格式化是一种痛苦。
https://stackoverflow.com/questions/12488044
复制相似问题