设计模式——策略模式(Strategy Pattern)

news2024/11/16 13:48:58
概述

策略模式又叫政策模式,是一种对象行为型模式。它是将定义的算法家族分别封装起来,让它们之间可以互相替换,从而让算法的变化不会影响到使用算法的用户。策略模式的主要目的是将算法的定义与使用分开,也就是将算法的行为和环境分开,将算法的定义放在专门的策略类中,每一个策略类封装了一种实现算法,使用算法的环境类针对抽象策略类进行编程,符合“依赖倒转原则”。在出现新的算法时,只需要增加一个新的实现了抽象策略类的具体策略类即可。策略模式定义如下:策略模式(Strategy Pattern):定义一系列算法类,将每一个算法封装起来,并让它们可以相互替换,策略模式让算法独立于使用它的客户而变化,也称为政策模式(Policy)。策略模式是一种对象行为型模式。

策略模式结构并不复杂,但我们需要理解其中环境类Context的作用,其结构如图:

在策略模式结构图中包含如下几个角色:

      ● Context(环境类):环境类是使用算法的角色,它在解决某个问题(即实现某个方法)时可以采用多种策略。在环境类中维持一个对抽象策略类的引用实例,用于定义所采用的策略。

      ● Strategy(抽象策略类):它为所支持的算法声明了抽象方法,是所有策略类的父类,它可以是抽象类或具体类,也可以是接口。环境类通过抽象策略类中声明的方法在运行时调用具体策略类中实现的算法。

      ● ConcreteStrategy(具体策略类):它实现了在抽象策略类中声明的算法,在运行时,具体策略类将覆盖在环境类中定义的抽象策略类对象,使用一种具体的算法实现某个业务处理。

策略模式是一个比较容易理解和使用的设计模式,策略模式是对算法的封装,它把算法的责任和算法本身分割开,委派给不同的对象管理。策略模式通常把一个系列的算法封装到一系列具体策略类里面,作为抽象策略类的子类。在策略模式中,对环境类和抽象策略类的理解非常重要,环境类是需要使用算法的类。在一个系统中可以存在多个环境类,它们可能需要重用一些相同的算法。

简单实现

      在使用策略模式时,我们需要将算法从Context类中提取出来,首先应该创建一个抽象策略类,其典型代码如下所示:

然后再将封装每一种具体算法的类作为该抽象策略类的子类,如下代码所示:

其他具体策略类与之类似,对于Context类而言,在它与抽象策略类之间建立一个关联关系,其典型代码如下所示:

在Context类中定义一个AbstractStrategy类型的对象strategy,通过注入的方式在客户端传入一个具体策略对象,客户端代码片段如下所示:

在客户端代码中只需注入一个具体策略对象,可以将具体策略类类名存储在配置文件中,通过反射来动态创建具体策略对象,从而使得用户可以灵活地更换具体策略类,增加新的具体策略类也很方便。也可以使用工厂方法模式获取具体的策略对象等。策略模式提供了一种可插入式(Pluggable)算法的实现方案

总结

