策略模式 详解 设计模式

策略模式

策略模式是一种行为型设计模式,它定义了一系列算法,将每个算法封装到具有共同接口的独立类中,并且使它们可以相互替换。 策略模式可以让算法的变化独立于使用算法的客户端。

主要解决: 在有多种算法相似的情况下,使用 if…else 所带来的复杂和难以维护。

结构

策略模式的主要角色如下:

  • 抽象策略(Strategy)类:这是一个抽象角色,通常由一个接口或抽象类实现。所有具体策略类都实现了该接口。
  • 具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现或行为
  • 环境/上下文(Context)类:持有一个策略类的引用,负责将客户端的请求委派给具体的策略对象

图例:

请添加图片描述

在 Java 中使用策略模式的写法:

  1. 定义策略接口:创建一个接口,用于定义所有具体策略类的公共行为
  2. 创建具体策略类:实现策略接口,并提供具体的算法实现。
  3. 创建上下文类:维护一个对策略接口的引用,并提供方法来设置和切换不同的具体策略类。
  4. 客户端使用:在客户端代码中,创建上下文对象,并设置具体的策略类,然后调用上下文对象的方法来执行具体的算法。
// 1. 定义策略接口
interface PaymentStrategy { void pay(double amount);
}// 2. 创建具体策略类
class AliPayStrategy implements PaymentStrategy {@Overridepublic void pay(double amount) {System.out.println("Paid " + amount + " via AliPay.");}
}class WeChatPayStrategy implements PaymentStrategy {@Overridepublic void pay(double amount) {System.out.println("Paid " + amount + " via WeChatPay.");}
}// 3. 创建上下文类
class PaymentContext {private PaymentStrategy paymentStrategy;public void setPaymentStrategy(PaymentStrategy paymentStrategy) {this.paymentStrategy = paymentStrategy;}public void makePayment(double amount) {paymentStrategy.pay(amount);}
}// 4. 客户端使用
public class Main {public static void main(String[] args) {PaymentContext paymentContext = new PaymentContext();// 使用支付宝支付paymentContext.setPaymentStrategy(new AliPayStrategy());paymentContext.makePayment(100.0);// 使用微信支付paymentContext.setPaymentStrategy(new WeChatPayStrategy());paymentContext.makePayment(50.0);}
}

代码中创建了策略接口 PaymentStrategy 和两个具体策略类 AliPayStrategyWeChatPayStrategy。然后,创建了上下文类 PaymentContext,它维护了一个对策略接口的引用,并提供了设置和执行具体策略的方法。最后,在客户端 Main 类中,创建了 PaymentContext 的实例,并设置了具体的支付策略,然后进行支付操作。

使用场景:

  • 当有多个相关的类只有行为或算法上稍有不同的情况下,可以考虑使用策略模式。它将算法的变化独立封装到各自的策略类中,易于扩展和维护。

  • 一个系统需要动态地在几种算法中选择一种时,可以将这些行为封装成不同的策略类,并在需要时动态切换。

  • 系统中各算法彼此完全独立,且要求对客户隐藏具体算法的实现细节时。

