当前位置: 首页 > news >正文

十六、策略模式

一、什么是策略模式

  策略(Strategy)模式的定义:该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。

  策略模式的主要角色如下:

  • 抽象策略(Strategy)类:定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。
  • 具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现。
  • 环境(Context)类:持有一个策略类的引用,最终给客户端调用。

二、策略模式的实现

  策略模式是准备一组算法,并将这组算法封装到一系列的策略类里面,作为一个抽象策略类的子类。策略模式的重心不是如何实现算法,而是如何组织这些算法,从而让程序结构更加灵活,具有更好的维护性和扩展性。

1. 抽象策略(Strategy)

/*** @author FluffyCatkin* @version 1.0* @date 2020/1/6 0006 17:50* @description 抽象策略(Strategy)类:定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。*/
public interface Strategy {void strategyMethod();
}

2. 具体策略(Concrete Strategy)

  • 具体策略类1
/*** @author FluffyCatkin* @version 1.0* @date 2020/1/6 0006 17:51* @description 具体策略(Concrete Strategy)类1:实现了抽象策略定义的接口,提供具体的算法实现。*/
public class ConcreteStrategy1 implements Strategy {@Overridepublic void strategyMethod() {System.out.println("策略1被调用.........................");}
}
  • 具体策略类2
/*** @author FluffyCatkin* @version 1.0* @date 2020/1/6 0006 17:51* @description 具体策略(Concrete Strategy)类2:实现了抽象策略定义的接口,提供具体的算法实现。*/
public class ConcreteStrategy2 implements Strategy {@Overridepublic void strategyMethod() {System.out.println("策略2被调用........................");}
}

3. 环境(Context)


/*** @author FluffyCatkin* @version 1.0* @date 2020/1/6 0006 17:52* @description 环境(Context)类:持有一个策略类的引用,最终给客户端调用。*/
public class Context {private Strategy strategy;public void setStrategy(Strategy strategy) {this.strategy = strategy;}public Strategy getStrategy(){return this.strategy;}public void contextMethod(){strategy.strategyMethod();}}

4. 测试类


/*** @author FluffyCatkin* @version 1.0* @date 2020/1/6 0006 17:48* @description 策略模式** 在现实生活中常常遇到实现某种目标存在多种策略可供选择的情况,例如,出行旅游可以乘坐飞机、乘坐火车、骑自行车或自己开私家车等,超市促销可以釆用打折、送商品、送积分等方法。* 在软件开发中也常常遇到类似的情况,当实现某一个功能存在多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能,如数据排序策略有冒泡排序、选择排序、插入排序、二叉树排序等。* 如果使用多重条件转移语句实现(即硬编码),不但使条件语句变得很复杂,而且增加、删除或更换算法要修改原代码,不易维护,违背开闭原则。如果采用策略模式就能很好解决该问题。* 策略模式的定义与特点:* 策略(Strategy)模式的定义:该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。* 策略模式的主要优点如下:* 多重条件语句不易维护,而使用策略模式可以避免使用多重条件语句。* 策略模式提供了一系列的可供重用的算法族,恰当使用继承可以把算法族的公共代码转移到父类里面,从而避免重复的代码。* 策略模式可以提供相同行为的不同实现,客户可以根据不同时间或空间要求选择不同的。* 策略模式提供了对开闭原则的完美支持,可以在不修改原代码的情况下,灵活增加新算法。* 策略模式把算法的使用放到环境类中,而算法的实现移到具体策略类中,实现了二者的分离。** 其主要缺点如下:* 客户端必须理解所有策略算法的区别,以便适时选择恰当的算法类。* 策略模式造成很多的策略类。* 策略模式的结构与实现:* 策略模式是准备一组算法,并将这组算法封装到一系列的策略类里面,作为一个抽象策略类的子类。策略模式的重心不是如何实现算法,而是如何组织这些算法,从而让程序结构更加灵活,具有更好的维护性和扩展性,现在我们来分析其基本结构和实现方法。* 模式的结构:* 策略模式的主要角色如下。抽象策略(Strategy)类:定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。* 具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现。* 环境(Context)类:持有一个策略类的引用,最终给客户端调用。* 策略模式的应用场景:* 策略模式在很多地方用到,如 Java SE 中的容器布局管理就是一个典型的实例,Java SE 中的每个容器都存在多种布局供用户选择。在程序设计中,通常在以下几种情况中使用策略模式较多。一个系统需要动态地在几种算法中选择一种时,可将每个算法封装到策略类中。* 一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现,可将每个条件分支移入它们各自的策略类中以代替这些条件语句。* 系统中各算法彼此完全独立,且要求对客户隐藏具体算法的实现细节时。* 系统要求使用算法的客户不应该知道其操作的数据时,可使用策略模式来隐藏与算法相关的数据结构。* 多个类只区别在表现行为不同,可以使用策略模式,在运行时动态选择具体要执行的行为。*/
public class Main {/*** 测试策略模式*/@Testpublic void strategyTest(){Strategy strategy1 = new ConcreteStrategy1();Strategy strategy2 = new ConcreteStrategy2();Context context = new Context();context.setStrategy(strategy1);context.contextMethod();System.out.println("==============================");context.setStrategy(strategy2);context.contextMethod();}
}