策略模式用于算法的自由切换和扩展,它是应用较为广泛的设计模式之一。策略模式对应于解决某一问题的一个算法族,允许用户从该算法族中任选一个算法来解决某一问题,同时可以方便地更换算法或者增加新的算法。只要涉及到算法的封装、复用和切换都可以考虑使用策略模式。

      1. 主要优点

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

      (1) 策略模式提供了对“开闭原则”的完美支持,用户可以在不修改原有系统的基础上选择算法或行为,也可以灵活地增加新的算法或行为。

      (2) 策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族,恰当使用继承可以把公共的代码移到抽象策略类中,从而避免重复的代码。

      (3) 策略模式提供了一种可以替换继承关系的办法。如果不使用策略模式,那么使用算法的环境类就可能会有一些子类,每一个子类提供一种不同的算法。但是,这样一来算法的使用就和算法本身混在一起,不符合“单一职责原则”,决定使用哪一种算法的逻辑和该算法本身混合在一起,从而不可能再独立演化;而且使用继承无法实现算法或行为在程序运行时的动态切换。

      (4) 使用策略模式可以避免多重条件选择语句。多重条件选择语句不易维护,它把采取哪一种算法或行为的逻辑与算法或行为本身的实现逻辑混合在一起,将它们全部硬编码(Hard Coding)在一个庞大的多重条件选择语句中,比直接继承环境类的办法还要原始和落后。

      (5) 策略模式提供了一种算法的复用机制,由于将算法单独提取出来封装在策略类中,因此不同的环境类可以方便地复用这些策略类。

      2. 主要缺点

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

      (1) 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法。换言之,策略模式只适用于客户端知道所有的算法或行为的情况。

      (2) 策略模式将造成系统产生很多具体策略类,任何细小的变化都将导致系统要增加一个新的具体策略类。

      (3) 无法同时在客户端使用多个策略类,也就是说,在使用策略模式时,客户端每次只能使用一个策略类,不支持使用一个策略类完成部分功能后再使用另一个策略类来完成剩余功能的情况。

      3. 适用场景

      在以下情况下可以考虑使用策略模式:

      (1) 一个系统需要动态地在几种算法中选择一种,那么可以将这些算法封装到一个个的具体算法类中,而这些具体算法类都是一个抽象算法类的子类。换言之,这些具体算法类均有统一的接口,根据“里氏代换原则”和面向对象的多态性,客户端可以选择使用任何一个具体算法类,并只需要维持一个数据类型是抽象算法类的对象。

      (2) 一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重条件选择语句来实现。此时,使用策略模式,把这些行为转移到相应的具体策略类里面,就可以避免使用难以维护的多重条件选择语句。

      (3) 不希望客户端知道复杂的、与算法相关的数据结构,在具体策略类中封装算法与相关的数据结构,可以提高算法的保密性与安全性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1303619.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IoTDB JavaAPI

文章目录 使用样例Java使用样例 官方已经给出了相关使用Demo,下载地址为: https://github.com/apache/iotdb 直接拉取相对应版本的源码 使用样例 Java使用样例 代码位置 iotdb/example/session/src/main/java/org/apache/iotdb/SessionExample.java iotdb/exa…

springboot打成war包及VUE打成war包放入tomcat启动

