设计模式之策略模式---Strategy Pattern

模式的介绍

模式的定义

策略模式(Strategy Pattern)是一种比较简单的模式,定义如下:
Define a family of algorithms, encapsulate each one, and make them interchangeable.

定义一组算法,将每一组算法都封装起来,并且使它们之间可以互换。

模式的使用场景

  • 多个类只有在算法或行为上稍有不同
  • 算法需要自由切换
  • 需要屏蔽算法规则

UML类图

这里写图片描述

角色介绍

  • Context:用来操作策略的上下文环境
  • Strategy : 策略的抽象。
  • ConcreteStrategyA、ConcreteStrategyB : 具体的策略实现。

模式的简单实现

简单实现的介绍:

本来想自己做一个策略模式的样例,但是,还是还是要承认别人的这个样例更好,还是用别人的样例吧。

通常如果一个问题有多个解决方案或者稍有区别的操作时,最简单的方式就是利用if-else or switch-case方式来解决,对于简单的解决方案这样做无疑是比较简单、方便、快捷的,但是如果解决方案中包括大量的处理逻辑需要封装,或者处理方式变动较大的时候则就显得混乱、复杂,而策略模式则很好的解决了这样的问题,它将各种方案分离开来,让操作者根据具体的需求来动态的选择不同的策略方案。

这里以简单的计算操作(+、-、*、/)作为示例:

使用简单的if else

public static double calc(String op, double paramA, double paramB) {
        if ("+".equals(op)) {
            System.out.println("执行加法...");
            return paramA + paramB;
        } else if ("-".equals(op)) {
            System.out.println("执行减法...");
            return paramA - paramB;
        } else if ("*".equals(op)) {
            System.out.println("执行乘法...");
            return paramA * paramB;
        } else if ("/".equals(op)) {
            System.out.println("执行除法...");
            if (paramB == 0) {
                throw new IllegalArgumentException("除数不能为0!");
            }
            return paramA / paramB;
        } else {
            throw new IllegalArgumentException("未找到计算方法!");
        }
}

使用策略模式

UML类图
这里写图片描述

详细代码:

public interface Strategy {
    public double calc(double paramA, double paramB);
}

加法的策略类

public class AddStrategy implements Strategy{

    @Override
    public double calc(double paramA, double paramB) {
        // TODO Auto-generated method stub
        System.out.println("执行加法策略...:"+(paramA + paramB));
        return paramA + paramB;
    }
}

减法的策略类

public class SubStrategy implements Strategy{

    @Override
    public double calc(double paramA, double paramB) {
        // TODO Auto-generated method stub
        System.out.println("执行减法策略...:"+(paramA - paramB));
        return paramA - paramB;
    }

}

乘法的策略类

public class MultiStrategy implements Strategy{

    @Override
    public double calc(double paramA, double paramB) {
        // TODO Auto-generated method stub
        System.out.println("执行乘法策略...:"+( paramA * paramB));
        return paramA * paramB;
    }

}

除法的策略类

public class DivStrategy implements Strategy {

    @Override
    public double calc(double paramA, double paramB) {
        // TODO Auto-generated method stub

        if(paramB == 0){
            throw new IllegalArgumentException("除数不能为0!");
        }
        System.out.println("执行除法策略...:"+(paramA / paramB));
        return paramA / paramB;
    }
}

Context类 Calc:

public class Calc {
    private Strategy strategy = null;

    public Strategy getStrategy() {
        return strategy;
    }

    public void setStrategy(Strategy strategy) {
        this.strategy = strategy;
    }

    public double calc(double paramA, double paramB) {
        // TODO Auto-generated method stub
        if (this.strategy == null) {
            throw new IllegalStateException("你还没有设置计算的策略");
        }
        return this.strategy.calc(paramA, paramB);
    }
}

main方法:

public class MainFunction {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        double paramA = 5;
        double paramB = 21;

        System.out.println("------------- 普通形式 ----------------");
        System.out.println("加法结果是:" + calc("+", paramA, paramB));
        System.out.println("减法结果是:" + calc("-", paramA, paramB));
        System.out.println("乘法结果是:" + calc("*", paramA, paramB));
        System.out.println("除法结果是:" + calc("/", paramA, paramB));

        System.out.println("------------ 策略模式  ----------------");
        Calc calc = new Calc();
        calc.setStrategy(new AddStrategy());
        calc.calc(paramA, paramB);

        calc.setStrategy(new SubStrategy());
        calc.calc(paramA, paramB);    

        calc.setStrategy(new MultiStrategy());
        calc.calc(paramA, paramB);  

        calc.setStrategy(new DivStrategy());
        calc.calc(paramA, paramB);  
    }

    public static double calc(String op, double paramA, double paramB) {
        if ("+".equals(op)) {
            System.out.println("执行加法...");
            return paramA + paramB;
        } else if ("-".equals(op)) {
            System.out.println("执行减法...");
            return paramA - paramB;
        } else if ("*".equals(op)) {
            System.out.println("执行乘法...");
            return paramA * paramB;
        } else if ("/".equals(op)) {
            System.out.println("执行除法...");
            if (paramB == 0) {
                throw new IllegalArgumentException("除数不能为0!");
            }
            return paramA / paramB;
        } else {
            throw new IllegalArgumentException("未找到计算方法!");
        }
    }
}

程序输出:

------------- 普通形式 ----------------
执行加法...
加法结果是:26.0
执行减法...
减法结果是:-16.0
执行乘法...
乘法结果是:105.0
执行除法...
除法结果是:0.23809523809523808
------------ 策略模式  ----------------
执行加法策略...:26.0
执行减法策略...:-16.0
执行乘法策略...:105.0
执行除法策略...:0.23809523809523808

模式的优缺点

优点

  • 算法可以自由的切换
  • 避免使用多重条件判断
  • 扩展性好

缺点

  • 策略类数量增多
  • 所有的策略类都需要对外暴露

Android源码中的模式实现

个人觉得策略模式应该在android中有许多应用,但是一时想不到什么特别好的例子,后补吧。

参考资料

(1).设计模式之禅—第18章 策略模式
(2)Android设计模式源码解析之策略模式
https://github.com/simple-android-framework/android_design_patterns_analysis/tree/master/strategy/gkerison

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hfreeman2008

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值