妙解设计模式之策略模式
目录
- 策略模式的概念
- 生活中的例子
- 编程中的例子
- 软件工程中的实际应用
- 数据排序
- 文件压缩
- 支付方式
- 图形绘制
策略模式的概念
策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列算法,把它们一个个封装起来,并且使它们可以相互替换。这种模式使得算法可以独立于使用它的客户端而变化。
策略模式的关键点
- 策略接口(Strategy):定义所有策略(算法)共有的方法。
- 具体策略类(ConcreteStrategy):实现策略接口的具体算法。
- 上下文类(Context):持有一个策略对象,并在需要时调用这个策略的方法。
策略模式的优点
- 易于扩展:增加新算法时,只需添加新的具体策略类,不需要修改现有的代码。
- 避免使用多重条件语句:通过使用策略模式,可以避免大量的
if-else
或switch
语句,使代码更加简洁和清晰。 - 提高代码的灵活性和可维护性:可以动态地改变算法,而不需要修改客户端代码。
策略模式的缺点
- 增加类的数量:每个具体策略都是一个单独的类,会导致类的数量增多,增加代码的复杂性。
- 所有策略类都需要暴露:策略类需要对外公开,以便可以被选择和使用。
生活中的例子
策略模式是一种设计模式,它允许你定义一系列算法(或者叫方法),然后在运行时选择其中一个来使用。就像你有一个装满不同类型武器的工具箱,每次打怪兽的时候,你可以选择最合适的武器来使用。
编程中的例子
策略接口
// 定义策略接口
public interface AttackStrategy {void attack();
}
这个接口定义了一个 attack
方法,所有的具体策略类都需要实现这个方法。
具体策略类
// 使用剑攻击
public class SwordAttack implements AttackStrategy {@Overridepublic void attack() {System.out.println("使用剑攻击怪兽!");}
}// 使用弓箭攻击
public class BowAndArrowAttack implements AttackStrategy {@Overridepublic void attack() {System.out.println("使用弓箭攻击怪兽!");}
}// 使用魔法攻击
public class MagicAttack implements AttackStrategy {@Overridepublic void attack() {System.out.println("使用魔法攻击怪兽!");}
}
这些类实现了 AttackStrategy
接口,并提供了具体的攻击方法。
上下文类
// 上下文类
public class MonsterHunter {private AttackStrategy strategy;// 设置策略public void setStrategy(AttackStrategy strategy) {this.strategy = strategy;}// 执行攻击public void attackMonster() {strategy.attack();}
}
上下文类 MonsterHunter
持有一个 AttackStrategy
对象,并在 attackMonster
方法中调用策略对象的 attack
方法。
使用策略模式
public class Main {public static void main(String[] args) {MonsterHunter hunter = new MonsterHunter();// 使用剑攻击hunter.setStrategy(new SwordAttack());hunter.attackMonster();// 使用弓箭攻击hunter.setStrategy(new BowAndArrowAttack());hunter.attackMonster();// 使用魔法攻击hunter.setStrategy(new MagicAttack());hunter.attackMonster();}
}
在这个例子中,我们创建了一个 MonsterHunter
对象,并通过 setStrategy
方法动态设置不同的攻击策略。每次设置策略后,我们调用 attackMonster
方法来执行相应的攻击。
软件工程中的实际应用
数据排序
在应用程序中,你可能需要对数据进行排序,但不同情况下的排序规则可能不同。例如,有时候需要按名字排序,有时候需要按年龄排序。这时,可以使用策略模式定义不同的排序算法,并根据需要选择合适的算法。
// 定义排序策略接口
public interface SortStrategy {void sort(int[] numbers);
}// 具体策略类:冒泡排序
public class BubbleSort implements SortStrategy {@Overridepublic void sort(int[] numbers) {// 实现冒泡排序算法}
}// 具体策略类:快速排序
public class QuickSort implements SortStrategy {@Overridepublic void sort(int[] numbers) {// 实现快速排序算法}
}// 上下文类
public class Sorter {private SortStrategy strategy;public void setStrategy(SortStrategy strategy) {this.strategy = strategy;}public void sort(int[] numbers) {strategy.sort(numbers);}
}// 使用策略模式进行排序
public class Main {public static void main(String[] args) {int[] numbers = {5, 2, 9, 1, 5, 6};Sorter sorter = new Sorter();sorter.setStrategy(new BubbleSort());sorter.sort(numbers);sorter.setStrategy(new QuickSort());sorter.sort(numbers);}
}
文件压缩
在文件压缩工具中,可能支持多种压缩算法,比如 ZIP、RAR、TAR 等。可以使用策略模式来选择不同的压缩算法
// 定义压缩策略接口
public interface CompressionStrategy {void compress(String filePath);
}// 具体策略类:ZIP压缩
public class ZipCompression implements CompressionStrategy {@Overridepublic void compress(String filePath) {// 实现ZIP压缩算法}
}// 具体策略类:RAR压缩
public class RarCompression implements CompressionStrategy {@Overridepublic void compress(String filePath) {// 实现RAR压缩算法}
}// 上下文类
public class Compressor {private CompressionStrategy strategy;public void setStrategy(CompressionStrategy strategy) {this.strategy = strategy;}public void compress(String filePath) {strategy.compress(filePath);}
}// 使用策略模式进行文件压缩
public class Main {public static void main(String[] args) {Compressor compressor = new Compressor();compressor.setStrategy(new ZipCompression());compressor.compress("example.txt");compressor.setStrategy(new RarCompression());compressor.compress("example.txt");}
}
支付方式
在电商网站中,用户可能使用不同的支付方式,例如信用卡支付、PayPal 支付、银行转账等。可以使用策略模式来实现不同的支付方式。
// 定义支付策略接口
public interface PaymentStrategy {void pay(double amount);
}// 具体策略类:信用卡支付
public class CreditCardPayment implements PaymentStrategy {@Overridepublic void pay(double amount) {// 实现信用卡支付}
}// 具体策略类:PayPal支付
public class PayPalPayment implements PaymentStrategy {@Overridepublic void pay(double amount) {// 实现PayPal支付}
}// 上下文类
public class PaymentProcessor {private PaymentStrategy strategy;public void setStrategy(PaymentStrategy strategy) {this.strategy = strategy;}public void processPayment(double amount) {strategy.pay(amount);}
}// 使用策略模式进行支付
public class Main {public static void main(String[] args) {PaymentProcessor processor = new PaymentProcessor();processor.setStrategy(new CreditCardPayment());processor.processPayment(100.0);processor.setStrategy(new PayPalPayment());processor.processPayment(100.0);}
}
图形绘制
在图形应用程序中,可能需要使用不同的绘制算法,比如绘制线条、绘制矩形、绘制圆形等。可以使用策略模式来封装不同的绘制算法。
// 定义绘制策略接口
public interface DrawStrategy {void draw();
}// 具体策略类:绘制线条
public class DrawLine implements DrawStrategy {@Overridepublic void draw() {// 实现绘制线条的算法}
}// 具体策略类:绘制矩形
public class DrawRectangle implements DrawStrategy {@Overridepublic void draw() {// 实现绘制矩形的算法}
}// 具体策略类:绘制圆形
public class DrawCircle implements DrawStrategy {@Overridepublic void draw() {// 实现绘制圆形的算法}
}// 上下文类
public class GraphicEditor {private DrawStrategy strategy;public void setStrategy(DrawStrategy strategy) {this.strategy = strategy;}public void draw() {strategy.draw();}
}// 使用策略模式进行绘图
public class Main {public static void main(String[] args) {GraphicEditor editor = new GraphicEditor();editor.setStrategy(new DrawLine());editor.draw();editor.setStrategy(new DrawRectangle());editor.draw();editor.setStrategy(new DrawCircle());editor.draw();}
}
相关文章:
妙解设计模式之策略模式
目录 策略模式的概念生活中的例子编程中的例子 软件工程中的实际应用数据排序文件压缩支付方式图形绘制 策略模式的概念 策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列算法,把它们一个个封装起来,并…...

Linux DHCP server 配置
参考:linux dhcp配置多vlan ip_linux 接口vlan-CSDN博客 配置静态IP地址: 给固定的MAC地址分配指定的IP地址,固定的IP地址不必包含在指定的IP池中,如果包含在IP地址池中,固定的IP地址会从IP地址池中移除 配置方法&…...
深入解析力扣166题:分数到小数(模拟长除法与字符串操作详解及模拟面试问答)
力扣166题:分数到小数 在本篇文章中,我们将详细解读力扣第166题“分数到小数”。通过学习本篇文章,读者将掌握如何使用多种方法来解决这一问题,并了解相关的复杂度分析和模拟面试问答。每种方法都将配以详细的解释和ASCII图解&am…...

新疆 | 金石商砼效率革命背后的逻辑
走进标杆企业,感受名企力量,探寻学习优秀企业领先之道。 本期要跟砼行们推介的标杆企业是新疆砼行业的龙头企业:新疆兵团建工金石商品混凝土有限责任公司(以下简称:新疆金石)。 从年产80万方到120万方&am…...

Dinky MySQLCDC 整库同步到 Doris
资源:flink 1.17.0、dinky 1.0.2、doris-2.0.1-rc04 问题:Cannot deserialize value of type int from String ,detailMessageunknowndatabases ,not a valid int value 2024-05-29 16:52:20.136 ERROR org.apache.doris.flink.…...

基于Qt的网上购物系统的设计与实现
企鹅:2583550535 代码和论文都有 第1章 绪论... 1 1.1 项目背景... 1 1.2 国内外研究现状... 1 1.3 项目开发意义... 3 1.4 报告主要内容... 3 第2章 关键技术介绍... 4 2.1 后端开发技术... 4 2.1.1 C. 4 2.1.2 Qt框架... 4 2.1.3 MySQL数据库... 5 2.2 …...

设计软件有哪些?建模和造型工具篇(4),渲染100邀请码1a12
建模使用到的工具有很多,这次我们接着介绍。 1、PolyBoost PolyBoost是由Digimation公司开发的3ds Max插件,旨在增强软件的多边形建模功能。该插件提供了一系列强大的建模工具,如边缘控制、顶点编辑、面片调整等,使用户能够更加…...

Java基础:面向对象(二)
Java基础:面向对象(二) 文章目录 Java基础:面向对象(二)1. 面向对象编程思想2. 类与对象2.1 类2.1.1 类的定义2.1.2 成员变量2.1.3 局部变量 2.2 对象2.2.1 对象的定义2.2.2 对象的使用2.2.3 对象创建的原理…...

【汽车之家注册/登录安全分析报告】
前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 1. 暴力破解密码,造成用户信息泄露 2. 短信盗刷的安全问题,影响业务及导致用户投诉 3. 带来经济损失,尤其是后付费客户,风险巨大,造…...

cocos 通过 electron 打包成 exe 文件,实现通信问题
cocos 通过 electron 打包成 exe 文件,实现通信问题 首先,我使用的 cocos 版本是 2.4.12,遇到一个问题,是啥子呢,就是我要把用 cocos 开发出来的项目打包成一个 exe 可执行程序,使用的是 electron …...

python中pow是什么意思
pow()方法返回xy(x的y次方)的值。 语法 以下是math模块pow()方法的语法: import math math.pow( x, y ) 内置的pow()方法 pow(x, y[, z]) 函数是计算x的y次方,如果z在存在,则再对结果进行取模,其结果等效…...
Go语言数据库框架 — Gorm
Go入门之Gorm 框架_go gorm-CSDN博客 https://zhuanlan.zhihu.com/p/677057361 一、简介 Gorm框使用ORM技术,将对象(O)和关系数据库(R)之间的映射(M)抽象出来,开发者通过操作对象的方式操作数据库,不需要直接处理SQL语句,降低了…...
Python库之PyQuery的高级用法深度解析
Python库之PyQuery的高级用法深度解析 引言 PyQuery是一个强大的Python库,它提供了类似于jQuery的语法来解析和操作HTML和XML文档。虽然PyQuery的基本用法已经相当直观,但本文将深入探讨一些高级用法,帮助开发者更高效地处理复杂的HTML文档…...
「架构」单元测试及运用
在参与管理和研发软件项目的过程中,单元测试的实际运用对于确保最终产品的质量至关重要。以下是一些实际运用的案例和说明。 静态测试的实际运用 在TechCorp的电子商务平台项目中,静态测试作为代码质量保证的第一道防线。开发团队在编写代码的同时,使用SonarQube等静态代码…...

C# 数组/集合排序
一:基础类型集合排序 /// <summary> /// 排序 /// </summary> /// <param name"isReverse">顺序是否取反</param> public static void Sort<T>(this IList<T> array, bool isReverse false)where T : IComparable …...

HDRnet
local feature and global feature 在这里插入图片描述 Local features and Global features in Image Local feature also known as local descriptors, are distinct, informative characteristics of an image or video frame that are used in computer vision and image…...

【ArcGISPro】3.1.5下载和安装教程
下载教程 arcgis下载地址:Трекер (rutracker.net) 点击磁力链下载弹出对应的软件进行下载 ArcGISPro3.1新特性 ArcGIS Pro 3.1是ArcGIS Pro的最新版本,它引入了一些新的特性和功能,以提高用户的工作效率和数据分析能力。以下是ArcGIS…...

理解多线程看这一篇就够了
一、基本概念与关系 程序 程序是含有指令和数据的文件,静态地存储在磁盘等存储设备上。它是软件的实体,但未被激活。 进程 进程是程序的一次执行过程,是系统运行程序的基本单位。当程序被操作系统加载并执行时,就成为一个进程&a…...
解释“this”的工作原理,原型继承如何工作,以及如何实现手写JS继承。还包括Array对象自带的方法列举,以及如何使用闭包。
1:"this"的工作原理: this 关键字指向当前执行上下文的对象,也就是当前函数被调用时所在的对象。this 的值取决于函数的调用方式,不同的调用方式会导致 this 指向不同的对象:作为对象的方法调用,this 指向该对象作为普通函数调用,this 指向全局对象(浏览器中是 wind…...

汇智知了堂实力展示:四川农业大学Python爬虫实训圆满结束
近日,汇智知了堂在四川农业大学举办的为期五天的校内综合项目实训活动已圆满结束。本次实训聚焦Python爬虫技术,旨在提升学生的编程能力和数据分析能力,为学生未来的职业发展打下坚实的基础。 作为一家在IT教育行业享有盛誉的机构ÿ…...

C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...

RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...

聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...

听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别
【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而,传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案,能够实现大范围覆盖并远程采集数据。尽管具备这些优势…...