二十四种设计模式之策略模式

2023-11-20

一、什么是策略模式?
简单来说,策略模式是将每一个算法封装到拥有共同接口的不同类中,使得算法可以在不影响客户端的情况下发生变化。(也可以理解为可供程序运行时选择的(不同的类==不同的解决方案))。

策略模式的特点:高内聚低耦合,可扩展,遵循ocp原则(开放封闭原则)

二、策略模式实例
1、有名的三气周瑜,诸葛亮三个锦囊妙计,就让周大都督赔了夫人又折兵。

首先我们先写一个接口

package com.trf.pattern.strategy;

/**
 * @author 小小唐
 * @Date 2022/5/6-星期五-14:55
 * 首先定一个策略接口,这是诸葛亮给赵云的三个锦囊妙计的接口
 */
public interface IStrategy {

    //每个锦囊妙计都是一个可执行的算法
    public void operate();
}

然后我们再封装接口

package com.trf.pattern.strategy;

/**
 * @author 小小唐
 * @Date 2022/5/6-星期五-15:05
 *
 * 策略接口封装
 * 妙计需要放在 锦囊 中
 */
public class Context {
    //构造函数,你要使用那个妙计
    private IStrategy strategy;

    public Context(IStrategy strategy) {
        this.strategy = strategy;
    }

    //使用计谋
    public void operate(){
        this.strategy.operate();
    }
}

再写三个策略实现类

package com.trf.pattern.strategy;

/**
 * @author 小小唐
 * @Date 2022/5/6-星期五-14:57
 * 锦囊妙计的实现类:找乔国老帮忙,使孙权不能杀刘备
 */
public class BackDoor implements IStrategy{
    @Override
    public void operate() {
        System.out.println("乔国老帮忙,吴国太给孙权施压");
    }
}
package com.trf.pattern.strategy;

/**
 * @author 小小唐
 * @Date 2022/5/6-星期五-15:00
 * 锦囊妙计实现类:求吴国太开了绿灯放行
 */
public class GivenGreenLight implements IStrategy{

    @Override
    public void operate() {
        System.out.println("吴国太开发绿灯,放行");
    }
}

package com.trf.pattern.strategy;

/**
 * @author 小小唐
 * @Date 2022/5/6-星期五-15:03
 * 锦囊妙计实现类:孙夫人断后,挡住追兵
 */
public class BlockEnemy implements IStrategy{
    @Override
    public void operate() {
        System.out.println("孙夫人断后,挡住追兵");
    }
}


最后锦囊妙计的执行,需要由赵云来执行

package com.trf.pattern.strategy;

/**
 * @author 小小唐
 * @Date 2022/5/6-星期五-15:09
 *
 * 赵云出场,根据诸葛亮的交代,依次拆开妙计
 *
 * 策略模式:高内聚低耦合,可扩展,ocp原则
 * 策略类可以继续增加,只要修改 Context.java
 */
public class ZhaoYun {
    public static void main(String[] args) {
        Context context;

        //刚到吴国的时候拆开一个
        System.out.println("-----刚到吴国的时候拆开一个------");
        context = new Context(new BackDoor());//拿到妙计
        context.operate();//拆开执行
        System.out.println("\n\n\n\n\n");

        //刘备乐不思蜀,拆开第二个
        System.out.println("-----刘备乐不思蜀,拆开第二个-----");
        context = new Context(new GivenGreenLight());
        context.operate();//执行妙计
        System.out.println("\n\n\n\n\n");

        //孙夫人退兵
        System.out.println("-----孙夫人退兵----------------");
        context = new Context(new BlockEnemy());
        context.operate();//执行妙计
        System.out.println("\n\n\n\n\n");
    }
}

2、假设现在需要根据业务的需求,对调用接口传进来的参数,选择合适的策略进行处理,这里假设有策略一和策略二,并且我们加入Lambda表达式来简化策略实现类

同样的步骤,我们先写接口

package com.trf.pattern.strategy2;

/**
 * @author 小小唐
 * @Date 2022/5/6-星期五-22:28
 *
 * 策略接口
 */
public interface StrategyLambda {
    String execute(String s);
}

然后封装策略接口

package com.trf.pattern.strategy2;

/**
 * @author 小小唐
 * @Date 2022/5/6-星期五-22:30
 *
 * 策略接口封装
 */
public class StrategyLambdaObj {

    private final StrategyLambda strategyLambda;

    public StrategyLambdaObj(StrategyLambda strategyLambda) {
        this.strategyLambda = strategyLambda;
    }

    public String strategyLambda(String s){
        return strategyLambda.execute(s);
    }
}

因为我们使用Lambda表达式,所以我们可以不用写策略实现类,直接让客户来执行策略

