如何抄袭网站/厦门网络营销推广
在遥远的王国里,有三个重要的角色:国王策略模式、他的皇家顾问算法家族,以及年轻的骑士接口。国王策略模式统治着整个王国,他的职责是确保每一个编程问题都能找到最合适的解决方案。
有一天,王国遇到了一场危机。编程王国中的一条巨龙,名叫“复杂性”,不断地改变自己的形态和行为,让程序员们疲于应对。面对这种情况,国王策略模式召集了他的皇家顾问算法家族。
算法家族中的成员包括快排骑士、归并骑士和冒泡骑士,他们每一个都有独特的技能和解决问题的方法。国王策略模式知道,这些骑士们的力量需要得到充分发挥,但他们的行动必须有组织、有协调。
于是,国王策略模式召见了年轻的骑士接口。接口骑士是一个精通沟通与协调的角色,他能让不同的算法骑士在合适的时候出场,发挥各自的优势。
策略模式国王说:“年轻的接口骑士,你需要创建一个共同的接口,让所有的算法骑士都能遵循这个接口来行动。这样一来,我们就能在遇到不同情况时,根据需要选择最适合的骑士出战。”
接口骑士接受了任务,开始设计一个通用的接口。这个接口规定了所有算法骑士必须遵循的方法和行为。无论是快排骑士、归并骑士还是冒泡骑士,他们都必须实现这个接口,确保可以被无缝调用和替换。
很快,接口设计完成了,算法家族的每个成员都被重新训练,适应新的接口。这样一来,当巨龙复杂性再次来袭时,接口骑士可以迅速选择合适的算法骑士来对抗它。
例如,当龙表现出需要快速排序的特性时,接口骑士会召唤快排骑士;当巨龙需要稳定排序时,接口骑士会召唤归并骑士;而当情况简单时,冒泡骑士便会上场。
通过创建一个共同的接口,将不同的算法封装成独立的类,并使它们之间可以相互替换。
策略模式(Strategy Pattern)
策略模式(Strategy Pattern)是一种行为设计模式,它能够在运行时选择最适合的算法或行为,同时能够将算法族封装成独立的类,并使它们之间可以相互替换。这种模式是通过创建一个共同的接口,而后将不同的行为或算法封装在不同的策略类中实现的。每个策略类都遵循相同的接口,从而保持策略的独立性与互换性。
核心组件
- Strategy(策略接口):这是一个共同的接口,它定义了所有支持的算法的抽象方法。任何具体策略都必须实现这个接口。
- ConcreteStrategy(具体策略):实现策略接口的类,提供具体的算法实现。
- Context(上下文):用来维护对策略对象的引用,它可以定义一个接口,让策略对象根据上下文来选择适当的算法。
适用场景
- 多种算法或行为:
- 当一个类存在多种行为,且使用条件时,可以将这些行为封装成不同的策略。
- 避免使用多重条件选择语句:
- 使用策略模式可以避免使用多重条件选择语句,这样可以更容易维护和扩展。
- 需要动态地改变算法或行为:
- 当算法或行为需要经常改变时,使用策略模式可以提供更好的代码组织和重新使用。
- 行为变化独立于使用行为的客户:
- 需要将行为与客户代码解耦,使得行为的改变不会影响客户代码。
实现实例
以电商系统的支付功能为例,假设需要支持多种支付方式(如信用卡、PayPal、比特币等)。使用策略模式可以定义一个支付接口(PaymentStrategy),并为每种支付方式实现一个具体的策略类。上下文(PaymentContext)可以持有一个支付策略引用,根据不同的用户选择使用不同的支付策略:
策略接口(Strategy Interface)
这个接口定义了所有支持的算法或行为的抽象方法。每个具体的策略类都必须实现这个接口。
public interface PaymentStrategy {void pay(int amount); // 定义支付行为的方法,每种支付策略都需要实现这个方法
}
具体策略类(Concrete Strategy Classes)
这些类实现了策略接口,并提供了具体的算法实现。
public class CreditCardStrategy implements PaymentStrategy {public void pay(int amount) {System.out.println("Paid " + amount + " using Credit Card"); // 信用卡支付实现}
}public class PayPalStrategy implements PaymentStrategy {public void pay(int amount) {System.out.println("Paid " + amount + " using PayPal"); // PayPal支付实现}
}public class BitcoinStrategy implements PaymentStrategy {public void pay(int amount) {System.out.println("Paid " + amount + " using Bitcoin"); // 比特币支付实现}
}
上下文类(Context Class)
这个类用于维护对策略对象的引用。它可以定义一个方法让策略对象根据上下文来选择适当的算法。
public class PaymentContext {private PaymentStrategy strategy; // 维护一个对策略对象的引用public PaymentContext(PaymentStrategy strategy) {this.strategy = strategy; // 构造函数中设置策略对象}public void setStrategy(PaymentStrategy strategy) {this.strategy = strategy; // 允许在运行时改变策略}public void executePayment(int amount) {strategy.pay(amount); // 执行支付,具体行为取决于策略对象}
}
客户端代码(Client Code)
这部分代码演示了如何使用策略模式来改变对象的行为。
public class Client {public static void main(String[] args) {PaymentContext context = new PaymentContext(new CreditCardStrategy());context.executePayment(100); // 使用信用卡策略支付100context.setStrategy(new PayPalStrategy());context.executePayment(200); // 更改策略为PayPal并支付200context.setStrategy(new BitcoinStrategy());context.executePayment(300); // 更改策略为比特币并支付300}
}
优缺点
优点
- 封装性好:
- 策略模式将每个变化的策略封装到独立的类中,使得每个策略可以独立于客户端实现变化。
- 易于扩展:
- 策略模式提供了一种扩展机制,新的策略类可以很容易地添加进现有系统中。
- 避免使用多重条件选择语句:
- 策略模式允许动态地改变行为,客户端仅需更改配置,无需修改代码。
缺点
- 客户端必须知道所有策略:
- 客户端需要了解所有的策略类,并自行决定使用哪一个策略类。
- 策略族的增多:
- 随着策略族的增加,各种策略类的数目也会增加,每个策略都需要对外暴露,这就增加了系统的复杂性。
类图
+----------------+ +------------------+
| Context |-------->| Strategy |
+----------------+ +------------------+
| - strategy: | | + execute() |
| Strategy | +------------------+
| + setStrategy()| ^
| + execute() | |
+----------------+ ||+-------------------+--------+--------+----------------+| | | |
+---------------+ +-----------------+ +----------------+ +--------------+
|ConcreteStrategyA| |ConcreteStrategyB| |ConcreteStrategyC| | ... |
+---------------+ +-----------------+ +----------------+ +--------------+
| + execute() | | + execute() | | + execute() | | + execute() |
+---------------+ +-----------------+ +----------------+ +--------------+
总结
策略模式提供了一种灵活的方式来切换对象的行为,增强了代码的可维护性和扩展性。它帮助将行为封装为对象,可以在运行时互换,这使得它在需要支持多种行为的系统中非常有用。这种模式特别适合于那些算法或行为多样化的场景,可以有效地帮助系统遵守开闭原则,即对扩展开放,对修改关闭。通过策略模式,程序员可以方便地添加新的策略而不影响现有的系统,并且能够在运行时动态地改变对象的行为。
相关文章:

设计模式使用场景实现示例及优缺点(行为型模式——策略模式)
在遥远的王国里,有三个重要的角色:国王策略模式、他的皇家顾问算法家族,以及年轻的骑士接口。国王策略模式统治着整个王国,他的职责是确保每一个编程问题都能找到最合适的解决方案。 有一天,王国遇到了一场危机。编程王…...

ReactRouter v6升级的步骤
React Router v6 引入了一个 Routes 组件,它有点像 Switch ,但功能要强大得多。与 Switch 相比, Routes 的主要优势在于: <Routes> 中的所有 <Route> 和 <Link> 都是相对的。这导致在 <Route path> 和 &…...

【JVM实战篇】内存调优:内存问题诊断+案例实战
文章目录 诊断内存快照在内存溢出时生成内存快照MAT分析内存快照MAT内存泄漏检测的原理支配树介绍如何在不内存溢出情况下生成堆内存快照?MAT查看支配树MAT如何根据支配树发现内存泄漏 运行程序的内存快照导出和分析快照**大文件的处理** 案例实战案例1:…...

专业条码二维码扫描设备和手机二维码扫描软件的区别?
条码二维码技术已广泛应用于我们的日常生活中,从超市结账到公交出行,再到各类活动的入场验证,条码二维码的便捷性不言而喻,而在条码二维码的扫描识别读取过程中,专业扫描读取设备和手机二维码扫描软件成为了两大主要工…...

基于嵌入式Linux的高性能车载娱乐系统设计与实现 —— 融合Qt、FFmpeg和CAN总线技术
随着汽车智能化的发展,车载娱乐系统已成为现代汽车的标配。本文介绍了一个基于Linux的车载娱乐系统的设计与实现过程。该系统集成了音视频娱乐、导航、车辆信息显示等功能,旨在提供安全、便捷、丰富的驾驶体验。 1. 项目概述 随着汽车智能化的发展&…...

探索IP形象设计:快速掌握设计要点
随着市场竞争的加剧,越来越多的企业开始关注品牌形象的塑造和推广。在品牌形象中,知识产权形象设计是非常重要的方面。在智能和互联网的趋势下,未来的知识产权形象设计可能会更加关注数字和社交网络。通过数字技术和社交媒体平台,…...

泛微Ecology8明细表对主表赋值
文章目录 [toc]1.需求及效果1.1 需求1.2 效果2.思路与实现3.结语 1.需求及效果 1.1 需求 在明细表中的项目经理,可以将值赋值给主表中的项目经理来作为审批人员 1.2 效果 在申请人保存或者提交后将明细表中的人名赋值给主表中对应的值2.思路与实现 在通过js测…...

opencv—常用函数学习_“干货“_5
目录 十五、图像分割 简单阈值分割 (threshold) 自适应阈值分割 (adaptiveThreshold) 颜色范围分割 (inRange) 分水岭算法 (watershed) 泛洪填充 (floodFill) GrabCut算法 (grabCut) 距离变换 (distanceTransform) 最大稳定极值区域检测 (MSER) 均值漂移滤波 (pyrMean…...

JAVA零基础学习1(CMD、JDK、环境变量、变量和键盘键入、IDEA)
JAVA零基础学习1(CMD、JDK、环境变量、变量和键盘键入、IDEA) CMD常见命令配置环境变量JDK的下载和安装变量变量的声明和初始化声明变量初始化变量 变量的类型变量的作用域变量命名规则示例代码 键盘键入使用 Scanner 类读取输入步骤示例代码 常用方法处…...

Redis的安装配置及IDEA中使用
目录 一、安装redis,配置redis.conf 1.安装gcc 2.将redis的压缩包放到指定位置解压 [如下面放在 /opt 目录下] 3.编译安装 4.配置redis.conf文件 5.开机自启 二、解决虚拟机本地可以连接redis但是主机不能连接redis 1.虚拟机网络适配器网络连接设置为桥接模式…...

ubuntu 物理内存爆炸而不使用虚拟内存的问题
ubuntu 物理内存不足时有时候会不去使用虚拟内存,让虚拟内存空闲,而直接关闭占用内存的进程,如果在进行模型测试或训练时,就会导致训练或测试进程被杀死。 1. 修改 swappiness: cat /proc/sys/vm/swappiness sudo sysc…...

Python实现音频均衡和降噪
使用librosa库来读取音频文件,音频处理是一个复杂过程,这里只是简单的进行降噪和均衡。 import librosa import soundfile as sf def improve_audio_quality(input_file, output_file): # 读取音频文件 audio, sample_rate librosa.load(input_…...

【JavaScript 算法】贪心算法:局部最优解的构建
🔥 个人主页:空白诗 文章目录 一、贪心算法的基本概念贪心算法的适用场景 二、经典问题及其 JavaScript 实现1. 零钱兑换问题2. 活动选择问题3. 分配问题 三、贪心算法的应用四、总结 贪心算法(Greedy Algorithm)是一种逐步构建解…...

Azcopy Sync同步Azure文件共享
文章目录 Azcopy Sync同步文件共享一、工作原理二、安装 AzCopy在 Windows 上在 Linux 上 三、资源准备1. 创建源和目标 Azure 存储账户2. 创建源和目标文件共享3. 确定路径4. 生成源和目的存储账户的共享访问签名(SAS)令牌配置权限示例生成的 URL 四、A…...

单例模式 饿汉式和懒汉式的区别
单例模式(Singleton Pattern)是设计模式中最简单、最常见、最容易实现的一种模式。它确保一个类仅有一个实例,并提供一个全局访问点。单例模式主要有两种实现方式:饿汉式(Eager Initialization)和懒汉式&am…...

Python中的模块和包的定义以及如何在Python中导入和使用它们
在Python中,模块(Module)和包(Package)是组织代码以便重用和共享的基本单元。它们使得Python代码更加模块化,易于管理和维护。 模块(Module) 模块是一个包含Python代码的文件&…...

设计模式使用场景实现示例及优缺点(结构型模式——组合模式)
结构型模式 组合模式(Composite Pattern) 组合模式使得用户对单个对象和组合对象的使用具有一致性。 有时候又叫做部分-整体模式,它使我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以像处理简单元…...

《系统架构设计师教程(第2版)》第11章-未来信息综合技术-06-云计算(Cloud Computing) 技术概述
文章目录 1. 相关概念2. 云计算的服务方式2.1 软件即服务 (SaaS)2.2 平台即服务 (PaaS)2.3 基础设施即服务 (IaaS)2.4 三种服务方式的分析2.4.1 在灵活性2.4.2 方便性方 3. 云计算的部署模式3.1 公有云3.2 社区云3.3 私有云3.4 混合云 4. 云计算的发展历程4.1 虚拟化技术4.2 分…...

网络安全工作者如何解决网络拥堵
网络如同现代社会的血管,承载着信息的血液流动。然而,随着数据流量的激增,网络拥堵已成为不容忽视的问题,它像是一场数字世界的交通堵塞,减缓了信息传递的速度,扰乱了网络空间的秩序。作为网络安全的守护者…...

电脑显示mfc140u.dll丢失的修复方法,总结7种有效的方法
mfc140u.dll是什么?为什么电脑会出现mfc140u.dll丢失?那么mfc140u.dll丢失会给电脑带来什么影响?mfc140u.dll丢失怎么办?今天详细给大家一一探讨一下mfc140u.dll文件与mfc140u.dll丢失的多种不同解决方法分享! 一、mfc…...

ospf的MGRE实验
第一步:配IP [R1-GigabitEthernet0/0/0]ip address 12.0.0.1 24 [R1-GigabitEthernet0/0/1]ip address 21.0.0.1 24 [R1-LoopBack0]ip address 192.168.1.1 24 [ISP-GigabitEthernet0/0/0]ip address 12.0.0.2 24 [ISP-GigabitEthernet0/0/1]ip address 21.0.0.2 24…...

开发指南047-前端模块版本
平台前端框架内置了一个文件version.vue <template> <div> <br> 应用名称: {{name}} <br> 当前版本:{{version}} <br> 服务网关: {{gateway}} </div> </template> <scrip…...

c#中的字符串方法
Concat() String.Concat(字符串1 字符串n) 字符串拼接 Contains () 字符串1.Contains(字符串2) 字符串1是否包含字符串2返回布尔值 CopyTo() 字符串1.CopyTo(0,空数组,0,5); 从哪开始 复制到哪里 从哪开始存 存储的个数 tartsWith 字符串1.StartsWith("字符串") 以…...

成像光谱遥感技术中的AI革命:ChatGPT
遥感技术主要通过卫星和飞机从远处观察和测量我们的环境,是理解和监测地球物理、化学和生物系统的基石。ChatGPT是由OpenAI开发的最先进的语言模型,在理解和生成人类语言方面表现出了非凡的能力,ChatGPT在遥感中的应用,人工智能在…...

学习分布式事务遇到的小bug
一、介绍Seata 在处理分布式事务时我用到是Seata,Seata的事务管理中有三个重要的角色: TC (Transaction Coordinator) - 事务协调者:维护全局和分支事务的状态,协调全局事务提交或回滚。 TM (Transaction Manager) - 事务管理器…...

ElasticSearch学习之路
前言 为什么学ElasticSearch? 数据一般有如下三种类型: 结构化数据,如:MySQL的表,一般通过索引提高查询效率非结构化数据,如:图片、音频等不能用表结构表示的数据,一般保存到mong…...

(C++二叉树02) 翻转二叉树 对称二叉树 二叉树的深度
226、翻转二叉树 递归法: 交换两个结点可以用swap()方法 class Solution { public:TreeNode* invertTree(TreeNode* root) {if(root NULL) return NULL;TreeNode* tem root->left;root->left root->right;root->right tem;invertTree(root->l…...

高阶面试-mongodb
mongodb的特点,为什么使用他 nosql数据库,前端到后端到数据库,都是json,无模式,数据模型发生变更,不需要强制更新表结构,可以快速实现需求迭代。 天生分布式,高可用,处…...

MySQL数据库慢查询日志、SQL分析、数据库诊断
1 数据库调优维度 业务需求:勇敢地对不合理的需求说不系统架构:做架构设计的时候,应充分考虑业务的实际情况,考虑好数据库的各种选择(读写分离?高可用?实例个数?分库分表?用什么数据库?)SQL及索引:根据需求编写良…...

[短笔记] Ubuntu配置环境变量的最佳实践
结论: 不确定是否要设为系统,则先针对当前用户设,写~/.profile确定为系统级,写/etc/environment,注意无需export不推荐写在~/.bashrc(Ubuntu不推荐,理由见references) References&…...