行为型设计模式——策略模式

news2024/11/20 6:29:15

策略模式

策略模式非常简单,只需要将策略或者某个算法定义成一个类,然后传给需要使用的对象即可。**定义:**该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。例如在ArrayListsort()中,如果想按照你自己的想法排序数组中的对象,你需要实现Comparator并重写排序方法,这个就是将排序策略封装成了Comparator 对象。

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

  • 抽象策略(Strategy)类:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
  • 具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现或行为。
  • 环境(Context)类:持有一个策略类的引用,最终给客户端调用。

案例实现

【例】促销活动

大家都参加过双十一购物活动吧,假设京东商场的优惠策略有很多种,那么哪一种最实惠呢?例如满300减30为第一种策略,第二种为总价打九折,第三种为3000减600 优惠券一张,不与参与其他优惠,那么我们可以给出下面的类图,其中SalesMan为京东App:

在这里插入图片描述

代码:

首先定义京东App类,即上面的SalesMan类:

public class JDApp {
    private Strategy strategy;

    public double payment(Strategy strategy,double total){
        return strategy.calculatePrice(total);
    }

}

接着定义策略接口,具体的策略实现该接口即可,三种策略实现如下:

public interface Strategy {
    double calculatePrice(double total);
}

public class StrategyA implements Strategy{
    @Override
    public double calculatePrice(double total) {
        // 总价打九折
        System.out.println("策略A:总价打九折");
        return total*0.90;
    }
}

public class StrategyB implements Strategy{
    @Override
    public double calculatePrice(double total) {
        // 每满300减30,每满1000减200
        System.out.println("策略B:每满300减30,每满1000减200");
        int numK = (int)total / 1000;
        int num300 = (int)(total-numK*1000) / 300;
        total = total - numK*200 - num300*30;
        return total;
    }
}

public class StrategyC implements Strategy {
    @Override
    public double calculatePrice(double total) {
        // 3000减600 优惠券一张,不与参与其他优惠
        System.out.println("策略C:3000减600大额优惠券一张,不与参与其他优惠");
        if(total>=3000){
            return total-600;
        }else {
            return total;
        }
    }
}

最后,在客户端使用不同的策略,如下:

public class Main {
    public static void main(String[] args) {

        double total = 3200;

        JDApp jdApp = new JDApp();
        double straA = jdApp.payment(new StrategyA(), total);
        System.out.println(straA);

        double straB = jdApp.payment(new StrategyB(), total);
        System.out.println(straB);

        double straC = jdApp.payment(new StrategyC(), total);
        System.out.println(straC);
    }
}

输出结果:

策略A:总价打九折
2880.0
策略B:每满300减30,每满1000减200
2600.0
策略C:3000减600大额优惠券一张,不与参与其他优惠
2600.0

优点

  • 策略类之间可以自由切换

    由于策略类都实现同一个接口,所以使它们之间可以自由切换。

  • 易于扩展

    增加一个新的策略只需要添加一个具体的策略类即可,基本不需要改变原有的代码,符合“开闭原则“

  • 避免使用多重条件选择语句(if else),充分体现面向对象设计思想。

缺点

  • 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。
  • 策略模式将造成产生很多策略类,可以通过使用享元模式在一定程度上减少对象的数量。

使用场景

  • 一个系统需要动态地在几种算法中选择一种时,可将每个算法封装到策略类中。
  • 一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现,可将每个条件分支移入它们各自的策略类中以代替这些条件语句。
  • 系统中各算法彼此完全独立,且要求对客户隐藏具体算法的实现细节时。
  • 系统要求使用算法的客户不应该知道其操作的数据时,可使用策略模式来隐藏与算法相关的数据结构。
  • 多个类只区别在表现行为不同,可以使用策略模式,在运行时动态选择具体要执行的行为。

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

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

相关文章

【c++】list迭代器失效问题

