1 基础知识

定义:定义了算法家族,分别封装起来,让他们可以相互替换,此模式让算法的变化不会影响到使用算法的用户(应用层)。特征:可以替换掉大量的if else语句

本质:分离算法,选择实现。

使用场景:

(1)出现有许多相关的类,仅仅是行为有差别的情况下,可以使用策略模式来使用多

个行为中的一个来配置一个类的方法,实现算法动态切换。

(2)出现同一个算法,有很多不同实现的情况下,可以使用策略模式来把这些“不同的实现”实现成为一个算法的类层次。

(3)需要封装算法中,有与算法相关数据的情况下,可以使用策略模式来避免暴露这些跟算法相关的数据结构

(4)出现抽象一个定义了很多行为的类,并且是通过多个 it-else语句来选择这些行为的情况下,可以使用策略模式来代替这些条件语句。

优点:符合开闭原则;避免使用多重条件转移语句;提高算法的保密性和安全性。 缺点:客户端必须知道所有的策略类,并自行决定使用哪一个策略类;产生多个策略类。

2 代码示例

使用场景:假设慕课网的视频课程在不同的时间段会有不同的打折活动。那么可以认为这些不同的打折活动便是不同的策略。

打折策略接口:PromotionStrategy

  1. public interface PromotionStrategy {
  2. void doPromotion();
  3. }

满减策略:ManJianPromotionStrategy

  1. public class ManJianPromotionStrategy implements PromotionStrategy{
  2.  
  3. public void doPromotion() {
  4. System.out.println("满减促销,满200-20元");
  5. }
  6. }

立减策略:LiJianPromotionStrategy

  1. public class LiJianPromotionStrategy implements PromotionStrategy {
  2.  
  3. public void doPromotion() {
  4. System.out.println("立减促销,课程的价格直接减去配置的价格");
  5. }
  6. }

返现策略:FanXianPromotionStrategy

  1. public class FanXianPromotionStrategy implements PromotionStrategy{
  2.  
  3. public void doPromotion() {
  4. System.out.println("返现促销,返回的金额存放到慕课网用户的余额中");
  5. }
  6. }

打折活动:PromotionActivity

  1. public class PromotionActivity {
  2. private PromotionStrategy promotionStrategy;
  3. //构造器注入
  4. public PromotionActivity(PromotionStrategy promotionStrategy) {
  5. this.promotionStrategy = promotionStrategy;
  6. }
  7.  
  8. public void executePromotionStrategy(){
  9. promotionStrategy.doPromotion();
  10. }
  11. }

应用层:Test

  1. public class Test {
  2. public static void main(String[] args) {
  3. PromotionActivity promotionActivity618 = new PromotionActivity(new LiJianPromotionStrategy());
  4. PromotionActivity promotionActivity1111 = new PromotionActivity(new FanXianPromotionStrategy());
  5.  
  6. //不同阶段采用不同的策略
  7. promotionActivity618.executePromotionStrategy();
  8. promotionActivity1111.executePromotionStrategy();
  9. }
  10. }

在上面应用层时预先定义好了,但如果没有预先定义好,那么可能就会有如下的情况:

  1. public static void main(String[] args) {
  2. PromotionActivity promotionActivity = null;
  3.  
  4. String promotionKey = "LIJIAN";
  5.  
  6. if ("LIJIAN".equals(promotionKey)){
  7. System.out.println(123);
  8. promotionActivity = new PromotionActivity(new LiJianPromotionStrategy());
  9. }else if ("MANJAN".equals(promotionKey)){
  10. System.out.println("其他策略");
  11. }
  12. //...其他策略
  13.  
  14. promotionActivity.executePromotionStrategy();
  15. }

通过不断的进行if else 判断来调整不同的策略,但这种情况肯定不是我们想要的。因此可以采用工厂模式来消除if else

