Sal*_*Sal 9 java design-patterns
我是一个网络开发者(游戏开发作为一种爱好),我看到自己多次使用以下范例.(两者都在开发服务器架构和视频游戏开发工作.)它看起来真的很难看,但我不知道一个解决方案.我将在游戏开发中给出一个例子,因为它是我最近注意到它的地方.这是我一直在研究的角色扮演游戏.每次发动战斗时,CombatEngine都会创建两个战斗员派对.每个战斗者都设置一个与给定战斗者相关联的ArtificialIntelligence对象,该战斗员负责为没有接收到明确命令的玩家指挥移动:
public class Combatant {
ArtificialIntelligence ai = null;
public Combatant()
{
// Set other fields here.
this.ai = new ArtificialIntelligence(this);
}
}
Run Code Online (Sandbox Code Playgroud)
这就是我不喜欢的内容:内部场(ArtificialIntelligence)在施工期间使用一个作战者,因为它需要一些作战场以指示适当的动作.因此,为了方便起见,我保留了对作为一个arg传递给ArtificialIntelligence对象的战斗员的引用,但该对象包含对ai对象本身的引用!它创建了这种奇怪的递归,但我不知道如何解决它.AI对象需要大量特定于战斗员的字段,所以这就是我传入整个对象的原因,但我不喜欢该对象如何包含对上覆战斗员中包含的ai字段的引用字段,包含在上覆的ai类中.这是不好的做法,还是我只是在思考它?
虽然这里没有"设计"问题 - 它只是你传递的参考 - 一个重要的考虑因素是你应该在传递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";
}
Run Code Online (Sandbox Code Playgroud)
我肯定会避免循环依赖.来救援的单一责任原则.您可以通过让ArtificialIntelligence在Combatant上运行来消除对Combatant中的Artificialntelligence的引用的需要.将所有依赖于ArtificialIntelligence的Combatant代码移到ArtificialIntelligence上.CombatEngine将执行以下操作:
创建与Artificialntelligence无关的Independent Combatant实例.
创建适当的Artificalintelligence实例并将其传递给先前创建的Combatant.
或者,您可以创建一个名为CombatController的新类,该类传递一个Combatant和一个ArtificialIntelligence.CombatEngine将执行以下操作:
创建一个不依赖于任何其他类的Combatant
创建一个不依赖于任何其他类的人工智能
创建一个CombatController并将其传递给Combatant和ArtificialIntelligence对象以供使用.CombatController应该公开控制Combatant的方法以及处理AI行为.
无论您使用上述哪种方法,都可以消除困扰您的循环依赖性.
对不起,我无法提供代码示例,因为我从手机输入这个答案,格式化很痛苦.