用策略模式优化代码的实例

2023-05-16

实例一:

利用利用策略模式实际开发中 if else 条件判断过多的问题,条件少还好,一旦 else if 过多这里的逻辑将会比较混乱,并很容易出错。
比如:在这里插入图片描述
刚开始条件较少,也就没管那么多直接写的;现在功能多了导致每次新增一个 else 条件都得仔细核对,生怕影响之前的逻辑。

重构之后这里的结构如下:在这里插入图片描述
最后直接变为两行代码,简洁了许多。

而之前所有的实现逻辑都单独抽取到其他实现类中。在这里插入图片描述拆分后的条件执行语句在这里插入图片描述
这样每当需要新增一个 else 逻辑,只需要新增一个类实现同一个接口便可完成。每个处理逻辑都互相独立互不干扰。在这里插入图片描述
按照目前的实现画了一个草图。

整体思路如下:

定义一个 InnerCommand 接口,其中有一个 process 函数交给具体的业务实现。
根据自己的业务,会有多个类实现 InnerCommand 接口;这些实现类都会注册到 Spring Bean 容器中供之后使用。
通过客户端输入命令,从 Spring Bean 容器中获取一个 InnerCommand 实例。
执行最终的 process 函数。
主要想实现的目的就是不在有多个判断条件,只需要根据当前客户端的状态动态的获取 InnerCommand 实例。

从源码上来看最主要的就是 InnerCommandContext 类,他会根据当前客户端命令动态获取 InnerCommand 实例。在这里插入图片描述第一步是获取所有的 InnerCommand 实例列表。
根据客户端输入的命令从第一步的实例列表中获取类类型。
根据类类型从 Spring 容器中获取具体实例对象。
因此首先第一步需要维护各个命令所对应的类类型。
在这里插入图片描述所以在之前的枚举中就维护了命令和类类型的关系,只需要知道命令就能知道他的类类型。

这样才能满足只需要两行代码就能替换以前复杂的 if else,同时也能灵活扩展。

InnerCommand instance = innerCommandContext.getInstance(msg);
instance.process(msg) ;

注:如果是springboot工程在获取上下文中的bean的时候可以通过如下方式:
方法一:

新建util类,实现ApplicationContextAware,重写setApplicationContext方法。这个方式下,工具类也被注册成了Bean,既然这样,那就必须确保该类能被Spring自动扫描到。

@Component
public class SpringContextUtils implements ApplicationContextAware {
 
    private static ApplicationContext applicationContext;
 
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SpringContextUtils.applicationContext = applicationContext;
    }
 
    public static <T> T getBean(Class<T> cls) {
        if (applicationContext == null) {
            throw new RuntimeException("applicationContext注入失败");
        }
        return applicationContext.getBean(cls);
    }
 
    public static Object getBean(String name) {
        if (applicationContext == null) {
            throw new RuntimeException("applicationContext注入失败");
        }
        return applicationContext.getBean(name);
    }
 
    public static <T> T getBean(String name, Class<T> cls) {
        if (applicationContext == null) {
            throw new RuntimeException("applicationContext注入失败");
        }
        return applicationContext.getBean(name, cls);
    }
 
    public static HttpServletRequest getRequest() {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder
            .getRequestAttributes();
        return requestAttributes == null ? null : requestAttributes.getRequest();
    }
}

方式二:

我想要的工具类,往往会部署在公共jar中,一般情况下不能被SpringBoot程序扫描到。所有就有手动注入上下文的方式。

@Slf4j
public class SpringUtils {
 
    private SpringUtils() {
    }
 
    private static ApplicationContext context = null;
 
    /**
     * 初始化Spring上下文
     *
     * @param ctx 上下文对象
     */
    public static void initContext(ApplicationContext ctx) {
        if(ctx == null) {
            log.warn("ApplicationContext is null.");
            return;
        }
        context = ctx;
    }
 
 
    /**
     * 根据类型获取Bean
     *
     * @param cls Bean类
     * @param <T> Bean类型
     * @return Bean对象
     */
    public static <T> T getBean(Class<T> cls) {
        return context == null ? null : context.getBean(cls);
    }
 
