设计模式基础概念(行为模式):策略模式

概述

策略模式是一种行为设计模式, 它能让你定义一系列算法, 并将每种算法分别放入独立的类中, 以使算法的对象能够相互替换

主要目的是通过定义相似的算法,替换if else 语句写法,并且可以随时相互替换

结构

在这里插入图片描述

示例

策略模式在 Java 代码中很常见。 它经常在各种框架中使用, 能在不扩展类的情况下向用户提供改变其行为的方式。

javax.servlet.http.HttpServlet: ​ service­()方法, 还有所有接受 Http­Servlet­Request和 Http­Servlet­Response对象作为参数的 do­XXX()方法。

识别方法: 策略模式可以 通过允许嵌套对象完成实际工作的方法,以及允许将该对象替换为不同对象的设置器来识别。

伪代码实现

strategies

策略(strategies)的定义:所有具体策略的通用接口, 它声明了一个上下文用于执行策略的方法

public interface PayStrategy {boolean pay(int paymentAmount);void collectPaymentDetails();
}

Concrete Strategies

具体策略 (Concrete Strategies): 实现上下文所用算法的各种不同变体。

PayByPayPal: 使用 PayPal 支付

public class PayByPayPal implements PayStrategy {@Overridepublic void collectPaymentDetails() {// todo}@Overridepublic boolean pay(int paymentAmount) {// todo}

PayByCreditCard: 使用信用卡支付

public class PayByCreditCard implements PayStrategy {@Overridepublic void collectPaymentDetails() {// todo}@Overridepublic boolean pay(int paymentAmount) {// todo}

Context

上下文 (Context): 维护指向具体策略的引用, 且仅通过策略接口与该对象进行交流。

public class Order {private int totalCost = 0;private boolean isClosed = false;// 提供一个计算的接口供客户端使用。public void processOrder(PayStrategy strategy) {strategy.collectPaymentDetails();// Here we could collect and store payment data from the strategy.}}

Client

客户端 (Client) 会创建一个特定策略对象并将其传递给上下文。

上下文则会提供一个设置器以便客户端在运行时替换相关联的策略。

public class Client {private static Map<Integer, Integer> priceOnProducts = new HashMap<>();private static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));private static Order order = new Order();private static PayStrategy strategy;static {priceOnProducts.put(1, 2200);priceOnProducts.put(2, 1850);priceOnProducts.put(3, 1100);priceOnProducts.put(4, 890);}public static void main(String[] args) throws IOException {while (!order.isClosed()) {int cost;String continueChoice;do {System.out.print("Please, select a product:" + "\n" +"1 - Mother board" + "\n" +"2 - CPU" + "\n" +"3 - HDD" + "\n" +"4 - Memory" + "\n");int choice = Integer.parseInt(reader.readLine());cost = priceOnProducts.get(choice);System.out.print("Count: ");int count = Integer.parseInt(reader.readLine());order.setTotalCost(cost * count);System.out.print("Do you wish to continue selecting products? Y/N: ");continueChoice = reader.readLine();} while (continueChoice.equalsIgnoreCase("Y"));if (strategy == null) {System.out.println("Please, select a payment method:" + "\n" +"1 - PalPay" + "\n" +"2 - Credit Card");String paymentMethod = reader.readLine();// Client creates different strategies based on input from user,// application configuration, etc.if (paymentMethod.equals("1")) {strategy = new PayByPayPal();} else {strategy = new PayByCreditCard();}}// Order object delegates gathering payment data to strategy object,// since only strategies know what data they need to process a// payment.order.processOrder(strategy);System.out.print("Pay " + order.getTotalCost() + " units or Continue shopping? P/C: ");String proceed = reader.readLine();if (proceed.equalsIgnoreCase("P")) {// Finally, strategy handles the payment.if (strategy.pay(order.getTotalCost())) {System.out.println("Payment has been successful.");} else {System.out.println("FAIL! Please, check your data.");}order.setClosed();}}}
}

应用场景

当你想使用对象中各种不同的算法变体, 并希望能在运行时切换算法时, 可使用策略模式。

策略模式让你能够将对象关联至可以不同方式执行特定子任务的不同子对象, 从而以间接方式在运行时更改对象行为。

当你有许多仅在执行某些行为时略有不同的相似类时, 可使用策略模式。

策略模式让你能将不同行为抽取到一个独立类层次结构中, 并将原始类组合成同一个, 从而减少重复代码。

如果算法在上下文的逻辑中不是特别重要, 使用该模式能将类的业务逻辑与其算法实现细节隔离开来。

策略模式让你能将各种算法的代码、 内部数据和依赖关系与其他代码隔离开来。 不同客户端可通过一个简单接口执行算法, 并能在运行时进行切换。

当类中使用了复杂条件运算符以在同一算法的不同变体中切换时, 可使用该模式。

策略模式将所有继承自同样接口的算法抽取到独立类中, 因此不再需要条件语句。 原始对象并不实现所有算法的变体, 而是将执行工作委派给其中的一个独立算法对象。

实现步骤

首先,从上下文类中找出修改频率较高的算法

其次,声明该算法所有变体的通用策略接口。将算法逐一抽取到各自的类中, 它们都必须实现策略接口。

之后,在上下文类中添加一个成员变量用于保存对于策略对象的引用

