23种策略模式之策略模式

news2024/11/15 14:00:01

23种策略模式之策略模式

文章目录

  • 23种策略模式之策略模式
    • 前言
    • 优缺点
    • 使用场景
    • 角色定义
    • UML
    • 模拟示例
    • 小结

前言

在软件开发中,设计模式是为了解决常见问题而提供的一套可重用的解决方案。策略模式(Strategy Pattern)是其中一种常见的设计模式,它属于行为型模式。该模式的核心思想是将不同的算法封装成独立的策略类,使得它们可以相互替换,而不影响客户端的使用。

策略模式与其他设计模式有一些明显的区别。与模板方法模式相比,策略模式强调算法的灵活性,允许在运行时切换不同的策略。与状态模式相比,策略模式更注重不同算法之间的替换性,而非状态的内部转换。

优缺点

优点
策略类之间相互独立,易于扩展和维护。

可以在运行时动态切换策略,灵活性高。

提供了一种可替代继承的方案,避免继承层次的臃肿。

缺点
客户端需要了解不同的策略类,增加了使用的复杂度。

策略模式增加了类的数量,可能会导致系统更加庞大。

使用场景

如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为
一个系统需要动态地在几种算法中选择一种
如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现
如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题

角色定义

  • 策略Context(上下文)

策略模式定义上下文角色本意是为了通过不同策略对象让上下文调用对应的算法或行为。

  • 策略抽象

策略抽象主要设定行为,定义策略需要具有哪些行为。

  • 策略实现

具体策略的实现,实现策略抽象行为具体细节。

UML

在这里插入图片描述

  • FruitMarket(策略抽象)
  • PapayaPeddler、KiwifruitPeddler、WatermelonPeddler(策略算法实现)
  • SellFruitsContext(策略Context)

模拟示例

//卖水果策略 上下文
public class SellFruitsContext{
	//水果市场策略抽象
    private FruitMarket fruitMarket;

    public SellFruitsContext() {
    }

    public SellFruitsContext(FruitMarket fruitMarket) {
        this.fruitMarket = fruitMarket;
    }
    //调用策略方法
    public void sellFruit(){
        this.fruitMarket.sellFruits();
    }
}
//水果市场 策略抽象
public interface FruitMarket {
    void sellFruits();
}
//策略实现者
public class KiwifruitPeddler implements FruitMarket {
    public void sellFruits() {
        System.out.println("卖猕猴桃咯,保熟!!");
    }
}

public class PapayaPeddler  implements FruitMarket {
    public void sellFruits() {
        System.out.println("卖木瓜咯,瓜保熟!!");
    }
}

public class WatermelonPeddler implements FruitMarket {
    public void sellFruits() {
        System.out.println("卖西瓜咯,瓜保熟!!");
    }
}
//定义类型枚举 通过 类型获取 对应的策略算法
public enum FruitEnum {
   KIWIFRUIT(1,KiwifruitPeddler.class),PAPAYA(2,PapayaPeddler.class),WATERMELON(3,WatermelonPeddler.class);
   //水果类型
    private Integer fruitType;
    //水果类型对应的策略算法
    private Class c;

    FruitEnum() {
    }

    FruitEnum(Integer fruitType, Class c) {
        this.fruitType = fruitType;
        this.c = c;
    }
    public FruitEnum getFruitEnumByType(Integer fruitType){
        for (FruitEnum value : FruitEnum.values()) {
            if(value.fruitType==fruitType)
                return value;
        }
        return null;
    }
}

小结

通过类型在枚举类获取对应策略算法实现类,将策略算法实现类传入策略上下文,通过策略上下文调用具体的策略算法。后期业务扩展可新增枚举数据添加策略算法实现类,完成对扩展业务的实现。

策略模式在代码重构的时候是很常见的,减少大量if else代码、增强代码扩展性、策略算法的灵活切换、避免单个条件重复判断,很多情况选择switch以及if else会比较多,但是随着业务复杂度业务代码量上来了,随之代码的扩展性以及可读性降低代码也显得极其臃肿,虽说对于每一种算法都要为其建立一种策略类,相对比较懒的程序员更愿意写if else,有时候也不要觉得策略算法实现类太多,因为策略算法的多少取决于你的业务复杂度,正是因为策略算法很多才体现出业务的复杂,才更需要用好策略模式。

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

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

相关文章

Mac配置环境变量不生效

Mac配置环境变量不生效 Mac中的环境变量介绍 Mac系统的环境变量,加载顺序为: /etc/profile /etc/paths ~/.bash_profile ~/.bash_login ~/.profile ~/.bashrc 当然/etc/profile和/etc/paths是系统级别的,系统启动就会加载,后面…

Linux驱动入门 —— 利用引脚号操作GPIO进行LED点灯

目录 一、字符设备驱动程序框架 编写驱动程序的步骤: 对于 LED 驱动,我们想要什么样的接口? LED 驱动能支持多个板子的基础:分层思想 二、Linux驱动如何指向一个GPIO 直接通过寄存器来操作GPIO 利用引脚号操作GPIO IMX6UL…

基于自动化脚本批量上传依赖到nexus内网私服

前言 因为某些原因某些企业希望私服是不能连接外网的,所以需要某些开源依赖需要我们手动导入到nexus中,尽管nexus为我们提供了web页面。但是一个个手动导入显然是一个庞大的工程。 对此我们就不妨基于脚本的方式实现这一过程。 预期效果 笔者本地仓库…

【Java】网络编程-UDP回响服务器客户端简单代码编写

这一篇文章我们将讲述网络编程中UDP服务器客户端的编程代码 1、前置知识 UDP协议全称是用户数据报协议,在网络中它与TCP协议一样用于处理数据包,是一种无连接的协议。 UDP的特点有:无连接、尽最大努力交付、面向报文、没有拥塞控制 本文讲…

