某游戏中Queen,King,Knight这3种角色,每种角色都有使用武器行为,设计这三个类,提高代码的重用性和可维护性。
Queen,King,Knight这三个角色都是角色,都可以move,可以stop,因此可以设计一个Character抽象类,抽取三个角色的共同行为,减少代码的重复性,Character定义如下:
public abstract class Character {
public void move() { // do move action }
public void stop() { // do stop action }
public void useWeapon() { // do use sword}
}
三个角色继承于Character这个抽象类, 但是如果Queen用的武器是枪呢? 可以在子类重写该方法啊!
public class Queen() extends Character {
@Override
public void useWeapon() {
// do use gun
}
}
public class King() extends Character { ... }
public class Knight() extends Character { ... }
但是还有一个问题,如果我新增了其他角色,当然继承于Character,如果新增的这个类没有使用武器的行为呢?
还有另外一种解决方法,将容易改变的行为抽象成一个接口。
public abstract class Character {
public void move() { // do move action }
public void stop() { // do stop action }
}
public interface WeaponBehavior {
void useWeapon();
}
public class King extends Character implements WeaponBehavior {
public void useWeapon() { // do use sword }
}
public class Queen extends Character implements WeaponBehavior {
public void useWeapon() { // do use sword }
}
public class Knight implements WeaponBehavior extends Character {
public void useWeapon() { // do use gun }
}
上面接口的方式看上去挺合理的,但是角色一多就会发现在useWeapon方法中会出现大量的代码重复,虽然可以将重复代码抽取出来放到其他地方,但是这样就破坏了类的封装性。
考虑到不同对象使用不同的武器,而且使用武器方法会不断改变,最好将经常改变的东西封装起来,以后一旦有需要修改的,则只需要修改封装部分就可以,而其他模块不会受到影响。策略模式的核心思想就是把变化的行为(算法)封装,让他们可以相互替换,这个模式可以让变化的算法独立于使用这些行为(算法)的客户。具体看下面的实现:
public interface WeaponBehavior {
void useWeapon();
}
public class SwordBehavior implements WeaponBehavior {
@Override
public void useWeapon() { // do sword behavior }
}
public class GunBehavior implements WeaponBehavior {
@Override
public void useWeapon() { // do gun behavior }
}
public abstract class Character {
WeaponBehavior weaponBehavior;
public void move() { // do move action }
public void stop() { // do stop action }
public void useWeapon() {
weaponBehavior.useWeapon();
}
public setWeaponBehavior(WeaponBehavior weaponBehavior) {
this.weaponBehavior = weaponBehavior;
}
}
public class King extends Character {
public King() {
weaponBehavior = new GunBehavior();
}
}
public class Queen extends Character {
public Queen() {
weaponBehavior = new SwordBehavior();
}
}
如上代码所示,将经常需要改变的行为封装成类,有如下好处:
策略模式适用于有多类似对象,这些对象又有类似行为,并且行为会不断发生变化这样的场景。策略模式将算法封装起来,让算法之间可以相互替换,并且这种替换对使用算法的客户来说是独立的。
策略模式体现了软件设计的原则:
原文:http://blog.csdn.net/jackie_zhu/article/details/46404599