内容简介:以前完整的看过《大话设计模式》,虽然完整看过,也做过笔记,但现在依然很多已经很模糊。这段时间趁着离职,有时间,打算重新过一遍,定义(维基百科):策略模式作爲一種軟件設計模式,指對象有某個行爲,但是在不同的場景中,該行爲有不同的實現算法。比如每個人都要“交個人所得稅”,但是“在美國交個人所得稅”和“在中國交個人所得稅”就有不同的算稅方法。策略模式,从模式名称中我们就可以窥探一二。无非就是一个动作可以有不同的策略,有不同的计算方法,我们将计算方法进行封装。如上的例子,美国税务计算、中国的税务计算采用了不同的计算
以前完整的看过《大话设计模式》,虽然完整看过,也做过笔记,但现在依然很多已经很模糊。这段时间趁着离职,有时间,打算重新过一遍, 该篇将介绍策略模式。
一、定义
定义(维基百科):策略模式作爲一種軟件設計模式,指對象有某個行爲,但是在不同的場景中,該行爲有不同的實現算法。比如每個人都要“交個人所得稅”,但是“在美國交個人所得稅”和“在中國交個人所得稅”就有不同的算稅方法。
策略模式,从模式名称中我们就可以窥探一二。无非就是一个动作可以有不同的策略,有不同的计算方法,我们将计算方法进行封装。如上的例子,美国税务计算、中国的税务计算采用了不同的计算方式(不同策略)。还有一个《大话设计模式》中的例子也很好的说明该设置模式,商场折扣,上次可能是满减,这次可能是直接打折,这就是两种不同的策略,那么我们在代码里该怎样设计,才会更清晰抽象这个问题呢?接下来我们就来看看策略模式是怎么抽象该类型的问题的。
二、策略模式UML图
我们看看策略模式是有怎样设计结构的。图片来源于维基百科。可以看到,策略模式定义了一个策略的接口Stragegy,该接口定义了一个方法,即为该策略的操作方法。再实现不同的策略类ConcreteStrategyA、ConcreteStrategyB,继承自策略接口。接着在上下文类Context类持有策略的引用,调用策略。
三、以商场打折为例子,我们来实现先策略模式。
1、先定义策略接口
package com.design.strategy; /** * 商场打折接口 */ public interface IShopDiscountStrategy { public int discount(int count); }复制代码
2、再定义具体的策略
package com.design.strategy; /** * 满减计算策略 */ public class DiscountFull implements IShopDiscountStrategy { //满的金额 private int fullCount; //减的金额 private int disCash; public DiscountFull(int fullCount,int disCash){ this.fullCount = fullCount; this.disCash = disCash; } @Override public int discount(int count) { if (count >= fullCount){ return count -disCash; } return count; } }复制代码
package com.design.strategy; /** * 打折策略,打7折 */ public class DiscountPercent implements IShopDiscountStrategy { //折扣率 private float disPer; public DiscountPercent(float disPer){ this.disPer = disPer; } @Override public int discount(int count) { return (int) (count * disPer); } }复制代码
3、再定义上下文类,持有具体的策略引用。
package com.design.strategy; public class DiscountContext { private IShopDiscountStrategy iShopDiscountStrategy; public DiscountContext(IShopDiscountStrategy iShopDiscountStrategy) { this.iShopDiscountStrategy = iShopDiscountStrategy; } public int discount(int count){ return iShopDiscountStrategy.discount(count); } }复制代码
到此,策略模式编写的打折场景已经编写完毕,在来看看怎么调用
package com.design.strategy;public class StrategyTestMain { public static void main(String[] args) { //使用满减策略计算实收总额 DiscountContext discountContext = new DiscountContext(new DiscountFull(200, 100)); System.out.println(discountContext.discount(200)); //使用折扣策略计算实收总额 DiscountContext discountContext1 = new DiscountContext(new DiscountPercent(0.7f)); System.out.println(discountContext1.discount(200)); } }复制代码
四、优缺点
优点
1、简化单元测试
从例子我们就可以看出来每个策略都有单独的类来实现,我们可以当度对策略进行测试。
2、扩展性好
我们要定义新的策略,只需要编写一个新的策略,并对新策略进行测试即可,不修改原来已经存在策略的代码。
3、避免使用多重条件转移语句
策略模式中使用的策略是有客户端选择的,策略相关的类不需要通过多重条件去选择策略。
缺点
1、客户端需自行决定使用的策略
客户端必须知道所有的策略类,并自行决定使用哪一个策略类。
2、定义的类比较多
每个策略都得定义一个类来实现。
结语
策略模式暂时总结到这里。看起来策略模式还是比较简单的,就是将不同的策略进行封装。实际适用于一个操作有不同的策略的应用场景中。如JDK中创建线程池,线程池任务满时,对提交的任务做处理就使用了策略模式。可以在创建线程池时,传入相应的处理策略。如下,最后一个参数传入一个处理策略。策略接口为RejectedExecutionHandler,具体的实现有:DiscardOldestPolicy,AbortPolicy....
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize, long keepAliveTime,TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler)复制代码
以上所述就是小编给大家介绍的《设计模式之策略模式》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 设计模式——订阅模式(观察者模式)
- 设计模式-简单工厂、工厂方法模式、抽象工厂模式
- java23种设计模式-门面模式(外观模式)
- 设计模式-享元设计模式
- Java 设计模式之工厂方法模式与抽象工厂模式
- JAVA设计模式之模板方法模式和建造者模式
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Redis 深度历险:核心原理与应用实践
钱文品 / 电子工业出版社 / 2019-1 / 79
Redis 是互联网技术架构在存储系统中使用得最为广泛的中间件,也是中高级后端工程师技术面试中面试官最喜欢问的工程技能之一,特别是那些优秀的互联网公司,通常要求面试者不仅仅掌握 Redis 基础用法,还要理解 Redis 内部实现的细节原理。《Redis 深度历险:核心原理与应用实践》作者老钱在使用 Redis 上积累了丰富的实战经验,希望帮助更多后端开发者更快、更深入地掌握 Redis 技能。 ......一起来看看 《Redis 深度历险:核心原理与应用实践》 这本书的介绍吧!