妙解设计模式之策略模式
目录
- 策略模式的概念
- 生活中的例子
- 编程中的例子
- 软件工程中的实际应用
- 数据排序
- 文件压缩
- 支付方式
- 图形绘制
策略模式的概念
策略模式(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教育行业享有盛誉的机构ÿ…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...
基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...
MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...
04-初识css
一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...
有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...
