1、什么是策略模式?

Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.

策略模式(Strategy Pattern):定义一族算法类,将每个算法分别封装起来,让它们可以互相替换。

2、策略模式定义

①、Context封装角色

它也叫做上下文角色, 起承上启下封装作用, 屏蔽高层模块对策略、 算法的直接访问,封装可能存在的变化。

②、Strategy 抽象策略角色

策略、 算法家族的抽象, 通常为接口, 定义每个策略或算法必须具有的方法和属性。

③、ConcreteStrategy 具体策略角色

实现抽象策略中的操作, 该类含有具体的算法。

3、策略模式通用代码

public class Context {
// 抽象策略
private Strategy strategy = null;
// 构造函数设置具体策略
public Context(Strategy strategy) {
this.strategy = strategy;
}
// 封装后的策略方法
public void doAnything(){
this.strategy.doSomething();
}
}
public interface Strategy {
// 策略模式的运算法则
public void doSomething();
}
public class ConcreteStrategy1 implements Strategy{
@Override
public void doSomething() {
System.out.println("ConcreteStrategy1");
}
}
public class ConcreteStrategy2 implements Strategy{
@Override
public void doSomething() {
System.out.println("ConcreteStrategy2");
}
}

测试:

public class StrategyClient {
public static void main(String[] args) {
// 声明一个具体的策略
Strategy strategy = new ConcreteStrategy1();
// 声明上下文对象
Context context = new Context(strategy);
// 执行封装后的方法
context.doAnything();
}
}

4、用策略模式改写if-else

假设我们要处理一个office文件,分为三种类型 docx、xlsx、pptx,分别表示Word文件、Excel文件、PPT文件,根据文件后缀分别解析。

4.1 常规写法

public class OfficeHandler {

    public void handleFile(String filePath){
if(filePath == null){
return;
}
String fileExtension = getFileExtension(filePath);
if(("docx").equals(fileExtension)){
handlerDocx(filePath);
}else if(("xlsx").equals(fileExtension)){
handlerXlsx(filePath);
}else if(("pptx").equals(fileExtension)){
handlerPptx(filePath);
}
} public void handlerDocx(String filePath){
System.out.println("处理docx文件");
}
public void handlerXlsx(String filePath){
System.out.println("处理xlsx文件");
}
public void handlerPptx(String filePath){
System.out.println("处理pptx文件");
}
private static String getFileExtension(String filePath){
// 解析文件名获取文件扩展名,比如 文档.docx,返回 docx
String fileExtension = filePath.substring(filePath.lastIndexOf(".")+1);
return fileExtension;
}
}

处理逻辑全部放在一个类中,会导致整个类特别庞大,假设我们要新增一种类型处理,比如对于2007版之前的office文件,后缀分别是 doc/xls/ppt,那我们得增加 else if 逻辑,违反了开闭原则,如何解决这种问题呢,答案就是通过策略模式。

4.2 策略模式改写

public interface OfficeHandlerStrategy {
void handlerOffice(String filePath);
}
public class OfficeHandlerDocxStrategy implements OfficeHandlerStrategy {
@Override
public void handlerOffice(String filePath) {
System.out.println("处理docx");
}
}

// 省略 OfficeHandlerXlsxStrategy/OfficeHandlerPptxStrategy 类

public class OfficeHandlerStrategyFactory {
private static final Map<String,OfficeHandlerStrategy> map = new HashMap<>();
static {
map.put("docx",new OfficeHandlerDocxStrategy());
map.put("xlsx",new OfficeHandlerXlsxStrategy());
map.put("pptx",new OfficeHandlerPptxStrategy());
}
public static OfficeHandlerStrategy getStrategy(String type){
return map.get(type);
}
}

测试:

public class OfficeHandlerStrategyClient {
public static void main(String[] args) {
String filePath = "C://file/123.xlsx";
String type = getFileExtension(filePath);
OfficeHandlerStrategy strategy = OfficeHandlerStrategyFactory.getStrategy(type);
strategy.handlerOffice(filePath);
} private static String getFileExtension(String filePath){
// 解析文件名获取文件扩展名,比如 文档.docx,返回 docx
String fileExtension = filePath.substring(filePath.lastIndexOf(".")+1);
return fileExtension;
}
}

4、策略模式优点

①、算法可以自由切换

这是策略模式本身定义的, 只要实现抽象策略, 它就成为策略家族的一个成员, 通过封装角色对其进行封装, 保证对外提供“可自由切换”的策略。

②、避免使用多重条件判断

简化多重if-else,或多个switch-case分支。

③、扩展性良好

增加一个策略,只需要实现一个接口即可。

5、策略模式应用场景

①、多个类只有在算法或行为上稍有不同的场景。

②、算法需要自由切换的场景。

③、需要屏蔽算法规则的场景。

