方法实现

时间:2016-06-08 05:51:16

标签: java design-patterns

我是java的新手,需要帮助以更复杂的方式设置方法的实现 - 我写过这个,但被告知我需要使用其中一个GoF模式来美化它。关于我需要做什么的一些帮助将是最合适的

protected void setWeapon() {
        if (this.getClass().getSimpleName().equals("FighterJet")) {
            this.weapon = new GuidedMissileSystem();
            System.out.println("FighterJet " + id + " equipped with " + weapon.getClass().getSimpleName());
        } else if (this.getClass().getSimpleName().equals("AttackHelicopter")) {
            this.weapon = new GrenadeLauncher();
            System.out.println("AttackHelicopter " + id + " equipped with " + weapon.getClass().getSimpleName());
        } else if (this.getClass().getSimpleName().equals("Tank")) {
            this.weapon = new Cannon();
            System.out.println("Tank " + id + " equipped with " + weapon.getClass().getSimpleName());
        } else if (this.getClass().getSimpleName().equals("InfantryMobilityVehicle")) {
            this.weapon = new MachineGun();
            System.out.println("InfantryMobilityVehicle " + id + " equipped with " + weapon.getClass().getSimpleName());
        } else if (this.getClass().getSimpleName().equals("Warship")) {
            this.weapon = new RocketLauncher();
            System.out.println("Warship " + id + " equipped with " + weapon.getClass().getSimpleName());
        } else if (this.getClass().getSimpleName().equals("Submarine")) {
            this.weapon = new TorpedoTube();
            System.out.println("Submarine " + id + " equipped with " + weapon.getClass().getSimpleName());
        }
    }

2 个答案:

答案 0 :(得分:1)

由于这似乎是基于实例具体的子类,因此您只需在构造函数中设置一个字段。

例如:

class ParentClass {
  final Weapon weapon;

  ParentClass(Weapon weapon) {
    this.weapon = weapon;
  }
}

然后,在Warship班:

class Warship extends ParentClass {
  Warship() {
    super(new RocketLauncher());
  }
}

(为清晰起见,省略了可见性修饰符和其他字段)

请注意,dependency injection不是GoF模式,我不认为。这只是在这里使用的最干净的。

答案 1 :(得分:1)

@ AndyTurner的答案可以通过下图说明:

Solution Diagram

虽然这个解决方案有效,但我不同意它遵循依赖性倒置原则,因为具体类负责创建Weapon个对象。此外,我相信它违反了开放封闭原则。想象一下,你的Weapon在战斗中坠毁了。你不能只为另一个替换它。

我想提出另一种解决方案,它在结构上相似,但在功能上有所不同:

Solution 2 Diagram

interface WarVehicle {
    boolean atack(WarVehicle other);
    boolean defend(WarVehicle from);
    void setWeapon(WarVehicle from);
    Weapon getWeapon();
    boolean acceptsWeapon();
}

abstract class AbstractWarVehicle {
    private Weapon weapon;
    public AbstractWarVehicle(Weapon weapon) {
        setWeapon(weapon);
    }

    public final void setWeapon(Weapon weapon) {
        if (!acceptsWeapon(weapon)) {
            throw new IllegalArgumentException("Weapon of type " 
                + weapon.getClass().getName() 
                + " cannot be added to WarVehicle of type " 
                + this.getClass().getName());
        }
        this.weapon = weapon;
    }

    public final Weapon getWeapon() {
        return this.weapon;
    }

    public boolean attack(WarVehicle other) {
        if (other != this) {
           return !other.defend(this);
        }
    }

    public boolean defend(WarVehicle from) {
        return this.getWeapon().getDefensePower() >= 
               from.getWeapon().getFirePower();
    }
}

class FighterJet extends AbstractWarVehicle {
    public boolean acceptsWeapon(Weapon weapon) {
        return weapon instanceof GuidedMissilesystem;
    }
}

class AttackHelicopter extends AbstractWarVehicle {
    public boolean acceptsWeapon(Weapon weapon) {
        return weapon instanceof GrenadeLauncher;
    }
}

// And so on...

使用它:

Weapon jet = new FighterJet(new GuidedMissleSystem()); // OK
Weapon jet2 = new FighterJet(new Cannon()); // throws!

这种方法的优点:

  • 这是DIP实施。
  • 可以使用Weapon替换setWeapon与类似的Weapon
  • 它尊重(在某种程度上)OCP,因为它可以子类化/组成FighterJetGuidedMissileSystem将接受SuperUltraMegaBlasterGeorgeForemanMissileSystem的任何实例,这意味着如果您的游戏已展开并获得GuidedMissileSystem,则如果它继承自{{}},您仍然可以使用它{1}}。

这种方法的缺点:

  • acceptsWeapon中的规则是静态的,因此无法在运行时更改。