为什么FPGA是战略芯片?

FPGA(Field Programmable Gate Array)是在PAL(可编程阵列逻辑)、GAL(通用阵列逻辑)等可编程器件的基础上进一步发展的产物,它是作为一种半定制电路而出现的,既解决了定制电路的不足&…

提升数据采集技能:用 Axios 实现的 Twitter 视频下载器全面解析

引入 在当今数据驱动的时代,高效的数据采集是实现成功数据科学项目的关键。数据采集不仅涉及到数据的获取,还包括数据的清洗、转换、存储和分析等多个环节。Twitter作为全球最大的社交媒体平台之一,蕴含着丰富的信息和海量的多媒体内容&…

计算机网络:数据链路层(网桥)

带你速通计算机网络期末 目录 一、冲突域和广播域 二、网桥介绍 三、网桥分类—―透明网桥 四、网桥分类―—源路由网桥 五、多接口网桥―—以太网交换机 总结 一、冲突域和广播域 冲突域:在同一个冲突域中的每一个节点都能收到所有被发送的帧。简单的说就是同一时间内只…

C# WPF上位机开发(内嵌虚拟机的软件开发)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 学习过halcon的同学都知道,它不仅有很多的图像算子可以使用,而且调试很方便。每一步骤的调试结果,都可以看到对…

WWW 指南-万维网联盟(World Wide Web)

WWW - 万维网联盟 WWW通常称为网络。 web是一个世界各地的计算机网络。 电脑在Web上使用标准语言沟通。 万维网联盟(W3C)制定了Web标准 什么是WWW? WWW 代表 World Wide Web(万维网)万维网常常被称为 网络网络是世界各地的计算机网络网络中…

Spark分布式内存计算框架

目录 一、Spark简介 (一)定义 (二)Spark和MapReduce区别 (三)Spark历史 (四)Spark特点 二、Spark生态系统 三、Spark运行架构 (一)基本概念 &#x…

博客社区资讯APP源码/开源知识付费社区小程序源码/资源社区源码/独有付费阅读+兼容安卓苹果

源码简介: 博客社区资讯APP源码,它是开源知识付费小程序源码,作为资源社区源码,它具有独有付费阅读兼容安卓苹果。它是Typecho后端的。 知识付费社区RuleApp多内容发布,后端基于Typoche博客程序开发带完整安装文档 竟…

互联网,我们的虚拟世界

同学们,你们知道互联网是干什么的吗?它就像一个虚拟的世界,让我们能够连接到任何地方,获取任何信息,就像你现在正在通过互联网阅读我的文章一样。 互联网 你们有没有想过,如果没有互联网,我们的…

借助3D文档控件Aspose.3D,用Java 创建 3D 场景

3D 场景是在计算机上显示 3D 形状的一种方式。在本指南中,我们将学习如何使用 Java 创建 3D 场景,而不需要任何特殊的 3D 软件。之后,我们将以FBX文件格式保存 3D 场景,这是共享 3D 内容的常见方式。那么,让我们开始吧…

BearPi Std 板从入门到放弃 - 先天神魂篇(3)(RT-Thread I2C设备)

简介 使用BearPi IOT Std开发板及其扩展板E53_SC1, SC1上有I2C1 的光照强度传感器BH1750 和 EEPROM AT24C02, 本次主要就是读取光照强度; 主板: 主芯片: STM32L431RCT6LED : PC13 \ 推挽输出\ 高电平点亮串口: Usart1I2C使用 : I2C1E53_SC1扩展板 : LE…

4G工业路由器物联网解决方案智慧储能系统

储能系统是用于电网和用户间起到电力缓冲和削峰填谷作用的电力管理平台。储能系统通常由电池、充电机、控制器、电能质量治理装置及监控系统组成。主要应用于可再生能源发电系统,电力需求侧响应,电动汽车充电等领域。 4G工业路由器是一款专门针对物联网…

winform使用CefSharp嵌入VUE网页并交互

1、NuGet添加CefSharp 如果下载慢或失败可以更新下载源 腾讯资源https://mirrors.cloud.tencent.com/nuget/华为资源https://repo.huaweicloud.com/repository/nuget/v3/index.json 2、将项目平台改为X64 3、在winform窗体添加cef using CefSharp; using CefSharp.WinForms; u…

Flink的容错机制

容错机制 容错:指出错后不影响数据的继续处理,并且恢复到出错前的状态。 检查点:用存档读档的方式,将之前的某个时间点的所有状态保存下来,故障恢复继续处理的结果应该和发送故障前完全一致,这就是所谓的检…

【C语言】操作符详解(三)

目录 逗号表达式 下标访问[ ],函数调用( ) 下标引用操作符[ ] 函数调用操作符() 逗号表达式 exp1,exp2,exp3,...expN 逗号表达式,就是用逗号隔开的多个表达式…

C# 提取PDF中指定文本、图片的坐标

获取PDF文件中文字或图片的坐标可以实现精确定位,这对于快速提取指定区域的元素,以及在PDF中添加注释、标记或自动盖章等操作非常有用。本文将详解如何使用国产PDF库通过C# 提取PDF中指定文本或图片的坐标位置(X, Y轴)。 ✍ 用于…

Linux---切换目录命令

1. 切换目录命令的使用 命令说明cd 目录切换到指定目录cd ~切换到当前用户的主目录cd ..切换到上一级目录cd .切换到当前目录cd -切换到上一次目录 注意: cd命令切换目录时,这个目录必须存在。cd 后面不写目录等价于cd ~ cd 目录效果图: cd ~效果图: cd ..效果图…