小侃设计模式(十三)-策略模式

news2024/11/25 14:33:04

1.概述

策略模式(Strategy Pattern)是一种比较简单的模式,它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。策略模式具有较强的实用性,当一个对象拥有很多行为,且这些行为大部分很类似,需要大量的if…else来进行区分,使用策略模式能够有效降低耦合,降低代码复杂度。本文将分析策略模式的原理及使用方式。

2.原理及使用

2.1 原理

策略模式的类图如下:
在这里插入图片描述

策略模式主要包含三个角色:

Strategy(抽象策略角色):定义所有支持的算法的公共接口,通常是接口;
StrategyA、StrategyB(具体策略角色):实现抽象策略中的操作,该类含有具体的算法;
Context(封装角色):它封装了高层模块对策略、算法的直接访问,封装了可能存在的变化,起承上启下的作用。

2.2 案例

鸡分为野鸡、圈养的鸡,不同的鸡有不同的行为,比如飞翔和叫,野鸡和圈养的鸡各不相同,圈养的鸡不会飞翔。传统的方式是定义一个基类Chicken,野鸡和家鸡分别继承Chicken,实现自己的方法。这其实是有问题的,明明家鸡不会飞,却要继承飞的方法,拥有这个行为。
如果用策略模式实现上述案例,如下:
在这里插入图片描述
代码如下:

public class Chicken {

    public FlyBehavior flyBehavior;

    public Chicken(FlyBehavior flyBehavior) {
        this.flyBehavior = flyBehavior;
    }

    /**
     * 类型
     */
    private String type;

    /**
     * 颜色
     */
    private String color;

    /**
     * 图片
     */
    private String image;

    /**
     * 年龄
     */
    private Integer age;


    public void eat() {
        System.out.println("鸡都吃五谷杂粮");
    }

    public void method() {
        flyBehavior.fly();
    }
}

public class Pheasant extends Chicken{

    public Pheasant(FlyBehavior flyBehavior) {
        super(flyBehavior);
    }

    public void method() {
        System.out.println("这是野鸡");
        flyBehavior.fly();
    }
}

public class HomeChicken extends Chicken {

    public HomeChicken(FlyBehavior flyBehavior) {
        super(flyBehavior);
    }

    public void method() {
        System.out.println("这是家养的鸡");
        flyBehavior.fly();
    }

}

public interface FlyBehavior {

    void fly();
}

public class FlyHigh implements FlyBehavior {

    @Override
    public void fly() {
        System.out.println("飞的又高又远!");
    }
}

public class CanNotFly implements FlyBehavior {

    @Override
    public void fly() {
        System.out.println("可惜这只鸡不会飞");
    }

}

public class Test {
    public static void main(String[] args) {
        FlyHigh flyHigh = new FlyHigh();
        CanNotFly canNotFly = new CanNotFly();

        HomeChicken homeChicken = new HomeChicken(canNotFly);
        homeChicken.method();

        System.out.println("------------------------");

        Pheasant pheasant = new Pheasant(flyHigh);
        pheasant.method();
    }
}

测试结果如下:
在这里插入图片描述

2.3 策略模式的优缺点

2.3.1 优点

1.扩展性良好,新增算法时,只需新增一个策略类即可,其它无需修改;
2.算法切换灵活:不同的策略类在使用时传入到封装角色中,可以灵活切换;
3.避免使用多重条件判断:使用策略模式能够有效减少代码中的if…else判断语句,增强程序可读性。

2.3.2 缺点

1.容易造成类爆炸:当策略过多时,策略类会有很多,不易复用;
2.所有的策略类都要对外暴露,违反迪米特法则。

3.小结

