首页 > 代码库 > 策略模式 -- 设计模式系列文章(一)

策略模式 -- 设计模式系列文章(一)

  • 概述

  在日常开发工作中,适当的使用一些设计模式,可以让代码扩展性更强,能更好地拥抱变化,让代码更加优雅。本文主要介绍设计模式中的策略模式,并附上测试示例 Demo 供大家参考。

  • 定义

  策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。

  • 个人理解

  策略模式,针对那些动作因对象而异的情况下,把每一个动作都独立封装起来并实现同一个接口,通过组合的方式赋予对象相对应的动作,从而使得所有的动作都可以相互替换。通过策略模式,可以达到在运行时修改对象的具体动作、对象和具体动作之间解耦的效果。

  • 设计原则

  1)找出应用中可能需要变化的地方,把它们独立出来,不要和那些不需要变化的代码混在一起;

  2)面向接口编程,而不是面向实现编程;

  3)多用组合,少用继承;

  • 示例介绍

  这里我以 CF 里面的背包为例子来描述策略模式(有可能 CF 背包的设计不是我讲的这样,这里只是举例说明策略模式)。玩过 CF 的同学都知道,每个角色都有自己的背包,背包里面可以放主武器、副武器、投掷类武器等。而这几类武器,又包含多种具体型号的武器,比如:主武器可以是狙击步枪、冲锋枪,副武器可以是普通手枪、左轮手枪,投掷类武器可以是手雷、烟雾弹、闪光弹等。为了能够达到能够随时调整背包装备的效果,可以采用策略模式。UML 图如下:

技术分享

 

  从上面的 UML 可以看出,先定义一个主武器的接口类 IMainArms 和投掷类武器的接口类 IThrowArms,然后让狙击步枪类 SniperRifle 和 冲锋枪类 SubmachineGun 都去实现主武器接口,让手雷类 AntitankGrenade 、闪光弹类 FlashBomb 和 烟雾弹类 SmokeBomb 都去实现投掷类武器接口,接着再在背包类 Pack 中通过 IMainArms 和 IThrowArms 两个接口声明一个主武器变量和一个投掷类武器的变量。至此,在配置背包时,就可以根据实际需要,往背包里面放不同的主武器和不同的投掷类武器,如果有新的主武器或者投掷类武器需要创建,则只需要在创建对应的类时,以相同的方式实现对应的接口后,即可像原有的武器使用方式使用新的武器。

  •  示例代码

   IMainArms 主武器接口

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();    }}

 

 

  欢迎转载,转载必须标明出处 

 

策略模式 -- 设计模式系列文章(一)