考虑到下面这种情行:
一个动作冒险游戏:有不同的角色:弓箭手(Archer),战士(Warrior),有不同的武器:剑(Sword),匕首(Knife),弓(Bow)。。。
实现:每个角色能使用一种武器,并可以在游戏过程中换武器。
常规做法:超类Character,接口WeaponBehavior
例如 战士(Warrior)继承Character,实现WeaponBehavior获得使用剑(Sword)或者匕首(Knife)的行为。
弊端:1:需要重复写相同的代码。例如 新的角色 也使用 剑(Sword)时,又要实现一样的方法。
2:不能在运行时动态改变行为。即不能再游戏过程中换武器。耦合度太高。
策略模式:定义了算法族,分别封装起来,让他们之间可以互相替换。
第二种做法则是使用策略模式:
1:将变化封装起来。(这个场景变化就是使用不停的武器。
//定义使用武器的接口WeaponBehavior
public interface WeaponBehavior {
void useWeapon();
}
//定义使用不同武器的行为 SwordBehavior和KnifeBehavior
public class SwordBehavior implements WeaponBehavior{
@Override
public void useWeapon() {
System.out.println("use Sword");
}
}
public class KnifeBehavior implements WeaponBehavior{
@Override
public void useWeapon() {
System.out.println("use Knife");
}
}
2 定义角色类
//超类
public abstract class Character {
WeaponBehavior weaponBehavior;
public void setWeapon(WeaponBehavior weaponBehavior){
this.weaponBehavior = weaponBehavior;
}
abstract void fight();
}
//定义具体角色类
public class Knight extends Character{
private WeaponBehavior weaponBehavior;
public Knight() {
this.weaponBehavior = new SwordBehavior();
}
@Override
void fight() {
weaponBehavior.useWeapon();
}
public void setWeapon(WeaponBehavior weaponBehavior){
this.weaponBehavior = weaponBehavior;
}
}
这样设计的好处:当在设计其他角色时,只需要将要使用的武器组合上去即可,而不用写重复的代码,这也是面向接口编程,而不是针对实现编程。并且可以在运行时换武器,使用implements的方法则会将角色与武器耦合在一起而做不到这一点。
public static void main(String[] args) {
Character knight = new Knight();
knight.fight();
knight.setWeapon(new KnifeBehavior());
knight.fight();
}
输出:use Sword
use Knife