1.策略模式的关键是:分析项目中变化部分与不变部分,它的核心思想是:多用组合/聚合少用继承;用行为类组合,而不是行为的继承;
2.体现了“对修改关闭,对扩展开放”原则,客户端增加行为不用修改原有代码,只要添加一种策略(或者行为)即可,避免了使用多重转移语句(if…else if…else);
3.提供了可以替换继承关系的办法:策略模式将算法封装在独立的Strategy类中使得你可以独立于其Context改变它,使它易于切换、易于理解、易于扩展;
4.需要注意的是:每添加一个策略就要增加一个类,当策略过多是会导致类数目庞大。

4.参考文献

1.《设计模式之禅》-秦小波著
2.《大话设计模式》-程杰著
3.https://www.bilibili.com/video/BV1G4411c7N4-尚硅谷设计模式

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

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

相关文章

ARM学习扫盲篇(一):CPSRSPSR、LcacheDcache、w/parityw/ECC

1、CPSR&SPSR CPSR—程序状态寄存器(current program status register) SPSR—程序状态保存寄存器(saved program status register) Icache&Dcache icache用来缓存指令; dcache用来缓存数据,dcache用的前提是mmu要启动…

(续)SSM整合之SSM整合笔记(ContextLoaderListener)(P177-178)

目录 ContextLoaderListener 一 ContextLoaderListener 二 测试ContextLoaderListener 1 新建模块spring_listener com.atguigu 2. 导入依赖 3 .转web 4 .web.xml 5 springmvc.xml 6 .spring.xml 7 首页index.html 8 控制层 HelloController 9 service接口…

【24计算机考研】备考前必须了解的避坑小知识,建议收藏

前言 我们可能已经了解到最近两三年的考研趋势,疫情的原因,不断增加的二战三战考生,导致每年考研人数持续增长,那么,如何在相同的时间里,赶超你的竞争对手,避坑 绝对是很重要的。 考研将是一场…

【Spring】——9、如何指定初始化和销毁的方法?

📫作者简介:zhz小白 公众号:小白的Java进阶之路 专业技能: 1、Java基础,并精通多线程的开发,熟悉JVM原理 2、熟悉Java基础,并精通多线程的开发,熟悉JVM原理,具备⼀定的线…

(STM32)从零开始的RT-Thread之旅--SPI驱动ST7735(3)使用DMA

上一篇: (STM32)从零开始的RT-Thread之旅--SPI驱动ST7735(2) 上一篇完成了ST7735驱动的移植,并已经可以通过SPI在屏幕上显示字符了,这一章会把SPI修改为DMA的传输方式。由于RTT对于STM32H7的SPI的DMA传输方式目前支持的并不好,这…

Vuex3使用教程(待续)

Vuex定义 以下是Vue官网对于Vuex的定义: Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。 从官方定义上看: Vuex提供了一个全部组件…

Java注释:单行、多行和文档注释

注释是对程序语言的说明,有助于开发者和用户之间的交流,方便理解程序。注释不是编程语句,因此被编译器忽略。 Java入门基础视频教程,java零基础自学就选黑马程序员Java入门教程(含Java项目和Java真题) Ja…

【Django】Django4.1.2使用xadmin避坑指南(二)

上一篇【Django】Django4.1.2使用xadmin避坑指南调完后,还是继续有问题,没事,咱们继续,必须啃下硬骨头~ 文章目录环境问题一:if not ContentType._meta.installed:这一句报错:AttributeError: Options obje…

《深度学习进阶 自然语言处理》第八章:Attention介绍

文章目录8.1 Attention结构8.1.1 seq2seq存在的问题8.1.2 编码器的改进8.1.3 解码器的改进8.2 Attention的应用8.3 总结之前文章链接: 开篇介绍:《深度学习进阶 自然语言处理》书籍介绍 第一章:《深度学习进阶 自然语言处理》第一章&#xf…

SSH连接WSL2踩坑记录与增加端口转换规则,实现外网与WSL2的连接