执行结果:

策略1被调用.........................
==============================
策略2被调用........................Process finished with exit code 0

三、应用场景

  策略模式在很多地方用到,如 Java SE 中的容器布局管理就是一个典型的实例,Java SE 中的每个容器都存在多种布局供用户选择。在程序设计中,通常在以下几种情况中使用策略模式较多。

  • 一个系统需要动态地在几种算法中选择一种时,可将每个算法封装到策略类中。
  • 一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现,可将每个条件分支移入它们各自的策略类中以代替这些条件语句。
  • 系统中各算法彼此完全独立,且要求对客户隐藏具体算法的实现细节时。
  • 系统要求使用算法的客户不应该知道其操作的数据时,可使用策略模式来隐藏与算法相关的数据结构。
  • 多个类只区别在表现行为不同,可以使用策略模式,在运行时动态选择具体要执行的行为。

四、优缺点分析

  策略模式的主要优点如下:

  • 多重条件语句不易维护,而使用策略模式可以避免使用多重条件语句,如 if…else 语句、switch…case 语句。
  • 策略模式提供了一系列的可供重用的算法族,恰当使用继承可以把算法族的公共代码转移到父类里面,从而避免重复的代码。
  • 策略模式可以提供相同行为的不同实现,客户可以根据不同时间或空间要求选择不同的。
  • 策略模式提供了对开闭原则的完美支持,可以在不修改原代码的情况下,灵活增加新算法。
  • 策略模式把算法的使用放到环境类中,而算法的实现移到具体策略类中,实现了二者的分离。

  其主要缺点如下:

  • 客户端必须理解所有策略算法的区别,以便适时选择恰当的算法类。
  • 策略模式造成很多的策略类,增加维护难度。

代码地址:https://gitee.com/fluffycatkin/JavaDesignModel.git

    image.png

原文出处:http://c.biancheng.net/view/1378.html

相关文章:

十六、策略模式

一、什么是策略模式 策略(Strategy)模式的定义:该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式,它通过对算法…...

Python装饰器

什么是python装饰器? 顾名思义,从字面意思就可以理解,它是用来"装饰"Python的工具,使得代码更具有Python简洁的风格。换句话说,它是一种函数的函数,因为装饰器传入的参数就是一个函数&#xff0…...

【Spring】使用自定义注解方式实现AOP鉴权

AOP,是一种面向切面编程,可以通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。 在软件开发中,鉴权(Authentication)是一项非常重要的安全措施,用于验证用户身份和权限。在应用程序中&…...

Go几种读取配置文件的方式

