不久前我正在研究一个问题,责任和他们应该去哪里的话题出现了。在我的相关问题中,大学是拥有所有规则并确保每个注册学生都有所需文件的机构和班级。
这让我想起了埃里克·利珀特(Eric Lippert)的一篇博客文章:巫师与勇士。
上面写着:
我们一直在谈论"规则",所以显然业务 该程序的域包括称为"规则"的东西,以及那些 规则与业务域中的所有其他对象进行交互。所以 那么"统治"应该是一个类吗?我不明白为什么不!这是什么 程序从根本上讲是关于的。似乎可能会有 成百上千条这样的规则,它们可能会改变 时间,因此将它们编码为类似乎是合理的。
规则:
战士只能使用剑。
向导只能使用工作人员。
我的问题是,我将如何在GameRules
class
中确定要传递的特定对象以验证我是否可以携带它?
public final class GameRules {
public static boolean verifyifwizardcancarry(Weapon weapon){
boolean canCarry = false
if weapon is a a staff set canCarry to true
return canCarry;
}
}
public abstract class Player{
private List<Weapon> weapons;
// constructor and OOP goodness left out
public abstract void add(Weapon weapon);
}
public final class Wizard extends Player{
@Override
public void add(Weapon weapon){
if(GameRules.verifyifwizardcancarry(weapon){
// - code to add weapon to inventory
}
}
}
如何验证传递给GameRules
class
的Weapon
是否确实是Sword
?从阅读来看,使用instanceof
或getClass()
被认为是代码异味。
我找到了这个答案,但它违反了 LSP 并且违背了博客所说的,它不应该抛出异常,也没有真正回答我的问题。
根据这个Java动态绑定和方法覆盖
创建这样的函数将在添加剑时调用,而不是武器的任何其他子项
public void add(Sword sword){
//nope
}
如果只能装备一种(或几种)武器,但随后 Overriden 函数会给出否定响应,也可以这样做。
我认为您在这种情况下无法避免使用instanceof
运算符。我的建议是,你让每个具体的Player
自己负责确定它可以携带哪些武器。因此,删除GameRules.verifyifwizardcancarry
并将此逻辑分散到玩家之间,以便Wizard
instanceof
检查其武器,其他玩家也这样做。