我问了一个关于使用策略模式和 LSP 的问题,但答案参差不齐,从长远来看,这不是一个好主意。然而,我的问题底部的评论指出,虽然我没有违反 LSP,但我违反了接口隔离原则,该原则指出:
客户端不应该被迫实现他们不使用的接口。代替一个胖接口,许多基于方法组的小接口是首选的,每个接口服务一个子模块。
假设我有一个这样的武器类:
public final Weapon{
private final String name;
private final int damage;
private final List<AttackStrategy> validactions;
private final List<Actions> standardActions;
public Weapon(String name, int damage, List<AttackStrategy> standardActions, List<Actions> attacks)
{
this.name = name;
this.damage = damage;
standardActions = new ArrayList<Actions>(standardActions);
validAttacks = new ArrayList<AttackStrategy>(validActions);
}
public void standardAction(String action){} // -- Can call reload or aim here.
public int attack(String action){} // - Call any actions that are attacks.
}
接口与实现:
public interface AttackStrategy{
void attack(Enemy enemy);
}
public class Shoot implements AttackStrategy {
public void attack(Enemy enemy){
//code to shoot
}
}
public class Strike implements AttackStrategy {
public void attack(Enemy enemy){
//code to strike
}
}
利用:
List<AttackStrategy> actions = new ArrayList<AttackStrategy();
actions.add(new Shoot())
List<Actions> standardActionactions = new ArrayList<Actions>();
actions.add(new Reload(10))
Weapon rifle = new Weapon("Sniper Rifle", 5, standardActionactions, actions);
List<AttackStrategy> actions = new ArrayList<AttackStrategy();
actions.add(new Swing())
List<Actions> standardActionactions = new ArrayList<Actions>();
actions.add(new Drop())
Weapon sword = new Weapon("Standard Sword", 10, standardActionactions, actions);
我有两种武器,它们的行为都不同,虽然都可以用来攻击,但每种武器都有不同的动作。例如,Sword不应该并且根据我的收藏逻辑,无论如何都不能调用或实现重新加载。
在我的文字冒险游戏中,如果您将“reload”传递给sword.standardAction("reload")
,内部逻辑将检查 List 是否包含 reload 对象,如果有,则执行,如果没有,则武器不可用,因此不能,所以它忽略它。
我是否违反了 ISP?
我的剑永远不会实现reload
,除非客户决定实现它,否则我不会强迫客户接受 aSword
知道Reload
他们永远不会使用的方法。