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

概述

策略模式又叫政策模式,是一种对象行为型模式。它是将定义的算法家族分别封装起来,让它们之间可以互相替换,从而让算法的变化不会影响到使用算法的用户。策略模式的主要目的是将算法的定义与使用分开,也就是将算法的行为和环境分开,将算法的定义放在专门的策略类中,每一个策略类封装了一种实现算法,使用算法的环境类针对抽象策略类进行编程,符合“依赖倒转原则”。在出现新的算法时,只需要增加一个新的实现了抽象策略类的具体策略类即可。策略模式定义如下:策略模式(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) 不希望客户端知道复杂的、与算法相关的数据结构,在具体策略类中封装算法与相关的数据结构,可以提高算法的保密性与安全性。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

NV040D语音芯片应用于取暖桌:智能语音提高用户体验

科技与生活的结合,是科技发展的展示。天气的降温,取暖桌越来越取得用户的心,时至今日传统的取暖桌已经没有办法满足用户的需求,智能语音取暖桌给用户的生活带来了不一样的体验。 NV040D语音芯片是一款性能稳定的芯片,拥…

arcgis api for js 图层标注文本不显示

在打包arcgis api for js 项目后,更新到现场所有地图文本要素不显示的时候。 可能就是环境设置问题了,需要配置iis或者ngixs里边配置如下类型 iis发布的项目 1、打开iis中发布的网站 2、找到网站的MIME类型如下图 3、添加一下类型(一个都不…

CentOS系统下配置HTTP服务器的步骤

在CentOS系统下配置HTTP服务器涉及到一系列的步骤。以下是一个基本的步骤概述,帮助你了解如何为CentOS系统配置HTTP服务器。 安装HTTP服务器软件: 首先,你需要在CentOS系统上安装HTTP服务器软件。常见的选择是Apache HTTP服务器。你可以使用…

前端开发新趋势:Web3、区块链与虚拟现实

文章目录 Web3:下一代互联网区块链技术去中心化应用程序(DApps) 区块链:重塑数字世界数字钱包NFT(非同质化代币) 虚拟现实:沉浸式体验WebVR和WebXR三维图形 新挑战与机会性能与复杂性安全性创新…

9.静态路由

静态路由 中小型网络都会用到,防火墙核心交换机用的很多,一般是用在出口 路由表:路由器用来转发数据包唯一的依据 NextHop下一跳 Static静态路由需要手动设置 ip route-static 目标网段 掩码 下一跳例如:ip route-static 192…

我们一起做过的SPA——Nuxt.js介绍

Nuxt.js 1 我们一起做过的SPA SPA(single page web application)单页 Web 应用,Web 不再是一张张页面,而是一个整体的应用,一个由路由系统、数据系统、页面(组件)系统等等,组成的应…

VMware虚拟机cpu不支持avx指令集处理

原创作者:运维工程师 谢晋 VMware虚拟机cpu不支持avx指令集处理 客户虚拟化环境内有台虚拟机内应用程序需要使用到avx指令集,排查过物理主机CPU是支持avx指令集,但虚拟机内缺无法正常应用,需将虚拟机CPU修改为硬件模式。将虚拟…

高压配电系统智能监测

高压配电系统智能监测是一种基于现代信息技术的电力系统监测手段,依托电易云-智慧电力物联网,旨在提高高压配电系统的安全性、可靠性和运行效率。具体而言,高压配电系统智能监测包括以下方面: 实时监测:通过安装传感器…

笔记69:Conv1d 和 Conv2d 之间的区别

笔记地址:D:\work_file\(4)DeepLearning_Learning\03_个人笔记\4. Transformer 网络变体 a a a a a a a a a a a

L1-028:判断素数

题目描述 本题的目标很简单,就是判断一个给定的正整数是否素数。 输入格式: 输入在第一行给出一个正整数N(≤ 10),随后N行,每行给出一个小于231的需要判断的正整数。 输出格式: 对每个需要判断的…

stable video diffusion:scaling latent video diffusion models to large datasets

【AIGC-AI视频生成系列-5】Stable Video Diffusion -长文解读视频/3D生成变革的开始 - 知乎一句话总结:长文解读一份Stability AI 最新力作Stable Video Diffusion,如同实验报告的论文,构建了一个高质量的视频生成通用模型,在多种…

cache教程 5.分布式节点的通信

0.对原教程的一些见解 其回顾完请求流程就是抽象了两个接口,PeerPicker和PeerGetter。这样操作,读者阅读时可能很难快速明白其含义,不好理解为什么就创建出两个接口,感觉会比较疑惑。原教程的评论中也有讨论这点。 本教程就先不创…

Error opening file for writing报错解决

报错展示及描述 在安装pycharm的时候出现了一下报错, Error opening file for writing。 报错原因 一般出现这种报错都是文件权限的原因,检查一下,果然这个文件夹权限是【只读】 查看文件权限的方式:【右击】文件夹名称&#xff0…

【23真题】拜托再练一套!保持手感!

今天分享的是23年河北科技大学882的信号与系统试题及解析。 本套试卷难度分析:22年河北科技大学822考研真题,我也发布过,若有需要,戳这里自取!本套试题难度中等偏下,题量适中,对于很多基础知识…

大创项目推荐 协同过滤电影推荐系统

文章目录 1 简介1 设计概要2 课题背景和目的3 协同过滤算法原理3.1 基于用户的协同过滤推荐算法实现原理3.1.1 步骤13.1.2 步骤23.1.3 步骤33.1.4 步骤4 4 系统实现4.1 开发环境4.2 系统功能描述4.3 系统数据流程4.3.1 用户端数据流程4.3.2 管理员端数据流程 4.4 系统功能设计 …

mycat部署和配置读写分离(二)

说明: MyCAT 是使用 JAVA 语言进行编写开发,使用前需要先安装 JAVA 运行环境(JRE),由于 MyCAT 中使用了 JDK7 中的一些特性,所以要求必须在 JDK7 以上的版本上运行。 1. jdk1.8安装 详见jdk环境安装 2. Mysql安装 详见mysql8.0.11源码安装…

Oracle(2-15)RMAN Incomplete Recovery

文章目录 一、基础知识1、The Procedure 不完全恢复步骤2、UNTIL TIME Example 基于时间的恢复3、UNTIL SEOUENCE Example 基于序列的恢复 二、基础操作1、不完全恢复准备工作2、不完全恢复开始恢复 RMAN Incomplete Recovery RMAN的不完全恢复 目标: 使用“UNTIL T…

【开源】基于Vue和SpringBoot的计算机机房作业管理系统

项目编号: S 017 ,文末获取源码。 \color{red}{项目编号:S017,文末获取源码。} 项目编号:S017,文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 登录注册模块2.2 课程管理模块2.3 课…

Linux基础指令(2)

今天我们继续来学我们有关于Linux的指令,今天的指令要比上次多多了。开始我们的学习吧。 man手册 先来看标题,手册我们第一时间想到的就是手册的查阅功能,我们都知道在我们上小学的时候,如果遇到不会的字,我们会通过…

《opencv实用探索·十六》opencv直方图计算calcHist函数解析

直方图理解: (对于8位灰度图像亮度/灰度为(0-255),12位灰度图像亮度/灰度为(0-4095)) 以8位图像为例,亮度分为0到255共256个数值,数值越大,代表的亮度越高。其中0代表纯黑色的最暗区域&#xff…