package com.trf.pattern.strategy2;

/**
 * @author 小小唐
 * @Date 2022/5/6-星期五-22:34
 *
 * 客户:策略模式结合Lambda组合
 */
public class Client{
    public static void main(String[] args) {
        //选择策略一
        StrategyLambdaObj One = new StrategyLambdaObj((String s) -> {
            return "执行策略一";
        });
        System.out.println("客户选择的策略是:"+One.strategyLambda("one"));

        //选择策略二
        StrategyLambdaObj Two = new StrategyLambdaObj( s -> {
            return "执行策略二";
        });
        System.out.println("客户选择的策略是:"+Two.strategyLambda("two"));
    }
}

总结:
策略模式的优点:
1、使用策略模式可以避免使用多重条件if…else if…else语句, 多重条件不易维护且代码可读性差。
2、策略模式提供了管理相关的算法族的办法, 策略类的等级结构定义了一个算法或者行为族.,恰当使用继承可以把公共的代码移到父类里面, 从而避免代码重复。

策略模式的缺点:
1、客户端必须知道所有的策略类, 并自行决定使用哪一个策略类, 这就意味着客户端必须理解这些算法的区别, 以便适时选择恰当的算法类。 换言之, 策略模式只适用于客户端知道算法或行为的情况。
2、由于策略模式把每个具体的策略实现都单独封装成类, 如果备选的策略很多的话, 那么对象的数目就会很多。

好了,这只是我对策略模式一点点浅薄的理解,如有不对,欢迎与我联系探讨qq:2083323290。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

二十四种设计模式之策略模式 的相关文章

  • 如何在 Spring Data 中选择不同的结果

    我在使用简单的 Spring Data 查询或 Query 或 QueryDSL 在 Spring Data 中构建查询时遇到问题 如何选择三列 研究 国家 登录 不同的行 并且查询结果将是用户对象类型的列表 Table User Id S
  • 在 mvn 命令中指定 pom.xml 并混合其他项目的目标

    我有多个问题 我可以在 mvn 命令中指定 pom xml 吗 在当前项目上执行 mvn 命令时 我可以混合另一个项目的目标吗 例如 mvn clean otherproject comple otherproject install ot
  • 从 java sdk 向对等方发送提案时出现访问被拒绝错误

    我正在尝试使用以下代码查询区块链并收到访问被拒绝错误 我也遇到同样的错误sendTransactionProposal方法也是如此 UserContext adminUserContext RegisterEnrollUser regist
  • Spring Security 自定义过滤器

    我想自定义 Spring security 3 0 5 并将登录 URL 更改为 login 而不是 j spring security check 我需要做的是允许登录 目录并保护 admin report html 页面 首先 我使用教
  • 使用 GWT 读取非常大的本地 XML 文件

    我正在使用 GWT 构建我的第一个 Java 应用程序 它必须从一个非常大的 XML 文件中读取数据 当我尝试发送对文件中信息的请求时遇到问题 并且我不太确定它是否与文件的大小或我的语义有关 在我的程序中 我有以下内容 static fin
  • 是否有任何简单(且最新)的 Java 框架可用于在 Swing 应用程序中嵌入电影?

    我正在构建一个小型 Swing 应用程序 我想在其中嵌入一部电影 重要的是 这个应用程序是一个 WebStart 应用程序 并且该库应该能够打包在我启动的 jnlp 中 即 不依赖于本机库 我知道并尝试过 JMF 但我认为与其他框架相比 其
  • 如何在 Antlr4 中为零参数函数编写语法

    我的函数具有参数语法 如下面的词法分析器和解析器 MyFunctionsLexer g4 lexer grammar MyFunctionsLexer FUNCTION FUNCTION NAME A Za z0 9 DOT COMMA L
  • 打印星号的 ASCII 菱形

    我的程序打印出这样的钻石 但只有当参数或菱形的每一面为4 例如如果我输入6 底部三角形的间距是错误的 我一直在试图找出答案 当参数改变时 底部的三角形不会改变 只有顶部的三角形会改变 它只适用于输入4 public static void
  • Spring RestTemplate 使用 cookie 遵循重定向

    最近我遇到了一个问题 我需要做一个GET请求远程服务 我假设使用一个简单的 servlet 并且 RestTemplate 返回Too many redirects 经过一番调查 似乎对指定远程服务发出的第一个请求实际上只是一个 302 重
  • Integer.parseInt("0x1F60A") 以 NumberformatException 结束

    我尝试从数据库中获取长字符串内的表情符号代码 格式如下 0x1F60A 所以我可以访问代码 但它将是String 起初 我尝试通过执行以下操作来转换变量tv setText beforeEmo getEmijoByUnicode int e
  • 如何在代理后面安装 Eclipse Neon

    对于 Neon Eclipse 附带了一个安装程序 我在安装程序中找不到任何配置菜单 我的java版本是 java version java version 1 8 0 72 Java TM SE Runtime Environment b
  • Spring Security SAML2 使用 G Suite 作为 Idp

    我正在尝试使用 Spring Security 5 3 3 RELEASE 来处理 Spring Boot 应用程序中的 SAML2 身份验证 Spring Boot 应用程序将成为 SP G Suite 将成为 IDP 在我的 Maven
  • 是否可以通过编程方式查找 logback 日志文件?

    自动附加日志文件以支持电子邮件会很有用 我可以以编程方式设置路径 如以编程方式设置 Logback Appender 路径 https stackoverflow com questions 3803184 setting logback
  • Java Swing For mac 中的 DJ Native Swing 浏览器

    我有一个用 Swing 制作的 Java 应用程序 并且使用了一个 DJ Native Swing 浏览器 当我尝试在 OS X 上使用它时 它抛出了一个NoClassDefFoundError尽管我添加了 swt jar 但始终如此 有人
  • 在另一个模块中使用自定义 gradle 插件模块

    我正在开发一个自定义插件 我希望能够在稍后阶段将其部署到存储库 因此我为其创建了一个独立的模块 在对其进行任何正式的 TDD 之前 我想手动进行某些探索性测试 因此 我创建了一个使用给定插件的演示模块 到目前为止 我发现执行此操作的唯一方法
  • 了解joda时间PeriodFormatter

    我以为我明白了 但显然我不明白 你能帮我通过这些单元测试吗 Test public void second assertEquals 00 00 01 OurDateTimeFormatter format 1000 Test public
  • 在 SWT/JFace RCP 应用程序中填充巨大的表

    您将如何在 SWT 表中显示大量行 巨大是指超过 20K 行 20 列的东西 不要问我为什么需要展示那么多数据 这不是重点 关键是如何让它尽可能快地工作 这样最终用户就不会厌倦等待 每行显示某个对象的实例 列是其属性 一些 我想使用 JFa
  • QuerySyntaxException:无法找到类

    我正在使用 hql 生成 JunctionManagementListDto 类的实际 Java 对象 但我最终在控制台上出现以下异常 org hibernate hql internal ast QuerySyntaxException
  • 返回 Java 8 中的通用函数接口

    我想写一种函数工厂 它应该是一个函数 以不同的策略作为参数调用一次 它应该返回一个函数 该函数根据参数选择其中一种策略 该参数将由谓词实现 嗯 最好看看condition3为了更好的理解 问题是 它没有编译 我认为因为编译器无法弄清楚函数式
  • Spring表单ModelAttribute字段验证避免400 Bad Request错误

    我有一个ArticleFormModel包含正常发送的数据html form由 Spring 使用注入 ModelAttribute注释 即 RequestMapping value edit method RequestMethod PO

