当前位置: 首页 > news >正文

24-Java策略模式 ( Strategy Pattern )

Java策略模式

    • 摘要
    • 实现
    • 范例

  • 策略模式的重心不是如何实现算法,而是如何组织、调用这些算法,从而让程序结构更加灵活,具有更好的维护性和扩展性。

  • 策略模式属于行为型模式

摘要

1. 意图

  • 针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。

2. 主要解决

  • 它将对象和行为分开,将行为定义为一个行为接口和具体的行为实现,说白了策略模式就是用来解决多个if判断的情况的。

3. 何时使用

  • 需要在运行时动态地改变对象的行为
  • 有多个算法可选,客户端需要根据不同的需要选择不同的算法
  • 一个类定义了多种行为,并且这些行为在类的方法中以多个条件语句的形式出现。这时候可以将每种条件分支转化为一个独立的策略

4. 如何解决

  • 将这些通用算法抽象出来

5. 关键代码

  • 策略接口、具体策略类和环境类

6. 应用实例

  • 做一批相机,分配中心需要根据相机的类型去找到不同的工人做相机
  • 电商购物的优惠计算

7. 优点

  • 松耦合:策略模式将不同的策略封装在独立的类中,与上下文对象解耦,增加了代码的灵活性和可维护性。
  • 易于扩展:可以通过添加新的策略类来扩展系统的功能,无需修改现有代码。
  • 符合开闭原则:对于新的策略,无需修改上下文对象,只需要实现新的策略接口即可。

8. 缺点

  • 类数量增多:每个具体策略都需要一个独立的类,如果策略较多,将导致类的数量增加。
  • 上层必须知道所有策略类:上层模块必须知道有哪些策略,并选择合适的策略进行使用,这与迪米特法则是相违背的,我只是想使用了一个策略,我凭什么就要了解这个策略呢?那要你的封装类还有什么 意义?这是原装策略模式的一个缺点。

9. 使用场景

  • 有多个相似的类,只有行为有差异的情况下,可以考虑使用策略模式.
  • 需要在运行时动态切换算法的情况下,可以使用策略模式.
  • 一个系统需要在不同时间应用不同的业务规则情况下,可以使用策略模式
  • 在一个系统中,有许多类需要根据某种规则进行排序,查找等操作的情况下,可以使用策略模式.

10. 注意事项

  • 如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题,否则日后的系统维护就会成为一个烫手山芋。

实现

在这里插入图片描述

Java策略模式通常包括以下三种角色:

  • Context(上下文):是策略模式中的核心类,用来管理具体策略实现类的创建,配置和执行,以及在运行时动态地选择具体的策略实现类.
  • Strategy(策略):是一个接口或抽象类,定义了策略实现类的通用方法和属性,具体策略实现类必须实现这些方法和属性.
  • ConcreteStrategy(具体策略):是策略接口的实现类,根据具体业务需求实现了策略接口定义的方法和属性.可以又多个具体策略实现类,Context类在运行时根据需要动态地选择具体的策略实现类.

范例

1. 支付策略接口(Strategy)

Strategy.java

package com.demo.gof;
public interface PaymentStrategy {/*** 支付** @param amount*/void pay(double amount);
}

2. 微信支付和支付宝支付策略类(ConcreteStrategy)

WechatPayment.java

package com.demo.gof;
public class WechatPayment implements PaymentStrategy {private String username;private String password;public WechatPayment(String username, String password) {this.username = username;this.password = password;}/*** 支付** @param amount*/@Overridepublic void pay(double amount) {System.out.println("微信支付:" + amount + "元");}
}

AliPayment.java

package com.demo.gof;
public class AliPayment implements PaymentStrategy{private String username;private String password;public AliPayment(String username, String password) {this.username = username;this.password = password;}/*** 支付** @param amount*/@Overridepublic void pay(double amount) {System.out.println("支付宝支付:" + amount + "元");}
}

3. 购物车类(Context)

ShoppingCart.java

package com.demo.gof;
public class ShoppingCart {private List<Item> itemList;private PaymentStrategy paymentStrategy;public ShoppingCart() {itemList = new ArrayList<>();}public void setPaymentStrategy(PaymentStrategy paymentStrategy) {this.paymentStrategy = paymentStrategy;}public void addItem(Item item){itemList.add(item);}public void removeItem(Item item){itemList.remove(item);}public double calculateTotal(){return itemList.stream().mapToDouble(Item::getPrice).sum();}public void pay(){paymentStrategy.pay(calculateTotal());}
}

4. 商品类

Item.java

package com.demo.gof;
@Data
public class Item {private String name;private double price;public Item(String name, double price) {this.name = name;this.price = price;}
}

5. 运行执行策略模式

Demo.java

package com.demo.gof;
public class Demo {public static void main(String[] args) {ShoppingCart shoppingCart = new ShoppingCart();Item item1 = new Item("item1",10);Item item2 = new Item("item2",10);shoppingCart.addItem(item1);shoppingCart.addItem(item2);shoppingCart.setPaymentStrategy(new AliPayment("aliPayUsername","aliPayPassword"));shoppingCart.pay();shoppingCart.setPaymentStrategy(new WechatPayment("wechatUsername","wechatPassword"));shoppingCart.pay();}
}