SSH连接WSL2踩坑记录 文章目录SSH连接WSL2踩坑记录1. 在WSL里的操作2. ssh连接3. 可能出现的错误4. 再配置端口转发到WSL1. 在WSL里的操作 1.1 重装openssh-server sudo remove openssh-server # 如果已经安装了,建设先卸载 sudo apt install openssh-server…

Ansys Lumerical | 行波 Mach-Zehnder 调制器仿真分析

前言 本示例描述了行波 Mach-Zehnder 调制器的完整多物理场(电气、光学、射频)仿真,最后在INTERCONNECT中进行了紧凑模型电路仿真。计算了相对相移、光学传输、传输线带宽和眼图等关键结果。 综述 此示例中5毫米长的Si波导由5毫米长的Al共面…

SpringBoot SpringBoot 开发实用篇 5 整合第三方技术 5.24 SpringBoot 整合 RabbitMQ(topic 模式)

SpringBoot 【黑马程序员SpringBoot2全套视频教程,springboot零基础到项目实战(spring boot2完整版)】 SpringBoot 开发实用篇 文章目录SpringBootSpringBoot 开发实用篇5 整合第三方技术5.24 SpringBoot 整合 RabbitMQ(topic 模式)5.24.1 …

FL Studio2023水果编曲软件最新版安装教程

FL Studio中文版是知名的音乐制作软件,让你的计算机就像是全功能的录音室,软件包含13种虚拟音源,可同时录制64轨音频轨,FL Studio中文版拥有的漂亮的大混音盘,先进的创作工具,让你的音乐突破想象力的限制&a…

智能化油田建设规划

一、数字化油田-技术现状 数字化油田实现了设备的远程生产过程监控,使井场实现无人值守。所以目前的设备运行维护管理系统只能实现数据统计管理,并不能实现设备状态监控及远程维护及故障诊断。 1、数字化油田— 存在的问题 缺少设备状态在线监测系统&a…

第三章. 业务功能开发--用户登录安全退出

第三章. 业务功能开发--用户登录安全退出 1. 用户登录 需求: 用户在登录页面,输入用户名和密码,点击"登录"按钮或者回车,完成用户登录的功能.*用户名和密码不能为空*用户名或者密码错误,用户已过期,用户状态被锁定,ip受限 都不能登录成功*登录成功之后,所…

Android Jetpack之Lifecycle的使用及源码分析

Lifecycle生命周期感知型组件可执行操作来响应另一个组件(如 Activity 和 Fragment)的生命周期状态的变化。这些组件有助于您编写出更有条理且往往更精简的代码,此类代码更易于维护。 尤其是在Activity和Fragment在已经默认支持LifeCycle的情…

【第五部分 | JS WebAPI】3:DOM 节点操作

目录 | 节点操作 1-1 概述 2-1 获取父节点 3-1 获取子节点(获取所有子对象 不推荐) 3-2 获取子节点(获取所有子【元素节点】) 3-3 获取首尾子节点 4-1 获取兄弟节点 5-1 动态创建、添加节点 5-2 案例:评论区 …

性能测试_JMeter_connection timed out :connect

jmeter报错:failed:connection timed out :connect/java.net.BindException: Address already in use: connect java.net.BindException: Address already in use: connectat java.net.DualStackPlainSocketImpl.connect0(Native Method)at java.net.DualStackPlainSocketImpl…

Linux系统上安装软件

安装jdk,安装tomcat,安装Mysql 四种安装方式: 安装jdk 1.去这个网站上下载linux版本的jdk Java Archive Downloads - Java SE 8 2.在虚拟机中的服务器终端中输入ifconfig(注意不是ipconfig,而是ifconfig…

智慧机场解决方案-最新全套文件

智慧机场解决方案-最新全套文件一、建设背景二、建设思路三、建设方案四、获取 - 智慧机场全套最新解决方案合集一、建设背景 中国处在机场持续大规模建设过程中,政府也有意愿建设机场作为城市名片,经济持续增长会带来机场的持续建设;我国机…