  • 一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现,可将每个条件分支移入它们各自的策略类中以代替这些条件语句

注意事项: 如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题。

混合模式是指在策略模式中引入了简单工厂模式或者享元模式等其他设计模式,来减少策略类的数量,简化系统的结构。

举例来说,假设一个系统有多种支付方式,除了支付宝支付和微信支付之外,还有银行卡支付、信用卡支付等多种支付方式。如果每种支付方式都对应一个具体的策略类,随着支付方式的增加,策略类的数量会急剧增加,导致类膨胀问题。为了解决这个问题,可以引入简单工厂模式,将支付方式的创建交给一个工厂类来完成;同时,如果某些支付方式具有相似的功能,可以使用享元模式来共享相同的部分,减少策略对象的数量。

代码案例:

// 1. 定义策略接口
interface PaymentStrategy { void pay(double amount);
}// 2. 创建具体策略类
class AliPayStrategy implements PaymentStrategy {@Overridepublic void pay(double amount) {System.out.println("Paid " + amount + " via AliPay.");}
}class WeChatPayStrategy implements PaymentStrategy {@Overridepublic void pay(double amount) {System.out.println("Paid " + amount + " via WeChatPay.");}
}class BankCardPayStrategy implements PaymentStrategy {@Overridepublic void pay(double amount) {System.out.println("Paid " + amount + " via BankCard.");}
}class CreditCardPayStrategy implements PaymentStrategy {@Overridepublic void pay(double amount) {System.out.println("Paid " + amount + " via CreditCard.");}
}// 3. 创建简单工厂类
class PaymentStrategyFactory {private static final Map<String, PaymentStrategy> strategies = new HashMap<>();static {strategies.put("AliPay", new AliPayStrategy());strategies.put("WeChatPay", new WeChatPayStrategy());// 可以添加更多支付方式的策略对象}public static PaymentStrategy getPaymentStrategy(String type) {return strategies.get(type);}
}// 4. 客户端使用
public class Main {public static void main(String[] args) {PaymentStrategy aliPayStrategy = PaymentStrategyFactory.getPaymentStrategy("AliPay");aliPayStrategy.pay(100.0);PaymentStrategy weChatPayStrategy = PaymentStrategyFactory.getPaymentStrategy("WeChatPay");weChatPayStrategy.pay(50.0);PaymentStrategy bankCardPayStrategy = PaymentStrategyFactory.getPaymentStrategy("BankCard");bankCardPayStrategy.pay(80.0);PaymentStrategy creditCardPayStrategy = PaymentStrategyFactory.getPaymentStrategy("CreditCard");creditCardPayStrategy.pay(120.0);}
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

物联网主机:为智能交通赋能

物联网&#xff08;IoT&#xff09;技术的发展为智能交通领域带来了许多创新的解决方案。而在物联网应用中&#xff0c;物联网主机起着关键的作用。本文将为大家介绍一款名为E6000的物联网主机&#xff0c;它是一种多协议、多接口的物联网主机&#xff0c;为智能交通系统的建设…

二维码门楼牌管理系统技术服务:革新城市标识管理的新篇章

文章目录 前言一、二维码门楼牌管理系统的诞生背景二、二维码门楼牌管理系统的技术优势三、二维码门楼牌管理系统的应用前景四、面临的挑战与问题五、结语 前言 在数字化、智能化的时代背景下&#xff0c;二维码门楼牌管理系统作为一种创新的技术服务&#xff0c;正逐渐改变着…

线程池学习

github看到一个项目&#xff08;GitHub - markparticle/WebServer: C Linux WebServer服务器&#xff09;&#xff0c;内部使用的一个线程池看着不错&#xff0c;拿来学习一下。 /** Author : mark* Date : 2020-06-15* copyleft Apache 2.0*/ #ifndef THREADPO…

【Excel PDF 系列】EasyExcel + iText 库实现 Excel 转换 PDF

你知道的越多&#xff0c;你不知道的越多 点赞再看&#xff0c;养成习惯 如果您有疑问或者见解&#xff0c;欢迎指教&#xff1a; 企鹅&#xff1a;869192208 文章目录 前言转换前后效果引入 pom 配置代码实现定义 ExcelDataVo 对象主方法EasyExcel 监听器 前言 最近遇到生成 …

【Android开发】01-第一个Android APP

一、改MainActivity class MainActivity : AppCompatActivity() {/*因Android的app有生命周期&#xff0c;故入口是OnCreate而不是main函数*/override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main…

Java教程:SpringBoot项目如何对接Nacos实现服务发现治理,配置管理

–Nacos大家都知道&#xff0c;不懂的可以去官网或者网上查阅一下&#xff0c;本次给大家讲解一下如何在SpringBoot项目中引入Nacos服务来进行服务治理与发现&#xff0c;配置管理等&#xff0c;在微服务当中是必不可少的&#xff0c;各个模块之间可以通过Feign远程调用&#x…

Python的循环结构练习

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 生命对某些人来说是美丽的&#xff0c…

爬取某牙视频

爬取页面链接&#xff1a;游戏视频_游戏攻略_虎牙视频 爬取步骤&#xff1a;点进去一个视频播放&#xff0c;查看media看有没有视频&#xff0c;发现没有。在xhr中发现有许多ts文件&#xff0c;但这种不是很长的视频一般都有直接的播放链接&#xff0c;所以目标还是找直接的链…

PYTHON 自动化办公:压缩图片(PIL)

1、介绍 在办公还是学习过程中&#xff0c;难免会遇到上传照片的问题。然而照片的大小限制一直都是个问题&#xff0c;例如照片限制在200Kb之内&#xff0c;虽然有很多图像压缩技术可以实现&#xff0c;但从图像处理的专业来说&#xff0c;可以利用代码实现 这里使用的库函数是…

基于正态分布的序列选择策略及其在因果关系和平衡定律中的应用

题目&#xff1a;基于正态分布的序列选择策略及其在因果关系和平衡定律中的应用 摘要&#xff1a; 本文提出了一种基于正态分布的序列选择策略&#xff0c;并将其应用于因果关系和平衡定律的研究中。通过对一个长度为1000的序列进行随机打乱&#xff0c;并选择使序列的方差和均…

1.亿级积分数据分库分表:总体方案设计

项目背景 以一个积分系统为例&#xff0c;积分系统最核心的有积分账户表和积分明细表&#xff1a; 积分账户表&#xff1a;每个用户在一个品牌下有一个积分账户记录&#xff0c;记录了用户的积分余额&#xff0c;数据量在千万级积分明细表&#xff1a;用户每次积分发放、积分扣…

【leetcode】 剑指 Offer学习计划(java版本含注释)(下)

目录 前言第十六天&#xff08;排序&#xff09;剑指 Offer 45. 把数组排成最小的数&#xff08;中等&#xff09;剑指 Offer 61. 扑克牌中的顺子&#xff08;简单&#xff09; 第十七天&#xff08;排序&#xff09;剑指 Offer 40. 最小的k个数&#xff08;简单&#xff09; 第…