编译运行以上 Java 范例,输出结果如下

在这里插入图片描述

相关文章:

24-Java策略模式 ( Strategy Pattern )

Java策略模式 摘要实现范例 策略模式的重心不是如何实现算法&#xff0c;而是如何组织、调用这些算法&#xff0c;从而让程序结构更加灵活&#xff0c;具有更好的维护性和扩展性。 策略模式属于行为型模式 摘要 1. 意图 针对一组算法&#xff0c;将每一个算法封装到具有共…...

突破编程_C++_C++11新特性(模板的改进与细节)

1 模板右尖括号的改进 在 C11 之前&#xff0c;模板的解析和实例化过程中&#xff0c;右尖括号 > 的处理有时会导致一些意外的结果&#xff0c;特别是在嵌套模板或模板模板参数中。这是因为 C 编译器通常会试图“查看前方”来确定何时结束模板参数的列表&#xff0c;这有时…...

云原生消息流系统 Apache RocketMQ 在腾讯云的大规模生产实践

导语 随着云计算技术的日益成熟&#xff0c;云原生应用已逐渐成为企业数字化转型的核心驱动力。在这一大背景下&#xff0c;高效、稳定、可扩展的消息流系统显得尤为重要。腾讯云高级开发工程师李伟先生&#xff0c;凭借其深厚的技术功底和丰富的实战经验&#xff0c;为我们带…...

Node.js的事件驱动模型(非阻塞I/O)

Node.js的事件驱动模型是它能高效处理并发的关键。这个模型允许Node.js在单个线程上运行&#xff0c;同时通过非阻塞I/O操作来处理成千上万的并发连接。下面是对Node.js事件驱动模型的详细解释&#xff1a; 事件循环&#xff08;Event Loop&#xff09; 事件循环是Node.js事件…...

java过滤器Filter相关知识点汇总

1.Filter概述 Servlet Filter又称Servlet过滤器&#xff0c;它是在Servlet2.3规范中定义的&#xff0c;能够对Servlet容器传给Web资源的request对象和response对象执行检查和修改。 Filter不是Servlet&#xff0c;不能直接访问&#xff0c;其本身也不能生成request对象和resp…...

旅游景区公共广播 园区广播 公路服务区广播

旅游景区公共广播 园区广播 公路服务区广播 旅游景区公共广播 旅游景区公共广播(又称背景音乐)简称BGM&#xff0c;它的主要作用是掩盖噪声并创造一种轻松和谐的气氛&#xff0c;是一种创造轻松愉快环境气氛的音乐。掩盖环境噪声&#xff0c;创造与旅游景区相适应的气氛&#…...

Elastic Stack--09--ElasticsearchRestTemplate

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 spring-data-elasticsearch提供的APIQueryBuildersElasticsearchRestTemplate 方法ElasticsearchRestTemplate ---操作索引 ElasticsearchRestTemplate ---文档操作…...

论坛管理系统|基于Spring Boot+ Mysql+Java+B/S架构的论坛管理系统设计与实现(可运行源码+数据库+设计文档+部署说明+视频演示)

推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 目录 目录 前台功能效果图 管理员功能登录前台功能效果图 用户功能模块 系统功能设计 数据库E-R图设计 l…...

2022 Task 2 Max Sum of 2 integers sharing first and last digits

Task 2 There is an array A consisting of N integers. What’s the maximum sum of two integers from A that share their first and last digits? For example, 1007 and 167 share their first(1) and last(7) digits, whereas 2002 and 55 do not. Write a function: …...

【分布式websocket】聊天系统消息加密如何做

前言 先介绍一下对称加密算法&#xff0c;在介绍一下加密流程&#xff0c;然后是介绍一下查询加密消息的策略。然后结合现有技术架构然后去选型。 决定采用客户端解密。简而言之就是采用对称服务端加密。然后将加密内容存储到消息表的content字段。然后客户拉取content字段 然…...

网络建设与运维培训介绍和能力介绍

1.开过的发票 3.培训获奖的证书 4合同签署 5.实训设备...

3 种方法限制 K8s Pod 磁盘容量使用

容器在运行期间会产生临时文件、日志。如果没有任何配额机制&#xff0c;则某些容器可能很快将磁盘写满&#xff0c;影响宿主机内核和所有应用。 容器的临时存储&#xff0c;例如 emptyDir&#xff0c;位于目录/var/lib/kubelet/pods 下&#xff1a; /var/lib/kubelet/pods/ …...

05-ESP32-S3-IDF USART

ESP32-S3 IDF USART详解 USART简介 USART是一种串行通信协议&#xff0c;广泛应用于微控制器和计算机之间的通信。USART支持异步和同步模式&#xff0c;因此它可以在没有时钟信号的情况下&#xff08;异步模式&#xff09;或有时钟信号的情况下&#xff08;同步模式&#xff…...