目录 一、list iterator的使用 二、list的迭代器失效 一、list iterator的使用 对于list的迭代器的用法,可以将它看做一个指针(实际要更加复杂)来使用,该指针指向list中的一个节点。 【注意】 (1)begin和end为正向迭代器&#x…

【C语言刷题每日一题#牛客网HJ73】——计算日期到天数转换(给定日期,计算是该年的第几天)

目录 问题描述 思路分析 数据结构构建部分 计算部分 代码实现 结果测试 此问题解决方法不唯一,这里介绍的是一种使用数组和循环实现的简单办法 问题描述 思路分析 问题的要求是输入一个日期,计算这是当年的第几天——要解决这个问题,逻…

记录汇川:H5U与Fctory IO测试8

主程序: 子程序: IO映射 子程序: 出料程序 子程序: 重量程序 子程序: 自动程序 Fctory IO配置: HMI配置 实际动作如下: Fctory IO测试8

SPI接口协议

SPI接口协议 SPI(Serial Peripheral Interface)是由Motorola公司定义的接口协议标准,串行外设接口(SPI)是微控制器和外围IC(如传感器、 ADC、 DAC、移位寄存器、 SRAM等)之间使用最广泛的接口之一。SPI是一种同步、全双工、主从式接口&#x…

智慧农庄电商小程序(商城系统)

文章目录 项目简介商城功能项目结构技术选型后端使用的技术前端使用的技术 程序体验 项目简介 基于当前流行技术组合的前后端分离商城系统: SpringBoot2JpaMybatisPlusSpringSecurityjwtredisVue的前后端分离的商城系统, 包含商城、拼团、砍价、商户管理…

redis stream restTemplate消息监听队列框架搭建

整体思路 1. pom增加redis依赖&#xff1b; 2. 消息监听器&#xff0c;实现StreamListener接口&#xff0c;处理消息到达逻辑&#xff1b; 3. 将消息订阅bean及监听器注册到配置中&#xff1b; 1. pom <?xml version"1.0" encoding"UTF-8"?> <…

【MySQL】锁机制

文章目录 一、表级锁和行级锁二、排他锁和共享锁三、InnoDB行级锁行级锁间隙锁意向共享锁和意向排他锁 四、InnoDB表级锁五、死锁六、锁的优化建议 一、表级锁和行级锁 表级锁&#xff1a; 对整张表加锁。开销小&#xff0c;加锁快&#xff0c;不会出现死锁&#xff1b;锁粒度…

c++学习笔记-STL案例-机房预约系统1-准备工作

前言 准备工作包括&#xff1a;需求分析、项目创建、主菜单实现、退出功能实现 目录 1 机房预约系统需求 1.1 简单介绍 1.2 身份介绍 1.3 机房介绍 1.4 申请介绍 1.5 系统具体要求 1.6 预约系统-主界面思维导图 2 创建项目 2.1 创建项目 2.2 添加文件 ​编辑 3 创建…

VTK开发调试环境下载(VTK开发环境一步到位直接开发,无需自己配置编译 VS2017+Qt5.12.10+VTK)

一、无与伦比的优势 直接下载代码就可以调试的VTK代码仓库。 二、资源制作原理 这个资源根据VTK源码 编译出动态库文件 pdb lib dll 文件&#xff08; x64 debug &#xff09; 并将这两者同时放在一个代码仓库里&#xff0c;下载就能用。 三、使用方法&#xff08;vtk-so…

【hyperledger-fabric】部署Java应用远程访问智能合约

简介 首先是根据b站的视频 hyperledger-fabric【3】在 java 应用中访问合约 以及hyperledger-fabric【5】Java应用和私有数据&#xff0c;本文章主要讲述的是视频中我遇到的问题&#xff0c;以及相关知识点的总结。 遇到的问题 问题1&#xff1a;git clone下载下来的代码发现…

Unity Meta Quest 一体机开发(十三):【手势追踪】自定义交互事件 EventWrapper