    /**
     * 根据名称获取Bean
     *
     * @param name Bean名称
     * @return Bean对象
     */
    public static Object getBean(String name) {
        return context == null ? null : context.getBean(name);
    }
 
    /**
     * 根据Bean名称和类获取Bean对象
     *
     * @param name Bean名称
     * @param cls Bean类
     * @param <T> Bean类型
     * @return Bean对象
     */
    public static <T> T getBean(String name, Class<T> cls) {
        return context == null ? null : context.getBean(name, cls);
    }
}

此种方式不用实现ApplicationContextAware接口,但是需要手动设置上下文。所以在程序入口处,需要调用initContext方法,完成上下文的初始化。

public static void main(String[] args) {
    ApplicationContext context = SpringApplication.run(YCloudsServiceBApplication.class, args);
    SpringUtils.initContext(context);
}

下面展示springboot实例:

实例二:(Spring Boot 工程实例)

springUtil类如上已经建好,接口ContractStrategy和其实现类MainContractStrategy和RelieveContractStrategy类似上面实例,这里不再粘出来。下面是Enum类:

public enum ContractValidateEnum {
  
  MAIN(1,MainContractStrategy.class,"主协议校验"),
  RELIEVE(2,RelieveContractStrategy.class,"解除协议校验");
  
  private int index;
  
  private Class<? extends ContractStrategy> strategy;
  
  private String info;
  
  ContractValidateEnum(int index,Class<? extends ContractStrategy> strategy, String info) {
    this.index = index;
    this.strategy = strategy;
    this.info = info;
  }
  
  /**
   * 根据index返回对应的enum
   *
   * @param index
   * @return
   */
  public static ContractValidateEnum fromIndex(int index) {
    for (ContractValidateEnum b : ContractValidateEnum.values()) {
      if (b.getIndex() == index) {
        return b;
      }
    }
    return MAIN;
  }
  
  /**
   * @return the index
   */
  public int getIndex() {
    return index;
  }


  /**
   * @return the info
   */
  public String getInfo() {
    return info;
  }

  /**
   * @return the strategy
   */
  public Class<?> getStrategy() {
    return strategy;
  }

}

然后是Context 类,他会根据当前客户端命令动态获取 strategy实例。

public class ContractValidateContext {
  
  public static ContractStrategy getStrategyInstance(ContractValidateEnum command){
    return (ContractStrategy) SpringUtil.getBean(command.getStrategy());
  }
}

这里直接在Enum里面放的Class<? extends ContractStrategy>可以简化Context里面代码,当然也可以参照实例一里面放String类型的实现类的名字,再根据Class.forName()来实现。
在使用的时候直接这样即可:

strategy = ContractValidateContext.getStrategyInstance(ContractValidateEnum.MAIN);
strategy.execValidate("参数");

注:本例主要是为了解决简单的策略模式不断新建对象造成的开销,这样用springBean配合静态Util类来管理实例,节省开销,提高系统性能,简化代码。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