Java设计模式之(十四)——策略模式的更多相关文章

  1. Java设计模式(18)策略模式(Strategy模式)

    Strategy是属于设计模式中 对象行为型模式,主要是定义一系列的算法,把这些算法一个个封装成单独的类. Stratrgy应用比较广泛,比如,公司经营业务变化图,可能有两种实现方式,一个是线条曲线, ...

  2. Java设计模式菜鸟系列(一)策略模式建模与实现

    转载请注明出处:http://blog.csdn.net/lhy_ycu/article/details/39721563 今天開始咱们来谈谈Java设计模式. 这里会结合uml图形来解说,有对uml ...

  3. Java设计模式(七)策略模式 模板模式

    (十三)策略模式 策略图案限定了多个封装算法,该算法可以相互替换包.法的客户.借用还有一位大神的样例. interface ICalculator{ public int calculate(Stri ...

  4. C#设计模式之十九策略模式(Stragety Pattern)【行为型】

    一.引言 今天我们开始讲“行为型”设计模式的第七个模式,该模式是[策略模式],英文名称是:Stragety Pattern.在现实生活中,策略模式的例子也非常常见,例如,在一个公司中,会有各种工作人员 ...

  5. JAVA设计模式——第 1 章 策略模式【Strategy Pattern】(转)

    刘备要到江东娶老婆了,走之前诸葛亮给赵云(伴郎)三个锦囊妙计,说是按天机拆开解决棘手问题,嘿,还别说,真是解决了大问题,搞到最后是周瑜陪了夫人又折兵呀,那咱们先看看这个场景是什么样子的. 先说这个场景 ...

  6. JAVA设计模式——(2)策略模式

    定义 定义一种算法,将每个算法都封装起来,并且使它们之间可以互换.是一种行为类模式. 举例 为了通俗易懂,我们拿各国的税率计算来举例子: 假设当前我们的程序只能支持计算中国和美国的税率: public ...

  7. Java设计模式(一) 策略模式

    策略模式:定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户. 1,定义算法接口 package com.pattern.strategy.test; publ ...

  8. Java设计模式之十二 ---- 备忘录模式和状态模式

    前言 在上一篇中我们学习了行为型模式的策略模式(Strategy Pattern)和模板模式(Template Pattern).本篇则来学习下行为型模式的两个模式,备忘录模式(Memento Pat ...

  9. java设计模式(六)策略模式

    适用于同一操作的不同行为,策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们可以相互替换,让算法独立于使用它的客户而独立变化,具体应用场景如第三方支付对接不同银行的算法. 要点:1)抽象策 ...

  10. Java设计模式(十) 备忘录模式 状态模式

    (十九)备忘录模式 备忘录模式目的是保存一个对象的某个状态,在适当的时候恢复这个对象. class Memento{ private String value; public Memento(Stri ...

随机推荐

  1. 跟着老猫一起来学GO,环境搭建

    老猫的GO学习系列博客已经正式发车了,相信大家以前学习一门编程语言的时候也有经验,咱们一般都是从环境开始,在此呢,大家也跟着老猫从最开始的搭建环境开始. GO语言的安装 首先呢,我们开始需要下载GO语 ...

  2. Java编程开发学习路线图(附所有免费课程+在线自测)

    转自  https://yq.aliyun.com/articles/134286?spm=5176.100239.0.0.1UfveS 摘要: 长期以来,Java一直占据TIOBE编程语言排行版第一 ...

  3. 2021.8.24考试总结[NOIP47]

    T1 prime 发现只需筛小于等于$mid(\sqrt r,k)$的质数,之后用这些质数筛掉区间内不合法的数即可. $code:$ 1 #include<bits/stdc++.h> 2 ...

  4. Celery Task(定时任务)及参数

    celery beat 是一个调度器:它以常规的时间间隔开启任务,任务将会在集群中的可用节点上运行. 默认情况下,入口项是从 beat_schedule 设置中获取,但是自定义的存储也可以使用,例如在 ...

  5. VMware Workstation 16.2 Pro for Linux SLIC 2.6 & Unlocker

    请访问原文链接:https://sysin.org/blog/vmware-workstation-16-linux-slic/,查看最新版.原创作品,转载请保留出处. 作者:gc(at)sysin. ...

  6. Python pip 和pip3区别 联系

    python 有python2和python3的区别 那么pip也有pip和pip3的区别 大概是这样的 pip是python的包管理工具,pip和pip3版本不同,都位于Scripts\目录下: 如 ...

  7. F. Mattress Run 题解

    F. Mattress Run 挺好的一道题,对于DP的本质的理解有很大的帮助. 首先要想到的就是将这个拆成两个题,一个dp光求获得足够的夜晚的最小代价,一个dp光求获得足够的停留的最小代价. 显然由 ...

  8. Apache Solr应用服务器存在远程代码执行漏洞👻

    Apache Solr应用服务器存在远程代码执行漏洞 1.描述 Apache Solr是一个开源的搜索服务,使用Java语言开发,主要基于HTTP和Apache Lucene实现的. Solr是一个高 ...

  9. Abp Vnext Vue3 的版本实现

    基于ABP Vnext的二次开发,前端 vue3.0,Typescript,Ant Design Vue ,Vben Admin 的后台管理框架. 技术点 Net Core5.0 ABP Vnext ...

  10. ELK集群之kibana(4)

    kibane安装及基础使用 Kibana的安装 Kibana包含前端展示.es操作简化 yum localinstall kibana-7.6.2-x86_64.rpm -y Kibana配置修改ki ...