安塔利斯升级php8

1、includes/classes/class.Database.php 255行 multi_query方法加返回类型 :bool query方法加返回类型&#xff1a;: mysqli_result|bool 2、includes/classes/class.Session.php on line 91 Optional parameter $planetID declared before required parameter $dpath is…...

Clickhouse MergeTree 原理(一)

作者&#xff1a;俊达 MergeTree是Clickhouse里最核心的存储引擎。Clickhouse里有一系列以MergeTree为基础的引擎&#xff08;见下图&#xff09;&#xff0c;理解了基础MergeTree&#xff0c;就能理解整个系列的MergeTree引擎的核心原理。 本文对MergeTree的基本原理进行介绍…...

【C语言】字符串函数上

&#x1f451;个人主页&#xff1a;啊Q闻 &#x1f387;收录专栏&#xff1a;《C语言》 &#x1f389;道阻且长&#xff0c;行则将至 前言 这篇博客是字符串函数上篇&#xff0c;主要是关于长度不受限制的字符串函数&#xff08;strlen,strcpy,strcat,strcm…...

Java集合基础知识总结(绝对经典)

List接口继承了Collection接口&#xff0c;定义一个允许重复项的有序集合。该接口不但能够对列表的一部分进行处理&#xff0c;还添加了面向位置的操作。 实际上有两种list&#xff1a;一种是基本的ArrayList&#xff0c;其优点在于随机访问元素&#xff0c;另一种是更强大的L…...

Linux:导出环境变量命令export

相关阅读 Linuxhttps://blog.csdn.net/weixin_45791458/category_12234591.html?spm1001.2014.3001.5482 Linux中的内建命令export命令用于创建一个环境变量&#xff0c;或将一个普通变量导出为环境变量&#xff0c;并且在这个过程中&#xff0c;可以给该环境变量赋值。 下面…...

案例--某站视频爬取

众所周知&#xff0c;某站的视频是&#xff1a; 由视频和音频分开的。 所以我们进行获取&#xff0c;需要分别获得它的音频和视频数据&#xff0c;然后进行音视频合并。 这么多年了&#xff0c;某站还是老样子&#xff0c;只要加个防盗链就能绕过。&#xff08;防止403&#xf…...

清华把大模型用于城市规划,回龙观和大红门地区成研究对象

引言&#xff1a;参与式城市规划的新篇章 随着城市化的不断推进&#xff0c;传统的城市规划方法面临着越来越多的挑战。这些方法往往需要大量的时间和人力&#xff0c;且严重依赖于经验丰富的城市规划师。为了应对这些挑战&#xff0c;参与式城市规划应运而生&#xff0c;它强…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

学校招生小程序源码介绍

基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码&#xff0c;专为学校招生场景量身打造&#xff0c;功能实用且操作便捷。 从技术架构来看&#xff0c;ThinkPHP提供稳定可靠的后台服务&#xff0c;FastAdmin加速开发流程&#xff0c;UniApp则保障小程序在多端有良好的兼…...

Element Plus 表单(el-form)中关于正整数输入的校验规则

目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入&#xff08;联动&#xff09;2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中&#xff0c;新增了一个本地验证码接口 /code&#xff0c;使用函数式路由&#xff08;RouterFunction&#xff09;和 Hutool 的 Circle…...

Web 架构之 CDN 加速原理与落地实践

文章目录 一、思维导图二、正文内容&#xff08;一&#xff09;CDN 基础概念1. 定义2. 组成部分 &#xff08;二&#xff09;CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 &#xff08;三&#xff09;CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 &#xf…...

docker 部署发现spring.profiles.active 问题

报错&#xff1a; org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)

前言&#xff1a; 在Java编程中&#xff0c;类的生命周期是指类从被加载到内存中开始&#xff0c;到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期&#xff0c;让读者对此有深刻印象。 目录 ​…...

基于Springboot+Vue的办公管理系统

角色&#xff1a; 管理员、员工 技术&#xff1a; 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能&#xff1a; 该办公管理系统是一个综合性的企业内部管理平台&#xff0c;旨在提升企业运营效率和员工管理水…...

redis和redission的区别

Redis 和 Redisson 是两个密切相关但又本质不同的技术&#xff0c;它们扮演着完全不同的角色&#xff1a; Redis: 内存数据库/数据结构存储 本质&#xff1a; 它是一个开源的、高性能的、基于内存的 键值存储数据库。它也可以将数据持久化到磁盘。 核心功能&#xff1a; 提供丰…...

pycharm 设置环境出错

pycharm 设置环境出错 pycharm 新建项目&#xff0c;设置虚拟环境&#xff0c;出错 pycharm 出错 Cannot open Local Failed to start [powershell.exe, -NoExit, -ExecutionPolicy, Bypass, -File, C:\Program Files\JetBrains\PyCharm 2024.1.3\plugins\terminal\shell-int…...