比较有名的方案有 使用viper管理配置[1] 支持多种配置文件格式,包括 JSON,TOML,YAML,HECL,envfile,甚至还包括Java properties 支持为配置项设置默认值 可以通过命令行参数覆盖指定的配置项 支持参数别名 viper[2]按照这个优先级(从高到低&am…...

每日一题(反转链表)

每日一题(反转链表) 206. 反转链表 - 力扣(LeetCode) 思路: 可以定义一个新的newhead结构体指针。再定义cur指针和next指针互相配合,将原链表中的节点从头到尾依次头插到newhead链表中,同时更…...

某人事系统架构搭建设计记录

首发博客地址 https://blog.zysicyj.top/ 先大致列一下基础情况 架构必须是微服务 场景上涉及大量查询操作,分析操作 存在临时大量写入的场景 并发并不高 对高可用要求较高,不能挂掉 对安全要求高 要能过等保测试等三方测试 使用人数并不多,十…...

uniapp 实现切换tab锚点定位到指定位置

1.主要使用uniapp scroll-view 组件的scroll-into-view属性实现功能 2.代码如下 <scroll-view:scroll-into-view"intoView"><u-tabsclass"tabs-list"change"tabChange":list"tabList"></u-tabs><view id"1&…...

华纳云:ssh登录22号端口拒绝连接Ubuntu?

如果您在尝试使用SSH登录Ubuntu服务器的时候遇到了22号端口拒绝连接的问题&#xff0c;您可以尝试以下几个步骤来解决问题&#xff1a; 确认SSH服务已启动&#xff1a; 确保Ubuntu服务器上的SSH服务已经正确启动。您可以在服务器上运行以下命令来检查SSH服务的状态&#xff1a…...

python conda实践 sanic框架gitee webhook实践

import subprocess import hmac import hashlib import base64 from sanic.response import text from sanic import Blueprint from git import Repo# 路由蓝图 hook_blue Blueprint(hook_blue)hook_blue.route(/hook/kaifa, methods["POST"]) async def kaifa(req…...

LeetCode——无重复的最长子串(中等)

题目 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度 示例 1: 输入: s "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc"&#xff0c;所以其长度为 3。示例 2: 输入: s "bbbbb" 输出: 1 解释: 因为…...

【SQL】关系模型与查询和更新数据

一、关系模型 1.1 主键 主键是关系表中记录的唯一标识。主键的选取非常重要&#xff1a;主键不要带有业务含义&#xff0c;而应该使用BIGINT自增或者GUID类型。主键也不应该允许NULL。 可以使用多个列作为联合主键&#xff0c;但联合主键并不常用。 1.2 外键 FOREIGN KEY …...

【Centos8_配置单节点伪分布式Spark环境】

安装centos8 jdk部署伪分布式spark环境 安装Centos8 环境下的JDK 下载jdk linux版本 下载链接&#xff1a; jdk-8u381-linux-x64.tar.gz 将该文件上传到Centos8 主机 部署配置jdk&#xff08;java8&#xff09; # 解压到指定路径 [lhangtigerkeen Downloads]$ sudo tar …...

【软考】系统集成项目管理工程师(三)信息系统集成专业技术知识①【16分】

一、系统集成的特点 官方解释&#xff1a; 1、信息系统建设的内容主要包括设备采购、系统集成、软件开发和运维服务等&#xff1b; 2、信息系统集成是指将计算机软件、硬件、网络通信、信息安全等技术和产品集成为能够满足用户特定需求的信息系统&#xff1b;显著特点如下&am…...

揭秘特权账号潜在风险,你中招了吗?

什么是特权账号&#xff1f; 特权账号指在企业运营过程中&#xff0c;为相关业务运营、系统管理、系统运维等人员赋予的系统维护、权限增加、数据修改删除、导出等高级权限的系统账号。这些账号多数连接企业核心资源&#xff0c;保障企业内部各项业务正常运作。然而&#xff0…...

线性代数的学习和整理13: 定义域,值域,到达域 和单射,满射,双射,反函数,逆矩阵

目录 1 函数与 向量/矩阵 2 初等数学的函数 2.1 函数 2.2 函数的定义&#xff1a;定义域 →映射→ 值域 3 高等数学里的函数&#xff1a;定义域和陪域/到达域&#xff08;非值域&#xff09;的映射关系 3.1 函数 3.2 单射&#xff0c;满射&#xff0c;双射等都是针对…...

深入MaxCompute -第十一弹 -QUALIFY

简介&#xff1a; MaxCompute支持QUALIFY语法过滤Window函数的结果&#xff0c;使得查询语句更简洁易理解。Window函数和QUALIFY语法之间的关系可以类比聚合函数GROUP BY语法和HAVING语法。 MaxCompute&#xff08;原ODPS&#xff09;是阿里云自主研发的具有业界领先水平的分…...

Mysql定时备份事件

创建了一个名为backup_database的定时任务&#xff0c;每天自动在当前时间的后一天开始执行。备份数据库的代码使用mysqldump命令将数据库导出为sql文件保存在指定的备份目录中。 需要注意的是&#xff0c;上述代码中的用户名 (username)、密码 (password)、主机名 (hostname) …...

探索ClickHouse——安装和测试

我们在Ubuntu 20 Server版虚拟机上对ClickHouse进行探索。 安装 检测环境 grep -q sse4_2 /proc/cpuinfo && echo "SSE 4.2 supported" || echo "SSE 4.2 not supported"SSE 4.2 supported 可以看到我们的环境支持编译版本的。如果不支持的环境…...

常用的css样式

1&#xff1a;flex布局 .flex-between {display: flex;justify-content: space-between; }.flex-evenly {display: flex;justify-content: space-evenly; }.flex-end {display: flex;justify-content: flex-end; }.flex {display: flex; }.flex-center {display: flex;justify…...

小兔鲜儿 - 微信登录

目录 微信登录​ 登录方式 静态结构​ 获取登录凭证​ 获取手机号码​ 微信登录接口(生产环境) 模拟手机登录(开发环境) 用户信息持久化存储​ 涉及知识点&#xff1a;微信授权登录&#xff0c;文件上传&#xff0c;Store 状态管理等。 微信登录​ 微信小程序的开放…...

conda相比python好处

Conda 作为 Python 的环境和包管理工具&#xff0c;相比原生 Python 生态&#xff08;如 pip 虚拟环境&#xff09;有许多独特优势&#xff0c;尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处&#xff1a; 一、一站式环境管理&#xff1a…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

label-studio的使用教程(导入本地路径)

文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性&#xff1a;电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中&#xff0c;电力载波技术&#xff08;PLC&#xff09;凭借其独特的优势&#xff0c;正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据&#xff0c;无需额外布…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...

听写流程自动化实践,轻量级教育辅助

随着智能教育工具的发展&#xff0c;越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式&#xff0c;也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建&#xff0c;…...

算法打卡第18天

从中序与后序遍历序列构造二叉树 (力扣106题) 给定两个整数数组 inorder 和 postorder &#xff0c;其中 inorder 是二叉树的中序遍历&#xff0c; postorder 是同一棵树的后序遍历&#xff0c;请你构造并返回这颗 二叉树 。 示例 1: 输入&#xff1a;inorder [9,3,15,20,7…...

C++_哈希表

本篇文章是对C学习的哈希表部分的学习分享 相信一定会对你有所帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、基础概念 1. 哈希核心思想&#xff1a; 哈希函数的作用&#xff1a;通过此函数建立一个Key与存储位置之间的映射关系。理想目标&#xff1a;实现…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现指南针功能

指南针功能是许多位置服务应用的基础功能之一。下面我将详细介绍如何在HarmonyOS 5中使用DevEco Studio实现指南针功能。 1. 开发环境准备 确保已安装DevEco Studio 3.1或更高版本确保项目使用的是HarmonyOS 5.0 SDK在项目的module.json5中配置必要的权限 2. 权限配置 在mo…...