0

我问了一个关于使用策略模式和 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他们永远不会使用的方法。

4

1 回答 1

0

听起来武器抽象有点太笼统了。我会把它分解成更小的抽象

  1. 武器(抽象或界面 - 随你选)

    • 攻击
  2. GunBasedWeapon(扩展武器)(枪、步枪、激光枪、80 年代威震天)

    • 目标
    • 重新加载
    • 攻击(抛出 OutOfBulletException)
  3. 手持武器(扩展武器)(剑、棍棒、锁链等)

    • 攻击(在没有乳液的 100 次点击后抛出 CallousesOnHandHurtException)
    • 涂抹乳液
  4. ThrowableWeapon(扩展武器)(回旋镖)

    • 攻击(抛出 SomebodyElseCaughtMyBoomerangException,然后抛出 ImHosedException)
  5. WeaponAction - 每个武器类现在可以有一个有效动作列表,如果有人以某种方式将“applyLotion”传递给 GunBasedWeapon,只有 Gun 类会知道它是无效的。

于 2017-10-24T02:42:04.573 回答