  • 然后提供设置器以修改该成员变量。
  • 上下文仅可通过策略接口同策略对象进行交互,
  • 如有需要还可定义一个接口来让策略访问其数据。

最后,客户端必须将上下文类与相应策略进行关联, 使上下文可以预期的方式完成其主要工作。

优缺点

策略模式优点:

  • 扩展性好,可以在不修改对象结构的情况下,为新的算法进行添加新的类进行实现;
  • 灵活性好,可以对算法进行自由切换;

策略模式缺点:

  • 使用策略类变多,会增加系统的复杂度。;
  • 客户端必须知道所有的策略类才能进行调用;

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

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

相关文章

功能组和功能组状态的概念关系和区别

在 AUTOSAR Adaptive Platform 中&#xff0c;功能组&#xff08;Function Group&#xff0c;FG&#xff09; 和 功能组状态&#xff08;Function Group State&#xff09; 是状态管理&#xff08;SM&#xff09;的核心概念&#xff0c;二者构成静态逻辑单元与动态行为模式的协…

力扣326:3的幂

力扣326:3的幂题目思路代码题目 给定一个整数&#xff0c;写一个函数来判断它是否是 3 的幂次方。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 整数 n 是 3 的幂次方需满足&#xff1a;存在整数 x 使得 n 3^x 思路 想要是三的幂次方的话将这个…

前瞻性技术驱动,枫清科技助力制造企业借助大模型完成生产力转化

麦肯锡于近期发布的《技术趋势展望2025》更清晰地定义了AI的角色与发展方向。报告在不止一个章节总结了基础模型加速小型化的趋势&#xff0c;多模态融合成为主流&#xff1a;企业的模型利用从追求“大而全”转向“小而精”&#xff0c;高效专用小模型成本降低90%的同时保持性能…

如何远程连接云服务器上mysql

一&#xff1a;使用系统命令查看端口占用# 查看MySQL进程及其端口sudo netstat -tlnp | grep mysql# 或者使用ss命令sudo ss -tlnp | grep mysql# 查看3306端口&#xff08;MySQL默认端口&#xff09;sudo netstat -tlnp | grep 3306出现如下信息&#xff0c;说明端口3306[root…

今日分享:C++模板(全详解)

&#x1f60e;【博客主页&#xff1a;你最爱的小傻瓜】&#x1f60e; &#x1f914;【本文内容&#xff1a;C模板 &#x1f60d; 】&#x1f914; -------------------------------------------------------------------------------------------------------------------…

ramdisk内存虚拟盘(一)——前世今生

1990 年代&#xff1a;前因——“硬盘太慢、驱动太多” 背景&#xff1a;早期 Linux 根文件系统要么在软盘、要么在 IDE 硬盘&#xff0c;内核把对应的软盘/IDE 驱动编进去即可顺利挂载。矛盾出现&#xff1a;随着 SCSI、PCMCIA、USB、RAID 控制器等百花齐放&#xff0c;如果把…

ETH持续上涨推动DEX热潮,交易活跃度飙升的XBIT表现强势出圈

BOSS Wallet 8月15日讯&#xff0c;随着ETH价格在过去24小时内强势拉升至4300美元&#xff0c;整个加密市场再度掀起涨势狂潮&#xff0c;链上交易活跃度空前高涨。其中&#xff0c;去中心化交易所平台迅速成为市场焦点&#xff0c;其平台活跃度与交易量双双上涨&#xff0c;吸…

Stand-In - 轻量级人物一致性视频生成 高保真视频人脸交换 ComfyUI工作流 支持50系显卡 一键整合包下载

Stand-In 是一个轻量级、即插即用的身份保护视频生成框架&#xff0c;只需要上传一张人物照片&#xff0c;加上一段提示词&#xff0c;即可生成高度一致性的高保真人物视频&#xff0c;人脸相似度和自然都几乎达到100%还原水平。 Stand-In 能把任何一张人脸&#xff08;甚至动漫…

vue3相关基础

1、ref和reactive的区别两者都是响应式数据的声明。Reactive只适用于非基本数据类型&#xff0c;如对象&#xff0c;数组等。而ref是兼容适用于reactive的的数据类型的以及其他数据&#xff0c;灵活性较高。ref声明的变量取值时需要.value。在<template></template>…

云手机存储和本地存储的区别

云手机存储通常指云存储&#xff0c;即数据存储在云端服务器&#xff0c;本地存储则是将数据存储在用户设备硬件中&#xff0c;主要区别体现在存储位置、访问方式、依赖条件等多个方面&#xff0c;具体如下&#xff1a;本地存储主要是将数据存储在用户自有设备的物理硬件中&…

【科研绘图系列】R语言绘制三维曲线图

文章目录 介绍 加载R包 数据下载 导入数据 数据预处理 画图 系统信息 参考 介绍 【科研绘图系列】R语言绘制三维曲线图 加载R包 library(tidyverse) library(ggsignif) library(RColorBrewer) library(dplyr) library(reshape2) library(grid

python常用包

以下按类别列举10个常用Python包&#xff0c;并以一句话概括其核心作用&#xff1a; 一、数据分析与科学计算 NumPy&#xff1a;提供高性能多维数组及数学运算&#xff0c;是数值计算的基础库。Pandas&#xff1a;通过DataFrame结构实现高效表格数据清洗、分析与处理。SciPy&am…

“ 船新版本 ”

在 GeeLark 最新版本中&#xff0c;增强了 AIGC 生成能力以及 AI 协助自定义任务开发功能&#xff0c;给用户优化构建从内容生产到运营自动化的完整技术链&#xff0c;为跨境电商及企业用户提供更完善的智能化解决方案&#xff0c;效率翻倍轻松出海。 AIGC 接入 MiniMax-Hailuo…

力扣 —— 二分查找

搜索插入位置 35. 搜索插入位置 - 力扣&#xff08;LeetCode&#xff09; 算法思想&#xff1a; class Solution(object):def searchInsert(self, nums, target):left0 rightlen(nums)-1while left < right :mid (left right) // 2if nums[mid] < target:left mid 1…

USB ADB 简介

概念 ADB 是 Android 平台的 调试桥接协议&#xff0c;允许主机&#xff08;PC&#xff09;与 Android 设备通信。 通过 ADB&#xff0c;开发者可以执行命令、调试应用、传输文件、访问 shell、调试 logcat 等。 ADB 运行在 USB 或 TCP/IP 上&#xff0c;但最常用的是 USB 连…

【Golang】:数据类型

目录 1. 基本数据类型 1.1 布尔类型 1.2 整数类型 1.3 浮点数类型 1.4 复数类型 1.5 字符类型 1.6 字符串类型 2. 类型转换 2.1 基本数据类型 → string 2.2 string → 基本数据类型 3. 常量 1. 基本数据类型 1.1 布尔类型 Go中的布尔类型取值为true或false&#…

旋钮键盘项目---foc讲解(开环)

这里就不过多的讲解什么原理&#xff0c;公式的变换了&#xff0c;感兴趣的可以看灯哥开源&#xff0c;讲解的非常好的。当然&#xff0c;更细致的讲解&#xff0c;也可以看b站其他教学。 我这里主要讲解我对于开环部分的理解&#xff0c;以及stm32代码的实现逻辑。可以看作是…

数据科学与计算:爬虫和数据分析案例笔记

案例 1&#xff1a;中国大学排名爬取与分析 一、任务描述 目标&#xff1a;爬取高三网中国大学排名一览表&#xff0c;提取学校名称、总分、全国排名、星级排名、办学层级等数据&#xff0c;并保存为 CSV 文件。 网址&#xff1a;2021中国的大学排名一览表_高三网 二、任务…

华测科技的3D GPR数据分析

很高兴得到了张总的支持&#xff0c;获得了他们雷达的数据&#xff0c;并写了雷达数据读取和转换文件。1 背景搜索后发现华测实力很强&#xff0c;因为他们可达到100km/h的时速&#xff0c;以前我只知道中电众益可以达到这个速度。2数据格式分析2.1 华测数据因为长时间不编程&a…

最长链(二叉树直径DFS)

题目描述现给出一棵N个结点二叉树&#xff0c;问这棵二叉树中最长链的长度为多少&#xff0c;保证了1号结点为二叉树的根。输入第1行为包含了一个正整数N&#xff0c;为这棵二叉树的结点数&#xff0c;结点标号由1至N。 接下来N行&#xff0c;这N行中的第i行包含两个正整数l[i]…