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

Java设计模式-策略模式

1. 策略模式简介

Java策略模式(Strategy Pattern)是一种行为型设计模式,‌它允许你在运行时改变对象的行为,而不改变其结构。这种模式的核心思想是将算法或行为封装在不同的对象中,然后让客户端在运行时选择合适的策略来执行。‌

这种模式使得算法可以独立于使用它的客户端变化,‌从而增强了系统的灵活性和可维护性。‌

2. 策略模式角色

在Java中,策略模式涉及以下几个核心角色:

  1. 策略接口(Strategy Interface):这是一个抽象类或接口,定义了执行某个任务的一系列可能的方法。例如,如果你正在创建一个排序算法的策略,那么这个接口可能会有 sort(int[] array) 这样的方法。

  2. 具体策略(Concrete Strategies):这是实现策略接口的类。每种具体的策略类都提供了一个具体的排序算法,比如快速排序、冒泡排序、归并排序等。

  3. 环境(Context):也称为上下文或客户端,它持有对策略对象的引用,并依赖于策略对象提供的服务。环境类有一个字段用于存储策略对象的实例,并通过这个引用调用相应的策略方法。

  4. 客户(Client):是使用策略的外部组件,它不需要关心具体是哪种策略,只需要通过环境来间接地使用策略功能。客户可以动态地设置或更换策略,以适应不同的需求。

3. 策略模式应用场景

Java策略模式是一种行为设计模式,它允许你定义一系列算法,并将它们封装起来,让算法的变化可以独立于使用算法的客户端而变化。这种模式通常用于需要在运行时选择算法的情况,例如:

  1. 游戏规则引擎:游戏中可以根据玩家的选择动态改变游戏规则,比如战斗、计分系统等。

  2. 用户界面组件:UI组件的行为可以根据用户的交互策略(如点击、滑动)进行切换。

  3. 金融计算:在交易策略中,不同的投资者可能会有各自的投资策略(如长期投资、短期交易),策略模式可以帮助管理和替换这些策略。

  4. 商品价格计算:不同的促销活动可以对应不同的价格计算策略(原价、折扣价等)。

  5. 数据分析:分析数据时,可以选择不同的统计分析策略(如平均值、中位数、频率分析)。

策略模式提供了一种灵活的方式来组织代码,使得算法的变化不会影响到客户端代码,提高了代码的可维护性和可扩展性。

4. 策略模式优点

Java策略模式允许你在运行时改变对象的行为或算法,而无需修改其实现类。其主要优点包括:

  1. 灵活性:通过策略模式,你可以动态地切换算法或行为,使得系统对变化更具适应性,提高了系统的扩展性和维护性。

  2. 开闭原则:遵循“开闭原则”,即对扩展开放,对修改关闭。新策略可以很容易地添加,而不影响已有的代码。

  3. 降低耦合:将算法封装在独立的对象中,降低了组件之间的耦合度,使得它们更容易替换和测试。

  4. 复用:相同的上下文可以根据需要选择不同的策略,避免了代码的重复编写。

  5. 便于理解和测试:因为策略是分离的,每个策略都有明确的功能,这有助于开发者理解代码,并方便单元测试。

5. 策略模式和工厂模式的区别

策略模式关注的是行为替换,而工厂模式关注的是对象实例化过程

策略模式中的策略对象通常是同质的,只是行为不同;工厂模式则返回各种不同的对象实例。

策略模式

  • 主要关注的是行为变化。它定义了一系列的算法,并将每一个算法封装到独立的对象中,然后由一个共同的接口来表示这些对象。在运行时,可以选择不同的策略实例来替换默认策略,实现了行为的替换和切换。
  • 适用于需要在运行时改变对象行为,或者针对不同的输入条件采用不同算法的情况。

工厂模式

  • 更侧重于对象的创建过程。它提供了一种创建对象的通用方式,隐藏了对象的具体创建细节。你可以通过工厂方法来指定创建哪种类型的对象,而无需关心其实现细节。
  • 常用于降低系统的耦合度,特别是当有许多不同类型的产品需要创建,且产品的创建规则复杂或者需要根据不同条件动态创建时。

6. 策略模式使用步骤

以下是Java策略模式的使用步骤:

  1. 创建策略接口(Strategy Interface):定义一系列相关的操作作为接口,让所有可能的策略都遵循相同的接口。
  2. 创建具体策略(Concrete Strategies):为每个不同的行为提供具体的实现类,它们都是策略接口的实现。
  3. 创建上下文类(Context):包含一个指向策略对象的引用,以及调用策略方法的方法。上下文是用户看到的部分,对策略的具体实现保持无知。
  4. 客户端选择并应用策略:在运行时,上下文根据业务需求选择并设置合适的策略。

7. 策略模式代码示例

7.1 定义策略接口