随机推荐

  • LabVIEW扫描成像或同步模拟电压生成和数据采集

    大量测量技术涉及探头扫描 同时测量物理量 例如 所有扫描成像方法都是这种情况 因此 数据采集需要高采集率 以及探头控制和测量之间的精确同步 GPScan VI 程序是用于控制 National Instruments 高速数据采集板的通用
  • 类型System.Double的对象无法转换为类型System.Single

    float gt System Single 单精度浮点型 占 4 个字节 double gt System Double 双精度浮点型 占 8 个字节 http msdn microsoft com zh cn library Syste
  • Linux命令(查看目录和切换目录)

    1 查看目录命令 ls 用法 ls 选项 目录名 案例 查看 usr下的所有文件 ls a usr 选项 a显示所有文件包含隐藏文件 l显示长文件信息 2 切换目录命令 cd change directory 用法 cd 目录名 案例 从当
  • npm,cnpm,yarn,pnmp之间的区别

    一 npm 1 由于版本号的影响 所以会造成版本不统一的情况 给定一个版本号 主版本号 次版本号 补丁版本号 以下这三种情况需要增加相应的版本号 主版本号 当API发生改变 并与之前的版本不兼容的时候 次版本号 当增加了功能 但是向后兼容的
  • Flask框架实战

    参考 第 2 章 Hello Flask Flask 入门教程 helloflask com 实战项目为一个基于flask框架实现的观影清单 个人实操后git地址 GitHub 2504973175 watchlist 基于flask框架的
  • Spark 配置

    文章目录 1 Spark 配置 1 1 Spark 属性 1 1 1 动态加载Spark属性 1 1 2 查看Spark属性 1 2 环境变量 2 重新指定配置文件目录 3 继承Hadoop集群配置 4 定制的Hadoop Hive配置 1
  • 动态白盒测试——基本路径测试法

    基本路径测试法 定义 基本路劲测试法是在程序控制流图的基础上 通过分析控制结构的环路复杂性 导出基本可执行路径集合 从而设计测试用例的方法 设计出的测试用例要保证被测程序的每个可执行语句至少被执行一次 点击学习控制流图 步骤 以详细设计或源
  • node.js连接数数据库及对数据库进行操作

    为了安装速度快一些 可以使用淘宝定制的 cnpm gzip 压缩支持 命令行工具代替默认的 npm 之后就可以使用 cnpm 命令来安装模块了 一 安装mysql驱动 cnpm install mysql 二 在工程下新建一个叫connec
  • 软件的可复用性

    1 什么是软件复用 软件复用就是利用已有的软件组件来实现或更新新的软件系统 2 软件复用的两个层面 for reuse 创造层面 开发可复用的软件 with reuse 使用层面 利用已有的可复用软件搭建新的软件应用系统 3 软件复用的优缺
  • 最简版Seq2Seq的英法机器翻译实践和详细代码解释

    Seq2Seq的英法机器翻译实践 本文的内容主要是基于英法平行语料库来实现一个简单的英法翻译模型 没有使用注意力机制和双向LSTM等技术 主要是为了掌握基本的Seq2Seq结构和TensorFlow函数使用 使用TensorFlow 1 1
  • 微信小程序预留ios安全区

    position fixed left 0 bottom 0 width 100 border top 1rpx solid ddd box shadow 0 1px 5px 0 eee background color fff z ind
  • Java使用jxl实现导出多sheet页Excel表格功能

    这篇文章主要介绍了使用jxl简化poi代码 实现导出Excel多sheet页功能 对大家的学习或者工作具有一定的参考学习价值 需要的朋友们下面随着小编来一起学习学习吧 以下代码就是一个小demo 大家可以直接自己创建maven项目然后跟着步
  • Linux Ubuntu 修改 /etc/apt/sources.list (镜像源)文件(非常实用)

    修改 etc apt sources list 文件 也即修改镜像源 能够加快在 Ubuntu 中下载和更新相关软件数据 否则默认情况下使用的是外网 下载起来比较慢 基本步骤 1 复制一份 etc apt sources list 文件 以
  • 时间序列特征构造:以电力负荷预测为例讲解(python语言)

    个人电气博文目录传送门 学好电气全靠它 个人电气博文目录 持续更新中 时间序列特征构造 时间序列问题 首先不管是回归问题 还是分类问题 一个模型的好坏 决定因素由数据集的大小 特征值的选取和处理 算法 其中最重要的是特征值的选取和处理 今天
  • 深入C++的拷贝构造和赋值函数 (深拷贝,浅拷贝)

    参考了 点击打开链接以及 高质量程序设计指南C C语言 说明 拷贝构造函数是一种特殊的构造函数 相同类型的类对象是通过拷贝构造函数来完成整个复制过程的 函数的名称必须和类名称一致 它的参数是唯一的 该参数是const类型的引用变量 例如 类
  • 尚硅谷微信小程序开发 仿网易云音乐App 小程序 后端接口服务器搭建

    目录 小程序学习 视频相关的教程文档与笔记分享 配套服务器 源码地址 接口使用说明文档 接口列表 启动服务 测试服务启动OK网页 http localhost 3000 test html 编辑 Postman测试服务器接口 postman
  • UDP协议与TCP协议的区别

    一 UDP的概述 User Datagram Protocol 用户数据报协议 UDP是传输层的协议 功能即为在IP的数据报服务之上增加了最基本的服务 复用和分用以及差错检测 二 UDP协议与TCP协议的区别 TCP连接时需要三次握手 有时
  • SparkSQL 操作数据库以及代码实践

    作者 禅与计算机程序设计艺术 1 简介 一 关于本文 SparkSQL是Apache Spark项目中用于处理结构化数据的开源模块 它提供了简单易用的API 能够将关系型数据库中的数据转换成DataFrame对象 方便进行各种分析查询 在实
  • 忘记阿里云远程连接密码怎么办

    此密码是连接终端控制台的密码 1 随便输入一个密码 点击确定 2 密码错误后网页右侧顶端出现1个修改远程连接密码的按钮 点击进去修改密码就OK了 QQ交流群 162136059
  • 二十四种设计模式之策略模式

    一 什么是策略模式 简单来说 策略模式是将每一个算法封装到拥有共同接口的不同类中 使得算法可以在不影响客户端的情况下发生变化 也可以理解为可供程序运行时选择的 不同的类 不同的解决方案 策略模式的特点 高内聚低耦合 可扩展 遵循ocp原则