策略模式——Strategy

案例展示——Strategy怎么用?

 了解一点历史的人都知道商鞅变法,正是由于商鞅变法,奠定了秦国强大的根基,使秦国从一个最弱小的战国迅速成为一个超强战国,奋六世之余烈,终于在秦始皇手上一统天下。可以说,没有商鞅变法,就没有强大的秦国,或许也可以断言,天下将不会由秦朝统一。那么商鞅变法为什么会有这么大的规律呢,现在我们从软件的设计的角度来看看商鞅变法的威力,下面是类图设计:

image

分析上面的类图:

  • IStrategy:抽象策略类,定义一个执行法律的方法

  • AwardBattle:法律一,鼓励打仗

  • AbolishSlave:法律二,废除奴隶制度

  • DefeatNobility:法律三,推翻贵族的垄断地位,取消封地

  • SYUpdateLaw:商鞅变法,执行法律

 看看上面的每一个法律,是不是都透露着变法家的博大情怀。每一个法律就是一个策略,每一次策略的实施都会使秦国发生脱胎换骨的变化。鼓励耕战,使国人争相入军报效国家,国家实力迅速提升;废除奴隶制度,使奴隶得到解放,人人拥护国家,为国效力;最重要的是推翻世族统治,封地收归国有,权利高度集中。正是由于秦国贯彻实施了商鞅变法,才造就了后来的辉煌蓝图。

下面是具体的代码实现:

// 抽象策略类
public interface IStrategy {
    // 每天政策都需要切实执行
    public void operate();
}

// 法律一:鼓励耕战
public class AwardBattle implements IStrategy {
    public void operate() {
        System.out.println("奖励有功战士!");
    }
}

// 法律二:废除奴隶制
public class AbolishSlave implements IStrategy {
    public void operate() {
        System.out.println("废除奴隶制度,举国之人皆是国民!");
    }
}

// 法律三:推翻贵族统治
public class DefeatNobility implements IStrategy {
    public void operate() {
        System.out.println("推翻世族,人人平等!");
    }
}

// 商鞅变法
public class SYUpdataLaw {
    // 构造函数中传入要实施的律法
    private IStrategy strategy;
    public SYUpdataLaw(IStrategy strategy) {
        this.strategy = strategy;
    }
    // 实施法律
    public void operate() {
        this.strategy.operate();
    }
}

// 开始变法
public class Client {
    public static void main(String[] args) {
        // 准备好法律,依次颁布实施
        SYUpdataLaw ul;
        System.out.println("==========前三年:鼓励打仗========");
        ul = new SYUpdataLaw(new AwardBattle());
        // 执行法律
        ul.operate();

        System.out.println("==========中三年:废除奴隶制=======");
        ul = new SYUpdataLaw(new AbolishSlave());
        // 执行法律
        ul.operate();

        System.out.println("==========时机成熟:推翻世族=======");
        ul = new SYUpdataLaw(new DefeatNobility());
        // 执行法律
        ul.operate();
    }
}

// 结果如下:
==========前三年:鼓励打仗========
奖励有功战士!
==========中三年:废除奴隶制=======
废除奴隶制度,举国之人皆是国民!
==========时机成熟:推翻世族=======
推翻世族,人人平等!

 上面的例子中就使用到了策略模式,每一个法律就是一个策略,策略用好了,国家就强大了。

深入分析——Strategy是什么?
Strategy的定义

定义: 定义一组算法,将每个算法都封装起来,并且使它们可以相互交换。通用类图设计如下:

image

  • Context组建:上下文角色,起承上启下的作用,屏蔽高层模块、算法的直接
    直接访问,封装可能存在的变化

  • Strategy组建:抽象策略角色,通常是接口,定义每个策略或算法所必须具有的方法和属性

  • ConcreateStrategy组建:具体的策略,实现了Strategy接口

下面是通用代码实现:

// 策略接口
public interface Strategy {
    // 执行策略
    public void doSomething();
}

// 策略1
public class ConcreateStrategy1 implements Strategy {
    public void doSomething() {
        System.out.println("执行策略1");
    }
}

// 策略2
public class ConcreateStrategy2 implements Strategy {
    public void doSomething() {
        System.out.println("执行策略2");
    }
}

// 妙计锦囊
public class Context {
    // 抽象策略
    private Strategy strategy = null;
    // 在构造函数中设置具体策略
    public Context(Strategy strategy) {
        this.strategy = strategy;
    }
    // 执行策略方法
    public void doAnything() {
        this.strategy.doSomething();
    }
}

// 实施策略
public class Client {
    public static void main(String[] args) {
        // 声明一个具体的策略
        Strategy strategy = new ConcreateStrategy1();
        // 造一个锦囊
        Context context = new Context(strategy);
        // 执行策略
        context.doAnything();
    }
}
Strategy的优点
  • 算法可以自由切换

  • 避免多重条件判断

  • 扩展性良好,新增一个算法只要实现接口就行了

Strategy的缺点
  • 策略类数量增多会增加系统的复杂性

  • 所有的策略类都需要向外暴露,不利于和高层模块的解耦

策略模式的扩展——策略枚举

直接看代码:

// 枚举的计算类
public enum Calculator {
    // 加法运算
    ADD("+") {
        public int exec(int a, int b) {
            return a + b;
        }
    },
    // 减法运算
    SUB("-") {
        public int exec(int a, int b) {
            return a - b;
        }
    };

    String value = "";

    // 定义成员值类型
    private Calculator(String value) {
        this.value = value;
    }

    // 获得枚举成员的值
    public String getValue() {
        return this.value;
    }

    // 声明一个抽象函数
    public abstract int exec(int a, int b);
}

// 计算
public class Client {
    public static void main(String[] args) {
        // 两个参数
        int a = 10, b = 20;
        System.out.println("运算结果为:" + Calculator.ADD.exec(a, b));
        System.out.println("运算结果为:" + Calculator.SUB.exec(a, b));
    }
}

 程序是什么意思一眼就能看出来,现在来说说什么是枚举策略,下面简单定义一下:

  • 是一个枚举类
  • 浓缩了策略模式的枚举,换句话说,每一个枚举算法就是策略
参考

《设计模式之禅》

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值