// 定义策略接口
interface PaymentStrategy {void pay(double amount);
}

7.2 创建具体策略

// 具体策略
class CreditCardPayment implements PaymentStrategy {@Overridepublic void pay(double amount) {System.out.println("Using credit card to pay: " + amount);}
}class CashPayment implements PaymentStrategy {@Overridepublic void pay(double amount) {System.out.println("Using cash to pay: " + amount);}
}

7.3 创建上下文

// 上下文
class ShoppingCart {private PaymentStrategy paymentStrategy;public void setPaymentStrategy(PaymentStrategy strategy) {this.paymentStrategy = strategy;}public void checkout(double total) {paymentStrategy.pay(total);}
}

7.4 测试实例代码

// 使用场景
public class Main {public static void main(String[] args) {ShoppingCart cart = new ShoppingCart();cart.setPaymentStrategy(new CreditCardPayment()); // 使用信用卡支付cart.checkout(500); // 输出 "Using credit card to pay: 500"// 可以动态更换策略cart.setPaymentStrategy(new CashPayment());cart.checkout(700); // 输出 "Using cash to pay: 700"}
}

8. 策略模式总结

综上,策略模式是一种行为型设计模式,‌它允许你在运行时改变对象的行为。‌这种模式的核心思想是将一系列可互换的算法封装成独立的策略类,‌并在运行时根据需要选择使用哪个策略。‌

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 无人机培训机构培训计划详解
  • Excel VBA批量获取文件夹内文件名及重命名文件教程
  • 音频进阶学习一——模拟信号和数字信号
  • 8.6.数据库基础技术-数据库的控制
  • LVS理论知识
  • 软件设计之MySQL(1)
  • Oracle(62)什么是内存优化表(In-Memory Table)?
  • 【数据结构】在链式存储结构上建立一棵二叉树的算法
  • 日撸Java三百行(day22:二叉树的存储)
  • Python | Leetcode Python题解之第335题路径交叉
  • Python实战项目:天气数据爬取+数据可视化(完整代码)
  • 【微信小程序】实现中英文切换
  • 100 Exercises To Learn Rust 挑战!准备篇
  • 掌握网络数据的钥匙:Python Requests-HTML库深度解析
  • AI秘境-墨小黑奇遇记 - 初体验(一)
  • [译] React v16.8: 含有Hooks的版本
  • ABAP的include关键字,Java的import, C的include和C4C ABSL 的import比较
  • Android系统模拟器绘制实现概述
  • Debian下无root权限使用Python访问Oracle
  • Django 博客开发教程 8 - 博客文章详情页
  • Facebook AccountKit 接入的坑点
  • Hibernate最全面试题
  • JS题目及答案整理
  • spring-boot List转Page
  • Vue2 SSR 的优化之旅
  • 关于字符编码你应该知道的事情
  • 湖南卫视:中国白领因网络偷菜成当代最寂寞的人?
  • 每天10道Java面试题,跟我走,offer有!
  • 如何用vue打造一个移动端音乐播放器
  • 深度学习中的信息论知识详解
  • 使用 Docker 部署 Spring Boot项目
  • 物联网链路协议
  • 小程序button引导用户授权
  • 一天一个设计模式之JS实现——适配器模式
  • 用Node EJS写一个爬虫脚本每天定时给心爱的她发一封暖心邮件
  • 做一名精致的JavaScripter 01:JavaScript简介
  • LevelDB 入门 —— 全面了解 LevelDB 的功能特性
  • 从如何停掉 Promise 链说起
  • 东超科技获得千万级Pre-A轮融资,投资方为中科创星 ...
  • 积累各种好的链接
  • 如何用纯 CSS 创作一个菱形 loader 动画
  • ​​​​​​​GitLab 之 GitLab-Runner 安装,配置与问题汇总
  • ​1:1公有云能力整体输出,腾讯云“七剑”下云端
  • ​LeetCode解法汇总2304. 网格中的最小路径代价
  • # Redis 入门到精通(七)-- redis 删除策略
  • #我与Java虚拟机的故事#连载06:收获颇多的经典之作
  • $NOIp2018$劝退记
  • %3cscript放入php,跟bWAPP学WEB安全(PHP代码)--XSS跨站脚本攻击
  • (el-Transfer)操作(不使用 ts):Element-plus 中 Select 组件动态设置 options 值需求的解决过程
  • (ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY)讲解
  • (附源码)springboot 智能停车场系统 毕业设计065415
  • (附源码)ssm基于jsp的在线点餐系统 毕业设计 111016
  • (三)Pytorch快速搭建卷积神经网络模型实现手写数字识别(代码+详细注解)
  • (删)Java线程同步实现一:synchronzied和wait()/notify()
  • (转)linux自定义开机启动服务和chkconfig使用方法