策略工厂:PromotionStrategyFactory

  1. public class PromotionStrategyFactory {
  2.  
  3. //定义一个map集合来保存不同策略
  4. private static Map<String,PromotionStrategy> Promotion_Strategy_Map = new HashMap<String, PromotionStrategy>();
  5. static {
  6. Promotion_Strategy_Map.put(PromotionKey.LIJIAN,new LiJianPromotionStrategy());
  7. Promotion_Strategy_Map.put(PromotionKey.MANJIAN,new ManJianPromotionStrategy());
  8. Promotion_Strategy_Map.put(PromotionKey.FANXIAN,new FanXianPromotionStrategy());
  9. }
  10.  
  11. //构造器私有
  12. private PromotionStrategyFactory(){
  13.  
  14. }
  15. //定义一个无促销的策略
  16. private static PromotionStrategy NON_PROMOTION = new EmptyPromotionStrategy();
  17.  
  18. public static PromotionStrategy getPromotionStrateg(String promotionKey){
  19. PromotionStrategy promotionStrategy = Promotion_Strategy_Map.get(promotionKey);
  20. //当为空时直接返回无促销策略
  21. return promotionStrategy == null ? NON_PROMOTION : promotionStrategy;
  22. }
  23.  
  24. //在声明常量的时候起到了一个分组的作用,默认即为final的不可更改
  25. private interface PromotionKey{
  26. String LIJIAN = "LIJIAN";
  27. String FANXIAN = "FANXIAN";
  28. String MANJIAN = "MANJIAN";
  29. }
  30. }

无促销类:EmptyPromotionStrategy  这个类只是为了对应为空时的情况

  1. public class EmptyPromotionStrategy implements PromotionStrategy{
  2.  
  3. public void doPromotion() {
  4. System.out.println("无促销");
  5. }
  6. }

应用层:Test

  1. public static void main(String[] args) {
  2. //外界传过来的
  3. String promotionKey = "LIJIAN";
  4. //采用工厂进行实例化
  5. PromotionActivity promotionActivity = new PromotionActivity(PromotionStrategyFactory.getPromotionStrateg(promotionKey));
  6.  
  7. promotionActivity.executePromotionStrategy();
  8. }

3

4 相关模式

(1)策略模式和状态模式

这两个模式从模式结构上看是一样的,但是实现的功能却是不一样的。状态模式是根据状态的变化来选择相应的行为,不同的状态对应不同的类,每个状态对应的类实现了该状态对应的功能,在实现功能的同时,还会维护状态数据的变化。这些实现状态对应的功能的类之间是不能相互替换的。策略模式是根据需要或者是客户端的要求来选择相应的实现类,各个实现类是平等的,是可以相互替换的。另外策略模式可以让客户端来选择需要使用的策略算法:而状态模式一般是由上下文,或者是在状态实现类里面来维护具体的状态数据,通常不由客户端来指定状态。

(2)策略模式和模板方法模式

这两个模式可组合使用,如同前面示例的那样。模板方法重在封装算法骨架;而策略模式重在分离并封装算法实现。

(3)策略模式和享元模式

    这两个模式可组合使用。策略模式分离并封装出一系列的策略算法对象,这些对象的功能通常都比较单一,很多时候就是为了实现某个算法的功能而存在。因此,针对这一系列的、多个细粒度的对象,可以应用享元模式来节省资源,但前提是这些算法对象要被频繁地使用,如果偶尔用一次,就没有必要做成享元了。

0