用策略模式优化代码的实例 的相关文章

  • 嵌入式有哪些发展方向?

    想学习单片机的同学可以关注 私信我或者在评论区回复我要入门 最近几年经过移动互联网 物联网的高速发展 xff0c 嵌入式技术在我们生活中随处可见 xff0c 在通讯 网络 工控 医疗 电子等领域发挥着越来越重要的角色 xff1b 随着对嵌入
  • 公式截取神器:将文献中的公式快速粘贴进word:

    一共需要两个软件 mathpix snipping tool 负责对公式截屏 然后自动转化为LaTex公式语法 AxMath 负责将LaTex语法转化为word里可显示的公式 作用与MathType一样 但个人感觉这个软件更好用 而且还是国
  • ubuntu安装HDF5 1.10.4 以及对应的python hdf5包

    1 安装HDF5 1 10以及对应的python hdf5的包 xff08 HDF5 1 10 4安装具体可参考其他博客 xff09 2 使用命令行环境变量安装对应的python hdf5包 xff0c HDF5 DIR 61 usr lo
  • Redis相关知识点整理

    文章目录 前言一 Redis基本数据类型StringHashListSetSort Set xff08 zset xff09 二 键值 xff08 key xff09 的常用操作三 Redis持久化方式3 1 持久化方式之RDB3 2 持久
  • html5基础入门知识(干货)

    一 什么是html 用来描述网页的语言 超文本标记语言 不是编程 xff0c 而是一种标记语言 使用标记标签来描述网页等等 我们只需记住html就是用标记标签来描述网页 xff0c xff08 网页是前端哦 xff0c 平时你们听过的c c
  • Matlab使用过程中内存不足问题的总结

    做图像处理的 xff0c 对matlab这工具软件一定不会陌生 xff0c 他的高集成度为图像处理提供了很大的方便 xff0c 但我们在使用时难免会出现内存不足的问题 xff0c 2 3G的内存还不够处理一次简单图像 xff0c 这确实很恐
  • VIO系统介绍

    VIO xff08 visual inertial odometry xff09 即视觉惯性里程计 xff0c 有时也叫视觉惯性系统 xff08 VINS xff0c visual inertial system xff09 xff0c 是
  • VINS-MONO概述

    VINS Mono是HKUST的Shen Shaojie团队开源的一套Visual Inertial融合定位算法 xff0c https github com HKUST Aerial Robotics VINS Mono xff0c 是用
  • 主流VIO框架分析及VINS部分解析

    本文为搜集的资料整理 xff1a C0包含位姿和运动信息 xff1b 对于T0来说 xff0c 不仅受rv10 rv11的视觉影响 xff0c 也受rb01的IMU的影响 上述方式繁琐 xff0c 故引入因子图 xff0c 便于思路梳理和理
  • evo评测VINS-MONO---TUM数据集

    为了想测试室外场景下VINS MONO定位情况 xff0c 室外环境的KITTY数据集因无时间戳 xff0c EVO测评较困难 故选择TUM数据集 xff0c outdoors1 8 户外 xff1a 在校园内的室外场景拍摄 xff0c 但
  • ROS编译错误:Could not find a package configuration file provided by “XXX“

    解决 xff1a 系统提示缺少什么包 xff0c 就安装什么包即可 xff1a sudo apt get install ros noetic xff0c 依据自己的系统和出错提示更改相关内容 示例 xff1a 1 xff09 CMake
  • ZED2运行VINS-MONO初试

    上篇博客 xff0c 已经完成ZED2的标定 xff0c 获取相关标定参数 xff0c 将在此基础上进行VINS的相关修改 xff0c 实现使用ZED2运行VINS MONO 一 VINS MONO环境搭建 因为系统环境从ubuntu18
  • ZED2双目相机运行VINS-FUSION初试

    基于ZED2运行VINS MONO的经验 xff0c 在运行VINS FUSION前有几点tips想跟大家分享 xff0c 应该能在运行的过程中避免一些踩坑吧 TIPs 1 xff09 关于zed2标定 开始使用Kalibr进行相机单目 双
  • VINS Fusion GPS融合部分

    概述 VINS Fusion在VINS Mono的基础上 xff0c 添加了GPS等可以获取全局观测信息的传感器 xff0c 使得VINS可以利用全局信息消除累计误差 xff0c 进而减小闭环依赖 局部传感器 如相机 xff0c IMU x
  • STM32烧录一次后无法再次烧录

    STM32烧录一次后无法再次烧录 本人是使用cubemx配置stm32 xff0c 在配置sys时没有配置Debug xff0c 所以会导致程序只可以烧录一次的情况 xff0c 再次烧录会发生无法找到芯片的情况 解决方法是将单片机reset
  • Vins-fusion gps融合 KITTY数据集测试

    下载kitti数据集 下载kitti数据集和真值poses的00 txt以及sequences文件00序列的times txt xff0c xff08 全网找了好久 xff0c 最后不得已翻墙从官网down下来的 xff09 代码修改 xf
  • Vins-fusion GPS融合部分测试(自己的数据ZED+RTK)

    经过前一段时间的积累 xff0c 目前暂时成功实现了用自己的数据测试实现Vins fusion 43 GPS融合 xff0c 其实放在数据采集处理上的时间比较多 xff0c 踩了很多坑 xff0c 效果在一些部分还不是很好 xff0c 后期
  • Ceres Solver实例分析

    ceres简介 Ceres solver 是谷歌开发的一款用于非线性优化的库 xff0c 在谷歌的开源激光雷达slam项目cartographer中被大量使用 本篇博客结合相关实例介绍一下 Ceres库 的基本使用方法 xff1a 使用Ce
  • MSCKF算法简介

    感谢 xff1a 紫薯萝卜 https zhuanlan zhihu com p 76341809 论文 xff1a https arxiv org abs 1712 00036 代码 xff1a https github com Kuma
  • API函数详解:CreateSemaphore函数

    Windows API函数 Visual Basic 语法格式声明Declare Function CreateSemaphore Lib 34 kernel32 34 Alias 34 CreateSemaphoreA 34 lpSema