文章目录 &#x1f4d5;教程说明&#x1f4d5;交互事件概述&#x1f4d5;自定义交互逻辑⭐方法一&#xff1a;Inspector 面板赋值⭐方法二&#xff1a;纯代码处理 此教程相关的详细教案&#xff0c;文档&#xff0c;思维导图和工程文件会放入 Spatial XR 社区。这是一个高质量…

XCTF:CatCatCat[WriteUP]

从题目中下载到一张图片和一个txt文件 编码的开头是&#xff1a;U2FsdGVkX1所以是rabbit加密 尝试使用密钥&#xff1a;91 密码不对&#xff0c;无法解密所以从图片下手 使用010Editor搜索图片文本内容 尝试搜索password、flag等敏感字体 直接拿到rabbit解密需要的密钥是&am…

【AI视野·今日Sound 声学论文速览 第四十四期】Tue, 9 Jan 2024

AI视野今日CS.Sound 声学论文速览 Tue, 9 Jan 2024 Totally 27 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Sound Papers DJCM: A Deep Joint Cascade Model for Singing Voice Separation and Vocal Pitch Estimation Authors Haojie Wei, Xueke Cao, Wenbo Xu…

移动光缆使用规定

移动光缆使用的规定&#xff1a; 1.1在移动光缆的施工过程中&#xff0c;其弯曲半径应该是移动光缆外径的15倍&#xff0c;并且不能小于20倍。 1.2在进行移动光缆敷设时&#xff0c;需要确保施加的拉力不超过移动光缆所允许的张力的80%。移动光缆的最大张力允许达到100%的限制…

Appium 自动化测试

1.Appium介绍 1&#xff0c;appium是开源的移动端自动化测试框架&#xff1b; 2&#xff0c;appium可以测试原生的、混合的、以及移动端的web项目&#xff1b; 3&#xff0c;appium可以测试ios&#xff0c;android应用&#xff08;当然了&#xff0c;还有firefoxos&#xff09;…

比亚迪:从低谷中涅槃,内功造就辉煌

修炼内功才能绽放光芒吗? 比亚迪用自己的奋斗史证明~ 只有经历低谷的洗礼&#xff0c;才能铸就属于自己的辉煌。 比亚迪这家公司的发展历程可谓是一部从战略转型到今天这个行业翘楚的奋斗史&#xff0c;真是跌宕起伏令人唏嘘。早期比亚迪从一个传统企业转型到汽车行业&#xf…

【Kafka-3.x-教程】-【五】Kafka-监控-Eagle

【Kafka-3.x-教程】专栏&#xff1a; 【Kafka-3.x-教程】-【一】Kafka 概述、Kafka 快速入门 【Kafka-3.x-教程】-【二】Kafka-生产者-Producer 【Kafka-3.x-教程】-【三】Kafka-Broker、Kafka-Kraft 【Kafka-3.x-教程】-【四】Kafka-消费者-Consumer 【Kafka-3.x-教程】-【五…

《ORANGE’S:一个操作系统的实现》读书笔记(二十八)文件系统(三)

上一篇文章记录了文件系统&#xff0c;我们将硬盘映像进行了分区&#xff0c;并且清楚了如何获取分区信息。但是硬盘驱动程序目前只能处理DEV_OPEN消息&#xff0c;这显然是不够的&#xff0c;这篇文章记录对硬盘驱动的完善&#xff0c;让它能够处理更多的消息&#xff0c;并且…

C++力扣题目110--平衡二叉树

给定一个二叉树&#xff0c;判断它是否是高度平衡的二叉树。 本题中&#xff0c;一棵高度平衡二叉树定义为&#xff1a; 一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;t…

YOLOv8 + openVINO 多线程数据读写顺序处理

多线程数据读写顺序处理 一个典型的生产者-消费者模型&#xff0c;在这个模型中&#xff0c;多个工作线程并行处理从共享队列中获取的数据&#xff0c;并将处理结果以保持原始顺序的方式放入另一个队列。 多线程处理模型&#xff0c;具体细节如下&#xff1a; 1.数据:数据里必…