定义

策略模式(Strategy),是一种对象行为模式:定义一系列的算法,将可变的部分封装起来,使得它们可以相互替换,让变化的部分于独立调用它的客户而变化,不会导致调用方需要跟着修改。 (这边的"算法"指的是系统中经常会变的部分,可能是超类定义的行为,或者特征之类的)

主要组成

抽象策略接口(Strategy): 定义同一组算法的公共接口;

具体策略实现(Concrete Strategy): 实现具体的某种算法;

客户端(Client): 调用者,一般会有策略列表存放各种策略,根据需要选择不同的策略实现功能;

UML图

框架代码

Strategy:

public interface Strategy {void AlgorithmInterface();
}
复制代码

Concrete Strategy:

public class ConcreteStrategyA {@Overridepublic void AlgorithmInterface(){//策略A的行为   }
}public class ConcreteStrategyB {@Overridepublic void AlgorithmInterface(){//策略B的行为   }
}
复制代码

Client:

Strategy strategy = new ConcreteStrategyA();
//Strategy strategy = new ConcreteStrategyB();
//执行处不管理策略具体实现细节
strategy.AlgorithmInterface();
复制代码

具体例子

UML图

代码

Vehicle(Strategy策略模块):

/*** 交通工具**/
public interface Vehicle {//使用指定交通工具出发,不关心该工具的操作细节String go();
}
复制代码

Car:

public class Car implements Vehicle{@Overridepublic String go() {return "开小汽车前往目的地";  }}
复制代码

Bilk:

public class Bilk implements Vehicle{@Overridepublic String go() {return "骑自行车前往目的地";}
}
复制代码

Plane:

public class Plane implements Vehicle{@Overridepublic String go() {return "乘坐飞机前往目的地";}
}
复制代码

PayMent(Strategy策略模块):

/*** 支付方式**/
public interface PayMent {//不关心支付方式的操作流程,只关心付款结果String cost();
}
复制代码

AliPay:

public class AliPay implements PayMent{@Overridepublic String cost() {return "使用支付宝流程付款";}
}
复制代码

WeChat:

public class WeChat implements PayMent{@Overridepublic String cost() {return "使用微信流程付款";  }
}
复制代码

Crash:

public class Crash implements PayMent{@Overridepublic String cost() {return "使用现金流程付款";}
}
复制代码

稳定部分TravelPlan(使用各种策略的地方): TravelPlan:

public abstract class TravelPlan {//可变的策略模块Vehicle vehicle;PayMent payMent;//公共稳定的操作接口public void setVehicle(Vehicle vehicle) {this.vehicle = vehicle;}public void setPayMent(PayMent payMent) {this.payMent = payMent;}public void go() {System.out.println((getGoTime() + payMent.cost() + vehicle.go() + getDestination()));}public abstract String getDestination();public abstract String getGoTime();
}
复制代码

BeijingTravelPlan:

public class BeijingTravelPlan extends TravelPlan{@Overridepublic String getDestination() {return "北京";}@Overridepublic String getGoTime() {return "2018.11.12.09:00";}
}
复制代码

TaiWanTravelPlan:

public class TaiWanTravelPlan extends TravelPlan{@Overridepublic String getDestination() {return "台湾";}@Overridepublic String getGoTime() {return "2018.11.13.10:00";}
}
复制代码

简单使用:

//定义北京旅游计划TravelPlan travelPlan = new BeijingTravelPlan();travelPlan.setPayMent(new WeChat());travelPlan.setVehicle(new Car());travelPlan.go();//告白出行交通工具和付款方式travelPlan.setPayMent(new Crash());travelPlan.setVehicle(new Bilk());travelPlan.go();日志输出:2018.11.12.09:00使用微信流程付款开小汽车前往目的地北京2018.11.12.09:00使用现金流程付款骑自行车前往目的地北京
复制代码

假设不使用策略模式

未将可变部分独立出来,即不存在Vehicle和PayMent这2个算法模块,则对于TravePlane继承体系可能为:

public abstract class TravelPlan {String vehicleType;String payMentType;public void setVehicle(String vehicle) {this.vehicleType = vehicle;}public void setPayMent(String payMent) {this.payMentType = payMent;}public void go() {System.out.println((getGoTime() + payMentCost() + vehicleGo() + getDestination()));}//存在一大堆条件判断public String vehicleGo () {switch (vehicleType) {case "Car":return "开小汽车前往目的地";   case "Bilk":return "骑自行车前往目的地"; case "Plane":return "乘坐飞机前往目的地";    default:return null;}}//存在一大堆条件判断public String payMentCost () {switch (vehicleType) {case "AliPay":return "使用支付宝流程付款";  case "WeChat":return "使用微信流程付款";    case "Crash":return "使用现金流程付款"; default:return null;}}public abstract String getDestination();public abstract String getGoTime();}
复制代码

经常会因为业务而发生修改扩展的部分都堆在了相对稳定的部分,没有面向接口通过组合的方式,后续修改vehicle和PayMent部分可能会不经意点影响到了其它功能点。

总结

优点

1.策略模式封装了可变部分,使得"可变"部分独立于"稳定"部分,在经常性的增加修改"可变"部分过程不需要动到"稳定"部分,可用于取代将全部行为封装到超类然后由每个子类都实现一遍的纯继承方式;

2.当算法种类多的时候,避免了一系列的条件判断,代码更简洁;

3.不同算法实现同一接口,可以互相替换,不需要硬编码到调用处;

4.2者分离后可以去除在各个子类单独实现算法的重复部分;

缺点

  1. 比起将"可变"与"稳定"部分都放一起来讲,类数目会增加比较多(大部分设计模式都会这样)

应用场景

  1. 许多相同的类,但是仅仅是行为不一致,就可以使用策略模式,将不同的行为抽象接口,实现成各个行为算法类;
  2. 单个类中,存在许多行为,但是在某些调用的地方需要使用if来判断不同的行为,则可以将这些行为用策略模式优化;

微信公众号

小白设计模式:策略模式相关推荐

  1. Python设计模式-策略模式

    Python设计模式-策略模式 代码基于3.5.2,代码如下; #coding:utf-8 #策略模式class sendInterface():def send(self,value):raise ...

  2. 关于设计模式——策略模式-Strategy Pattern

    文章目录 1 策略模式 1.1 模拟鸭子 1.2 设计原则 1.3 整合行为 1.4 模拟鸭子代码的代码 1.5 动态设定行为 1.6 重新查看整体 1.7 继承和组合 1.8 总结 1.9 优劣期间 ...

  3. [设计模式] ------ 策略模式

    策略模式 它定义了算法家族,分别封装起来,让他们直接可以互相替换,此模式让算法的变化,不会影响到使用算法的客户 其实很简单,可能很多人都用到了,只不过还不知道这就是策略模式而已. 比如定义一个接口A, ...

  4. java 策略模式 促销_java设计模式——策略模式

    一. 定义与类型 定义:针对一组算法,将每一种算法都封装到具有共同接口的独立的类中,从而是它们可以相互替换.策略模式的最大特点是使得算法可以在不影响客户端的情况下发生变化,从而改变不同的功能.当代码中 ...

  5. Springboot 使用设计模式- 策略模式

    前言 直白点,什么场景我们需要使用到设计模式- 策略模式. 在平常的springboot项目里面做CRUD,我们的习惯性基本是 一个mapper,一个service,一个serviceImpl. 但是 ...

  6. 李建忠设计模式——策略模式Strategy

    目录 1.策略模式定义 1.动机 2.模式定义 3.结构 2.实现例子 1.问题描述 2.代码实现 3.要点总结 4.参考 1.策略模式定义 1.动机 软件构建过程中,某些对象使用的算法可能多种多样, ...

  7. 15. 星际争霸之php设计模式--策略模式

    题记 ============================================================================== 本php设计模式专辑来源于博客(jy ...

  8. Java设计模式-策略模式作业

    Java设计模式-策略模式作业,所有类和接口均在一个package内 文章目录 前言 一.作业内容 二.具体实现 1.类图 2.Strategy接口 3.PreCopyStrategy类 4.Post ...

  9. 设计模式-策略模式2.0

    设计模式-策略模式2.0 前面文章我们说过了传统的策略模式的实现,本文我们简单说下设计模式中的升级版的策略模式,策略模式2.0. 代码实现 talk is cheap show me the code ...

  10. 设计模式-策略模式(Strategy)-Java

    设计模式-策略模式(Strategy)-Java 目录 文章目录 1.前言 2.示例案例-电影票打折方案 3.策略模式概述 3.1.策略模式定义 3.2.策略模式结构 3.3.策略模式结构图中角色 3 ...

最新文章

  1. 库函数strlen源码重现及注意问题
  2. svn命令在linux下的使用
  3. Euro Truck Simulator 2欧洲卡车模拟2用VR玩
  4. makefile使用宏及用法$(宏标识符) $(cc)_宏编程的艺术
  5. 科大星云诗社动态20210216
  6. [Hadoop in China 2011] 中兴:NoSQL应用现状及电信业务实践
  7. [css] 用css怎么实现两端对齐?
  8. linux 查看path文件,linux入门之环境变量与文件查找
  9. 阿狸心形表白html,2013qq情侣分组心形一对 心心相印的地久天长
  10. 微信小程序开发学习笔记007--微信小程序项目01
  11. java面向对象笔试_Java面向对象笔试题.doc
  12. 如何去除chrome最常访问的网页
  13. 大数据分析平台如何进行支出跟踪
  14. Python3实现旋转数组的3种算法 1
  15. Intel 64 Memory ordering principles
  16. 三星5G商用关键设备开发完成;施耐德布局物联网│IoT黑板报
  17. win7如何显示文件后缀名 win7怎么显示文件后缀名?
  18. 线性代数(一)—— 行列式
  19. ⑦企业级zabbix监控 微信报警、邮箱报警、钉钉报警、全网最细
  20. 计算机函数sumif求平均值,EXCEL的经典函数sumif的用法和实例(详细汇总)_excel函数_office之家...

热门文章

  1. layui鼠标放上图片局部放大_老照片修复教程之—裁剪图片大小
  2. 根目录_ubuntu 18.04 server版根目录只有4G?
  3. 腐蚀rust高速箭怎么做不了_高速公路波形护栏板安装时的设置要求
  4. python可视化的图表汉字显示成框框_Matplotlib图表上输出中文(汉字)、减号问题...
  5. mysql5.7建库建表_MySQL5.7 建库建表的命令
  6. STM8单片机低功耗---停机(Halt)模式实现
  7. C语言学习笔记---时间函数ctime()和gmtime()
  8. Android学习笔记(九)——Activity的跳转和数据传递
  9. 目标识别:如何从人脸图片中扣出眼图,实时人脸人眼检测和识别
  10. thttpd服务器修改时间后导致CPU占用率过高