1.springboot打成war包步骤 首先在springboot启动类中继承SpringBootServletInitializer,重写configure方法,如下: SpringBootApplication() public class StartApplication extends SpringBootServletInitializer {public static void main(String[] …

计算机网络编程

网络编程 Java 是第一大编程语言和开发平台。它有助于企业降低成本、缩短开发周期、推动创新以及改善应用服务。如今全球有数百万开发人员运行着超过 51 亿个 Java 虚拟机, Java 仍是企业和开发人员的首选开发平台。 课程内容的介绍 1. 计算机网络基础 2. So…

Network 灰鸽宝典【目录】

目前已有文章 11 篇 Network 灰鸽宝典专栏主要关注服务器的配置,前后端开发环境的配置,编辑器的配置,网络服务的配置,网络命令的应用与配置,windows常见问题的解决等。 文章目录 canvas理论基础canvas高级应用示例canv…

Java 线程的基本概念

创建和运行线程 方法一,直接使用 Thread // 创建线程对象 Thread t new Thread() {public void run() {// 要执行的任务}};// 启动线程 t.start();例如: // 构造方法的参数是给线程指定名字,推荐 Thread t1 new Thread("t1") …

软件测试:基础概念

目录 ​编辑 一、前言 二、软件测试的原则和方法论 1.测试的原则 2.测试的方法论 2. 软件测试策略 2.1 单元测试 2.2 集成测试 2.3 系统测试 2.4 用户验收测试 3. 软件测试的最佳实践 3.1 自动化测试 3.2 持续集成 3.3 边界值测试 三、软件测试的技术和实践 1.…

深度学习——第4.3章 深度学习的数学基础

第4章 深度学习的数学基础 目录 4.7 指数函数和对数函数 4.7 指数函数和对数函数 深度学习经常会用到Sigmoid函数和Softmax函数,这些函数是通过包含exp(x)的指数函数创建的。后面我们需要求解这些函数的导数。 4.7.1 指数 指数是一个基于“乘以某个数多少次”&a…

远程工作:自由职业者如何成功赚钱

前言 在这个不断进步的数字化时代,远程工作已经从一个可选的边缘工作方式,成长为主流职业趋势的一部分。特别是自从全球疫情改变了我们的生活和工作方式以来,远程工作的概念不再是遥不可及的理想,而是已经成为许多人日常工作的现…

12 位多通道国产芯片ACM32F403/F433 系列,支持 MPU 存储保护功能,应用于工业控制,智能家居等产品中

ACM32F403/F433 芯片的内核基于 ARMv8-M 架构,支持 Cortex-M33 和 Cortex-M4F 指令集。芯片内核 支持一整套DSP指令用于数字信号处理,支持单精度FPU处理浮点数据,同时还支持Memory Protection Unit (MPU)用于提升应用的…

PCB-修改pcb封装后,规则重新检查出现的提示解决

规则检查 前提 前提 要在.pcbdoc页面点击design 点击 run design rule check 3.出现提示 4.意思是对某些器件修改过,进行重新铺铜即可 重新铺铜快捷键:TGA,如下是重新铺铜后的结果

气温波动 C语言xdoj45

问题描述 最近一段时间气温波动较大。已知连续若干天的气温,请给出这几天气温的最大波动值是多少,即在这几天中某天气温与前一天气温之差的绝对值最大是多少。 输入说明 输入数据分为两行。 第一行包含了一个整数n,表示给出了连续n天…

订单接入支付宝流程实战与优化

概述 了解支付宝支付能力接入方式。电商项目如何对支付流程进行设计及优化。基于 RocketMQ 事务消息实现的订单确认机制,来完成订单超时回退功能。 支付宝接入流程简介 国内目前有支付牌照的公司总共只有两百来家,比如支付宝、云闪付、和包支付、翼支…

el-table的复选框占满全格

el-table的复选框格子很小每次点击都点不到&#xff0c;又不想设置行点击&#xff0c;因为每次复制内容都会选中&#xff0c;实现效果是点击el-table的复选框单元格就可以选中 <template><div style"width: 60vw; margin: 10px;"><el-table :data&quo…

金蝶云星空审核使用了基础资料的属性字段报错:表达式计算出错

文章目录 金蝶云星空审核使用了基础资料的属性字段报错&#xff1a;表达式计算出错报错内容解决方案 金蝶云星空审核使用了基础资料的属性字段报错&#xff1a;表达式计算出错 报错内容 表达式计算出错: F_XXXX_MaterialId.FIsSNManage true and F_XXXX_ProductLibraryId 0 …

Cython笔记:基本使用方法

1 Cython 介绍 Cython 是一种编程语言&#xff0c;用于编写 C 扩展的 Python 模块。它结合了 Python 的易用性和 C 的执行效率&#xff0c;旨在提高特定类型的任务的性能&#xff0c;特别是涉及大量数值计算的任务。 1.2 几个特征 1.2.1 Python 语法的基础 Cython 的大部分语…

市场全局复盘 20231208

一、板块成交额排名&#xff1a; 资金流入前三个板块K 线&#xff1a; 行业成交额排名&#xff1a; 个股资金流入排名&#xff1a; select 成交额排名 ,近日指标提示 ,短线主题 ,涨停分析,CODE,名称,DDE大单净量,现价,量比,连板天,周涨停,月涨停,年涨停天,连涨天,…

【Nacos】在Windows环境下搭建Nacos服务与Python开发示例

在Windows环境下搭建Nacos服务与Python开发示例 Nacos是一个开源的动态服务发现、配置和服务管理平台。本文将介绍在Windows环境下搭建Nacos服务&#xff0c;并提供一个简单的Python示例&#xff0c;演示如何通过Nacos实现服务注册与发现。 官方提示&#xff1a;Nacos定义为一…

软件开发流程分析

软件开发流程分析 相关概念1 原型设计2 产品设计3 交互设计4 代码实现详细步骤 相关概念 前端&#xff1a;自研API&#xff0c;调用第三放API 后端&#xff1a;自研API&#xff0c;第三方API 数据库&#xff1a;Mysql&#xff0c;数据采集&#xff0c;数据迁移 服务器&#xf…

优势怪代码

#include <stdio.h> int main() { int t; scanf("%d", &t); // 读取测试用例的数量 while (t--) { // 对每个测试用例进行处理 int n, max1 0, max2 0, k 0; scanf("%d", &n); // 读取数组的大小 in…

瑞萨RZ/G2L核心板Linux Log目录文件详解

为了排除系统问题&#xff0c;监控系统健康状况以及了解系统与应用程序的交互方式&#xff0c;我们需要了解各log文件的作用&#xff0c;以G2L中yocto文件系统为例&#xff0c;在系统/var/log/目录下会存放记录系统中各个部分的log文件作用如下&#xff1a; 1. 文件详情 下图…