随机推荐

  • java 专业英语词汇

    abstract 关键字 抽象 39 bstr kt access vt 访问 存取 39 kses n 入口 使用权 algorithm n 算法 39 lg riem annotation java 代码注释 n u 39 tei n
  • 自动控制原理(1)-典型环节的传递函数

    构成线性定常控制系统的七个环节 xff1a 比例环节 xff0c 微分环节 xff0c 一阶微分环节 xff0c 二阶微分环节 xff0c 积分环节 xff0c 惯性环节 xff0c 振荡环节 1 比例环节 K为比例系数比例环节又称无惯性环
  • ESP8266从入门到入门系列(一) 你好,ESP8266

    0 前言 转载自我的古月居频道 距离我签约古月居已经过去了一个月了 xff0c 博主因为在这一个月的时间里琐碎的事情非常的多 xff0c 所以也推迟了我发博客的时间 古月居这个平台是以ROS起家的 xff0c 但是我们不能局限于软件 xff
  • BearPi-HM_Nano 鸿蒙os学习笔记(一)-在Windows下搭建开发环境

    BearPi HM Nano 鸿蒙os学习笔记 一 在Windows下搭建开发环境 0 前言 最近HarmonyOS2 0发布了 xff0c 就想着跟上时代的脚步 xff0c 后来在度娘上搜索相关信息 xff0c 发现了一款比较便宜的鸿蒙开
  • 普通数组如何转换成json数据格式

    我们都知道json有很多种格式 xff0c 而开发过程中经常遇到格式转换的问题 xff0c 特别是接口调用的时候 xff0c 如何将普通数组转成我们需要的json格式呢 xff0c 下面我提供了一种方法 xff0c 也是一种思路 xff0c
  • github常用命令(收藏版)

    目录 创建仓库 x1f30f 初始化仓库 x1f30f 查看仓库状态 x1f30f 设置用户信息 x1f30f 创建钥匙 x1f30f 验证钥匙 x1f30f 与远程仓库建立连接 x1f30f 重新设置仓库url地址 x1f30f 初次拉取
  • Android中Parcelable接口用法

    1 Parcelable接口 Interface for classes whose instances can be written to and restored from a Parcel Classes implementing t
  • STM32开发笔记(四)——FreeRTOS

    STM32开发笔记 xff08 四 xff09 FreeRTOS 小狼 64 http blog csdn net xiaolangyangyang 一 FreeRTOS调度原理 FreeRTOS调度分为时间片调度和抢占调度两种 时间片调度
  • 硬件学习之为什么三相电机不需要电容?

    1 单项电机 一个单相电机里一共有两个线圈 xff0c 主线圈和副线圈 当单相正弦电流通过主线圈时 xff0c 主线圈就会产生一个交变脉动磁场 xff0c 这个磁场的强弱随时间作正弦电流变化而变化 xff0c 但在它的方向一直是1 3这个方
  • Orb-slam2+win7+VS2015+USB双目摄像头

    Orb slam2 43 win7 43 VS2015 43 USB双目摄像头 本文将介绍如何在win7上使用USB双目摄像头实现Orb slam2 主要硬件 我们以USB双目摄像头 43 VS2015 43 win7来实现功能 xff1a
  • win7+opencv-2.4.13安装教程

    win7 43 opencv 2 4 13安装教程 本文将介绍如何在win7上安装opencv 2 4 13 一 安装过程 1 下载OpenCV 安装包 xff0c 以opencv 2 4 13 为例 2 双击 opencv 2 4 13
  • WIN7+Visual Studio 2013安装配置教程

    WIN7 43 Visual Studio 2013安装配置 本文将介绍如何在win7上安装Visual Studio 2013 一 xff1a 安装过程 1 下载Visual Studio 2013 安装包 下载之后的文件是 iso 格式
  • Ubuntu18.04 + Orb-Slam3 + USB双目摄像头

    Ubuntu18 04 43 Orb slam3 43 USB双目摄像头 本文将介绍如何在Ubuntu18 04上使用USB双目摄像头实现Orb slam3 主要硬件 我们以USB双目摄像头在Ubuntu18 04上来实现功能 xff1a
  • 树莓派结合Pixhawk飞控实现四轴双目视觉避障

    无人机双目视觉避障的实现 本文将介绍如何使用树莓派结合PIX飞控实现无人机双目视觉避障的功能 主要硬件 我们以双目摄像头 43 树莓派 43 Pixhawk飞控来实现功能 xff1a 双目摄像头与树莓派通过USB接口来连接 xff0c 树莓
  • TypeScript 终极初学者指南

    大家好 xff0c 我是 ConardLi xff0c 在过去的几年里 TypeScript 变得越来越流行 xff0c 现在许多工作都要求开发人员了解 TypeScript xff0c 各大厂的大型项目基本都要求使用 TypeScript
  • STM32——STM32库结构详解

    STM32库是由ST公司针对STM32提供的函数接口 xff0c 即API xff08 application program interface xff09 xff0c 开发者可以调用这些函数接口来配置STM32的寄存器 xff0c 脱离
  • 监控树莓派Raspberry Pi的CPU/GPU的温度

    监控树莓派Raspberry Pi的CPU GPU的温度 树莓派Raspberry Pi的CPU GPU的温度对于Pi的温度 高效运行非常重要 xff0c 所以我们要实时监控树莓派Raspberry Pi的CPU GPU的温度 1 运行环境
  • 【嵌入式系统】二、初识 Tiva TM4C123G系列开发板

    大二电赛小白 思考 主要偏向于嵌入式的应用 xff0c 请大家多多指教 xff01 TM4C123x系列是TI公司推出的一款32位基于ARM Cortex M4的处理器 1 TM4C123GH6PM的M4内核 超低功耗 耗电量370 A M
  • fdisk用法

    NAME fdisk Partition table manipulator for Linux SYNOPSIS fdisk u b sectorsize C cyls H heads S sects device fdisk l u d
  • 用策略模式优化代码的实例

    实例一 xff1a 利用利用策略模式实际开发中 if else 条件判断过多的问题 xff0c 条件少还好 xff0c 一旦 else if 过多这里的逻辑将会比较混乱 xff0c 并很容易出错 比如 xff1a 刚开始条件较少 xff0c