策略模式(Strategy)---行为型的更多相关文章

  1. 【转】设计模式 ( 十八 ) 策略模式Strategy(对象行为型)

    设计模式 ( 十八 ) 策略模式Strategy(对象行为型) 1.概述 在软件开发中也常常遇到类似的情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成 ...

  2. 设计模式 ( 十八 ) 策略模式Strategy(对象行为型)

    设计模式 ( 十八 ) 策略模式Strategy(对象行为型) 1.概述 在软件开发中也经常遇到类似的情况,实现某一个功能有多种算法或者策略,我们能够依据环境或者条件的不同选择不同的算法或者策略来完毕 ...

  3. 策略模式 Strategy 政策Policy 行为型 设计模式(二十五)

    策略模式 Strategy   与策略相关的常见词汇有:营销策略.折扣策略.教学策略.记忆策略.学习策略.... “策略”意味着分情况讨论,而不是一概而论 面对不同年龄段的人,面对不同的商品,必然将会 ...

  4. [.net 面向对象程序设计深入](26)实战设计模式——策略模式 Strategy (行为型)

    [.net 面向对象程序设计深入](26)实战设计模式——策略模式 Strategy (行为型) 1,策略模式定义 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模 ...

  5. 设计模式22:Strategy 策略模式(行为型模式)

    Strategy 策略模式(行为型模式) 动机(Motivation) 在软件构建过程中,某些对象使用的算法可能多种多样,经常改变,如果将这些算法都编码到对象中,将会使对象变得异常复杂:而且有时候支持 ...

  6. [.net 面向对象程序设计深入](24)实战设计模式——策略模式(行为型)

    [.net 面向对象程序设计深入](24)实战设计模式——策略模式(行为型) 1,策略模式定义 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它 ...

  7. 设计模式 笔记 策略模式 Strategy

    //---------------------------15/04/28---------------------------- //Strategy 策略模式----对象行为型模式 /* 1:意图 ...

  8. JAVA设计模式之策略模式 - Strategy

    在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改.这种类型的设计模式属于行为型模式. 在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 ...

  9. 设计模式(一):“穿越火线”中的“策略模式”(Strategy Pattern)

    在前段时间呢陆陆续续的更新了一系列关于重构的文章.在重构我们既有的代码时,往往会用到设计模式.在之前重构系列的博客中,我们在重构时用到了“工厂模式”.“策略模式”.“状态模式”等.当然在重构时,有的地 ...

  10. 设计模式 - 策略模式(Strategy Pattern) 具体解释

    策略模式(Strategy Pattern) 具体解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26577879 本文版权全 ...

随机推荐

  1. Pandas 读取超过 65536 行的 Excel 文件

    Excel 文件的格式曾经发生过一次变化,在 Excel 2007 以前,使用扩展名为 .xls 格式的文件,这种文件格式是一种特定的二进制格式,最多支持 65,536 行,256 列表格.从 Exc ...

  2. springboot+JPA 整合redis

    1.导入redis依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifact ...

  3. 第5章:Linux系统管理

    1.文件读写 1).Python内置的open函数 f = open('data.txt', 'w') f.write('hello, world') f.close() 2).避免文件句柄泄露 tr ...

  4. 【数据结构】P1996 约瑟夫问题

    [题目链接] https://www.luogu.org/problem/P1996 题目描述 n个人(n<=100)围成一圈,从第一个人开始报数,数到m的人出列,再由下一个人重新从1开始报数, ...

  5. k8s认证及serviceAccount、userAccount

    1.概述 用kubectl向apiserver发起的命令,采用的是http方式,K8s支持多版本并存. kubectl的认证信息存储在~/.kube/config,所以用curl无法直接获取apis中 ...

  6. Codeforces 1247D. Power Products

    传送门 要满足存在 $x$ ,使得 $a_i \cdot a_j = x^k$ 那么充分必要条件就是 $a_i \cdot a_j$ 质因数分解后每个质因数的次幂都要为 $k$ 的倍数 证明显然 设 ...

  7. Nopcommerce 使用Task时dbcontext关闭问题

    1.开启一个线程 Task.Run(() => { CreatPrintImage(preViewModel.DiyProductGuid); }); 2.线程代码 /// <summar ...

  8. regex 正则分割字符串

    string _content=adak.sjdkajskj爱25教:师的656教案时; string en=@"\.|56|25";//单个[asj]分别以a,s,j为分隔符. ...

  9. JSON在JS中的应用

    一. JSON在JS中的应用: 首先解释下JSON对象与普通js对象字面量定义时格式的区别: Js对象字面量定义格式: var person = { name:"Wede", ag ...

  10. 1 简介mvp模式

    1   模型-视图-表示器也称为监视控制器模式 ,如下图表示 2 mvp 模式希望通过表示器(presenter)来关联网页,而不必在他们之间建立严格的 3 一个简单的mvp架构的例子 public ...