在平常开发工做中,适当的使用一些设计模式,可让代码扩展性更强,能更好地拥抱变化,让代码更加优雅。本文主要介绍设计模式中的策略模式,并附上测试示例 Demo 供你们参考。算法
策略模式定义了一系列的算法,并将每个算法封装起来,并且使它们还能够相互替换。策略模式让算法独立于使用它的客户而独立变化。编程
策略模式,针对那些动做因对象而异的状况下,把每个动做都独立封装起来并实现同一个接口,经过组合的方式赋予对象相对应的动做,从而使得全部的动做均可以相互替换。经过策略模式,能够达到在运行时修改对象的具体动做、对象和具体动做之间解耦的效果。设计模式
1)找出应用中可能须要变化的地方,把它们独立出来,不要和那些不须要变化的代码混在一块儿;ide
2)面向接口编程,而不是面向实现编程;测试
3)多用组合,少用继承;this
这里我以 CF 里面的背包为例子来描述策略模式(有可能 CF 背包的设计不是我讲的这样,这里只是举例说明策略模式)。玩过 CF 的同窗都知道,每一个角色都有本身的背包,背包里面能够放主武器、副武器、投掷类武器等。而这几类武器,又包含多种具体型号的武器,好比:主武器能够是狙击步枪、冲锋枪,副武器能够是普通手枪、左轮手枪,投掷类武器能够是手雷、烟雾弹、闪光弹等。为了可以达到可以随时调整背包装备的效果,能够采用策略模式。UML 图以下:spa
从上面的 UML 能够看出,先定义一个主武器的接口类 IMainArms 和投掷类武器的接口类 IThrowArms,而后让狙击步枪类 SniperRifle 和 冲锋枪类 SubmachineGun 都去实现主武器接口,让手雷类 AntitankGrenade 、闪光弹类 FlashBomb 和 烟雾弹类 SmokeBomb 都去实现投掷类武器接口,接着再在背包类 Pack 中经过 IMainArms 和 IThrowArms 两个接口声明一个主武器变量和一个投掷类武器的变量。至此,在配置背包时,就能够根据实际须要,往背包里面放不一样的主武器和不一样的投掷类武器,若是有新的主武器或者投掷类武器须要建立,则只须要在建立对应的类时,以相同的方式实现对应的接口后,便可像原有的武器使用方式使用新的武器。设计
IMainArms 主武器接口code
package strategy; public interface IMainArms { void fire(); void aim(); }
IThrowArms 投掷类武器接口对象
package strategy; public interface IThrowArms { void bomb(); }
SniperRifle 狙击步枪类
package strategy; public class SniperRifle implements IMainArms { private int bulletNum; @Override public void fire() { if(this.bulletNum>0){ System.out.println("狙击枪扣动扳机..."); this.bulletNum = this.bulletNum - 1; } } @Override public void aim() { System.out.println("狙击枪瞄准..."); } public int getBulletNum() { return bulletNum; } public void setBulletNum(int bulletNum) { this.bulletNum = bulletNum; } }
SubmachineGun 冲锋枪类
package strategy; public class SubmachineGun implements IMainArms { private int bulletNum; @Override public void fire() { if(this.bulletNum>0){ System.out.println("冲锋枪扣动扳机..."); this.bulletNum = this.bulletNum - 1; } } @Override public void aim() { System.out.println("冲锋枪瞄准..."); } public int getBulletNum() { return bulletNum; } public void setBulletNum(int bulletNum) { this.bulletNum = bulletNum; } }
AntitankGrenade 手雷类
package strategy; public class AntitankGrenade implements IThrowArms { private boolean isBomb; @Override public void bomb() { System.out.println("手雷爆炸..."); this.setBomb(true); } public boolean isBomb() { return isBomb; } public void setBomb(boolean isBomb) { this.isBomb = isBomb; } }
FlashBomb 闪光弹类
package strategy; public class FlashBomb implements IThrowArms { private boolean isBomb; @Override public void bomb() { System.out.println("闪光弹爆炸..."); this.setBomb(true); } public boolean isBomb() { return isBomb; } public void setBomb(boolean isBomb) { this.isBomb = isBomb; } }
SmokeBomb 烟雾弹类
package strategy; public class SmokeBomb implements IThrowArms { private boolean isBomb; @Override public void bomb() { System.out.println("烟雾弹爆炸..."); this.setBomb(true); } public boolean isBomb() { return isBomb; } public void setBomb(boolean isBomb) { this.isBomb = isBomb; } }
MainTest 测试类
package test; import strategy.AntitankGrenade; import strategy.FlashBomb; import strategy.Pack; import strategy.SniperRifle; import strategy.SubmachineGun; public class MainTest { public static void main(String[] args) { SniperRifle sniperRifle = new SniperRifle(); sniperRifle.setBulletNum(100); SubmachineGun submachineGun = new SubmachineGun(); submachineGun.setBulletNum(50); AntitankGrenade antitankGrenade = new AntitankGrenade(); antitankGrenade.setBomb(false); FlashBomb flashBomb = new FlashBomb(); flashBomb.setBomb(false); Pack pack1 = new Pack(); pack1.setMainArms(sniperRifle); pack1.setPackNo(1); pack1.setThrowArms(antitankGrenade); Pack pack2 = new Pack(); pack2.setMainArms(submachineGun); pack2.setPackNo(2); pack2.setThrowArms(flashBomb); pack1.getMainArms().aim(); pack1.getMainArms().fire(); pack1.getThrowArms().bomb(); pack2.getMainArms().aim(); pack2.getMainArms().fire(); pack2.getThrowArms().bomb(); } }