当前位置: 首页 > news >正文

案例突破——再探策略模式

再探设计模式

  • 一、背景介绍
  • 二、 思路方案
  • 三、过程
    • 1. 策略模式基本概念
    • 2. 策略模式类图
    • 3. 策略模式基本代码
      • 策略类
      • 抽象策略类
      • Context类
      • 客户端
    • 4. 策略模式还可以进行优化的地方
    • 5. 对策略模式的优化(配置文件+反射)
  • 四、总结
  • 五、升华

一、背景介绍

在做项目重构的过程中,发现对于主题讨论中,针对于学生评论/回复的内容的按照评论/回复日期排序、按照评论数量排序、按照点赞次数排序可以使用策略模式进行优化。

二、 思路方案

  1. 策略模式基本概念
  2. 策略模式类图
  3. 策略模式基本代码
  4. 策略模式还可以进行优化的地方
  5. 对策略模式进行优化

三、过程

1. 策略模式基本概念

定义:定义了算法家族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化不会影响到使用算法的客户。

2. 策略模式类图

在这里插入图片描述

3. 策略模式基本代码

策略类

package com.wangwei.strategypattern.normal;/*** @author : [WangWei]* @version : [v1.0]* @className : ConcreteStrategy* @description : [描述说明该类的功能]* @createTime : [2023/9/7 10:34]* @updateUser : [WangWei]* @updateTime : [2023/9/7 10:34]* @updateRemark : [描述说明本次修改内容]*/
public class ConcreteStrategyA implements IStrategy{public void AlgorithmInterface(){System.out.println("算法A实现");}
}package com.wangwei.strategypattern.normal;/*** @author : [WangWei]* @version : [v1.0]* @className : ConcreteStrategy* @description : [描述说明该类的功能]* @createTime : [2023/9/7 10:34]* @updateUser : [WangWei]* @updateTime : [2023/9/7 10:34]* @updateRemark : [描述说明本次修改内容]*/
public class ConcreteStrategyB implements IStrategy{public void AlgorithmInterface(){System.out.println("算法B实现");}
}package com.wangwei.strategypattern.normal;/*** @author : [WangWei]* @version : [v1.0]* @className : ConcreteStrategy* @description : [描述说明该类的功能]* @createTime : [2023/9/7 10:34]* @updateUser : [WangWei]* @updateTime : [2023/9/7 10:34]* @updateRemark : [描述说明本次修改内容]*/
public class ConcreteStrategyC implements IStrategy{public void AlgorithmInterface(){System.out.println("算法C实现");}
}

抽象策略类

package com.wangwei.strategypattern.normal;/*** @author : [WangWei]* @version : [v1.0]* @className : IStrategy* @description : [描述说明该类的功能]* @createTime : [2023/9/7 10:37]* @updateUser : [WangWei]* @updateTime : [2023/9/7 10:37]* @updateRemark : [描述说明本次修改内容]*/
public interface IStrategy {void AlgorithmInterface();
}

Context类

package com.wangwei.strategypattern.normal;/*** @author : [WangWei]* @version : [v1.0]* @className : Context* @description : [公共上下文]* @createTime : [2023/9/7 10:38]* @updateUser : [WangWei]* @updateTime : [2023/9/7 10:38]* @updateRemark : [描述说明本次修改内容]*/
public class Context {IStrategy iStrategy=null;public Context(IStrategy iStrategy) {this.iStrategy = iStrategy;}public void ContextInterface(){iStrategy.AlgorithmInterface();}
}

客户端

package com.wangwei.strategypattern.normal;/*** @author : [WangWei]* @version : [v1.0]* @className : Client* @description : [描述说明该类的功能]* @createTime : [2023/9/7 10:40]* @updateUser : [WangWei]* @updateTime : [2023/9/7 10:40]* @updateRemark : [描述说明本次修改内容]*/
public class Client {public static void main(String[] args) {Context context=null;context= new Context(new ConcreteStrategyA());context.ContextInterface();context = new Context(new ConcreteStrategyB());context.ContextInterface();context = new Context(new ConcreteStrategyB());context.ContextInterface();}
}

4. 策略模式还可以进行优化的地方

当我们需要增加新的策略的时候,是需要修改客户端的代码,那么对于客户端来说是不符合开闭原则的。

5. 对策略模式的优化(配置文件+反射)

package com.wangwei.strategypattern.better;/*** @author : [WangWei]* @version : [v1.0]* @className : ConcreteStrategy* @description : [描述说明该类的功能]* @createTime : [2023/9/7 10:34]* @updateUser : [WangWei]* @updateTime : [2023/9/7 10:34]* @updateRemark : [描述说明本次修改内容]*/
public class ConcreteStrategyA implements IStrategy {public void AlgorithmInterface(){System.out.println("算法A实现");}
}
package com.wangwei.strategypattern.better;/*** @author : [WangWei]* @version : [v1.0]* @className : ConcreteStrategy* @description : [描述说明该类的功能]* @createTime : [2023/9/7 10:34]* @updateUser : [WangWei]* @updateTime : [2023/9/7 10:34]* @updateRemark : [描述说明本次修改内容]*/
public class ConcreteStrategyB implements IStrategy {public void AlgorithmInterface(){System.out.println("算法B实现");}
}
package com.wangwei.strategypattern.better;/*** @author : [WangWei]* @version : [v1.0]* @className : ConcreteStrategy* @description : [描述说明该类的功能]* @createTime : [2023/9/7 10:34]* @updateUser : [WangWei]* @updateTime : [2023/9/7 10:34]* @updateRemark : [描述说明本次修改内容]*/
public class ConcreteStrategyC implements IStrategy {public void AlgorithmInterface(){System.out.println("算法C实现");}
}
package com.wangwei.strategypattern.better;import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;/*** @author : [WangWei]* @version : [v1.0]* @className : Context* @description : [公共上下文]* @createTime : [2023/9/7 10:38]* @updateUser : [WangWei]* @updateTime : [2023/9/7 10:38]* @updateRemark : [描述说明本次修改内容]*/
public class Context {static Map<String,String> config = new HashMap<>();static Map<String,IStrategy> configBean = new HashMap<>();//提前读取配置文件中的策略,并提前准备好已有的策略对象static {InputStream inputStream = Context.class.getResourceAsStream("/config.properties");Properties properties = new Properties();try {properties.load(inputStream);} catch (IOException e) {throw new RuntimeException(e);}String strategyType = properties.getProperty("strategyType");String[] strs = strategyType.split(",");for (String string : strs) {String key = string.split(":")[0];String value = string.split(":")[1];// 去掉头部空格String key1 = key.trim();String value1 = value.trim();config.put(key1, value1);}//提前准备好已有的策略对象for (Map.Entry<String,String> entry:config.entrySet()) {Class strategyClass ;try {strategyClass = Class.forName(entry.getValue());configBean.put(entry.getKey(),(IStrategy) strategyClass.getConstructor().newInstance());} catch (Exception e) {throw new RuntimeException(e);}}}IStrategy iStrategy;public Context(String type) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, IOException {if(configBean.containsKey(type)){this.iStrategy = configBean.get(type);}else {Class strategyClass = Class.forName(config.get(type));this.iStrategy = (IStrategy)strategyClass.getConstructor().newInstance();}}public void ContextInterface(){iStrategy.AlgorithmInterface();}}
package com.wangwei.strategypattern.better;/*** @author : [WangWei]* @version : [v1.0]* @className : IStrategy* @description : [描述说明该类的功能]* @createTime : [2023/9/7 10:37]* @updateUser : [WangWei]* @updateTime : [2023/9/7 10:37]* @updateRemark : [描述说明本次修改内容]*/
public interface IStrategy {void AlgorithmInterface();
}
package com.wangwei.strategypattern.better;import java.io.IOException;
import java.lang.reflect.InvocationTargetException;/*** @author : [WangWei]* @version : [v1.0]* @className : Client* @description : [描述说明该类的功能]* @createTime : [2023/9/7 10:40]* @updateUser : [WangWei]* @updateTime : [2023/9/7 10:40]* @updateRemark : [描述说明本次修改内容]*/
public class Client {public static void main(String[] args) throws ClassNotFoundException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException, IOException {/*1.前端通过下拉框选择不同的类型2.类型是从配置文件中读取的*/Context context;context= new Context("strategyA");context.ContextInterface();context = new Context("strategyB");context.ContextInterface();context = new Context("strategyC");context.ContextInterface();}
}

四、总结

  1. 优点:配置文件+反射的方式,符合开闭原则。用户可以在不修改原有代码的基础上选择算法,也可以灵活的增加新的算法。

  2. 缺点:无法同时在客户端使用多个策略类。

  3. 关键点:都是对通一份数据,根据不同的算法进行处理。

  4. 什么时候使用策略模式:一个系统需要动态地在几种算法中选择一种。

五、升华

  1. 学习是一个反复的过程:通过项目切实的需求来结合具体的设计模式,在反过来在此基础上优化设计模式。

相关文章:

案例突破——再探策略模式

再探设计模式 一、背景介绍二、 思路方案三、过程1. 策略模式基本概念2. 策略模式类图3. 策略模式基本代码策略类抽象策略类Context类客户端 4. 策略模式还可以进行优化的地方5. 对策略模式的优化&#xff08;配置文件反射&#xff09; 四、总结五、升华 一、背景介绍 在做项目…...

uboot启动流程-涉及lowlevel_init汇编函数

一. uboot启动流程涉及函数 之前文章简单分析了 uboot启动流程的开始&#xff0c;从链接脚本文件 u-boot.lds 中&#xff0c;我们已经知道了入口点是 arch/arm/lib/vectors.S 文件中的 _start函数。 _start函数&#xff1a;调用了 reset 函数&#xff0c;reset 函数内部&…...

质数距离 - 如何在较合理的时间复杂度内求2e9范围内的质数

求l、r之间的质数&#xff0c;范围在2e9&#xff0c;但l、r的差值不大&#xff0c;在1e6范围内 先求出 内的质数&#xff0c;然后拿这个指数去筛[l, r]范围内的即可 #include<bits/stdc.h> #define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); #define endl \…...

八、3d场景的区域光墙

在遇到区域展示的时候我们就能看到炫酷的区域选中效果&#xff0c;那么代码是怎么编辑的呢&#xff0c;今天咱们就好好说说&#xff0c;下面看实现效果。 思路&#xff1a; 首先&#xff0c;光墙肯定有多个&#xff0c;那么必须要创建一个新的js文件来作为他的原型对象。这个光…...

深入探讨 Presto 中的缓存

【squids.cn】 全网zui低价RDS&#xff0c;免费的迁移工具DBMotion、数据库备份工具DBTwin、SQL开发工具等 Presto是一种流行的开源分布式SQL引擎&#xff0c;使组织能够在多个数据源上大规模运行交互式分析查询。缓存是一种典型的提高 Presto 查询性能的优化技术。它为 Prest…...

3.物联网射频识别,(高频)RFID应用ISO14443-2协议,(校园卡)Mifare S50卡

一。ISO14443-2协议简介 1.ISO14443协议组成及部分缩略语 &#xff08;1&#xff09;14443协议组成&#xff08;下面的协议简介会详细介绍&#xff09; 14443-1 物理特性 14443-2 射频功率和信号接口 14443-3 初始化和防冲突 &#xff08;分为Type A、Type B两种接口&…...

【IDEA】IDEA 单行注释开头添加空格

操作 打开 IDEA 的 Settings 对话框&#xff08;快捷键为CtrlAltS&#xff09;&#xff1b;在左侧面板中选择Editor -> Code Style -> Java&#xff1b;在右侧面板中选择Code Generation选项卡&#xff1b;将Line comment at first column选项设置为false使注释加在行开…...

三等分功分器[波导]设计详细教程

想必大家通过阅读相关文献可以发现三等分实现可以有很多不同的方法&#xff0c;这里采用的是先不等分再等分的方式&#xff0c;仅供参考。 主要指标 中心频率为280GHz&#xff0c;采用WR-3频段的标准波导&#xff0c;将2:1不等功率分配耦合器与3dB等功率分配耦合器级联&#…...

Mysql分库分表

1.原理 2.Sharding JDBC 官网https://shardingsphere.apache.org/ 2.1 水平拆分 创建一个新的springboot项目 导入依赖,直接将原本的dependencies给覆盖掉 <dependencies><!-- ShardingJDBC依赖 --><dependency><groupId>org.apache.shardings…...

【算法学习】-【双指针】-【复写零】

LeetCode原题链接&#xff1a;1089. 复写零 下面是题目描述&#xff1a; 给你一个长度固定的整数数组 arr &#xff0c;请你将该数组中出现的每个零都复写一遍&#xff0c;并将其余的元素向右平移。 注意&#xff1a;请不要在超过该数组长度的位置写入元素。请对输入的数组 …...

【算法优选】双指针专题——叁

文章目录 &#x1f60e;前言&#x1f333;[两数之和](https://leetcode.cn/problems/he-wei-sde-liang-ge-shu-zi-lcof/)&#x1f6a9;题目描述&#xff1a;&#x1f6a9;算法思路&#xff1a;&#x1f6a9;算法流程&#xff1a;&#x1f6a9;代码实现 &#x1f384;[三数之和]…...

Java栈的压入、弹出序列(详解)

目录 1.题目描述 2.题解 方法1 方法2 1.题目描述 输入两个整数序列&#xff0c;第一个序列表示栈的压入顺序&#xff0c;请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序&#xff0c;序列4,5,3,2,1是该压栈序…...

RabbitMQ学习笔记(消息发布确认,死信队列,集群,交换机,持久化,生产者、消费者)

MQ&#xff08;message queue&#xff09;&#xff1a;本质上是个队列&#xff0c;遵循FIFO原则&#xff0c;队列中存放的是message&#xff0c;是一种跨进程的通信机制&#xff0c;用于上下游传递消息。MQ提供“逻辑解耦物理解耦”的消息通信服务。使用了MQ之后消息发送上游只…...

PyTorch - 模型训练损失 (Loss) NaN 问题的解决方案

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/133378367 在模型训练中&#xff0c;如果出现 NaN 的问题&#xff0c;严重影响 Loss 的反传过程&#xff0c;因此&#xff0c;需要加入一些微小值…...

8、Nacos服务注册服务端源码分析(七)

本文收录于专栏 Nacos 中 。 文章目录 前言确定前端路由CatalogController.listDetail()ServiceManager总结 前言 前文我们分析了Nacos中客户端注册时数据分发的设计链路&#xff0c;本文根据Nacos前端页面请求&#xff0c;看下前端页面中的服务列表的数据源于哪里。 确定前端…...

MySQL使用Xtrabackup在线做主从

1、主库上操作 1.1前提 172.16.11.2&#xff08;主库&#xff09; 172.16.11.4&#xff08;从库&#xff09; 在执行备份之前&#xff0c;确保数据库没有锁定&#xff0c;以避免备份期间的任何写操作。 确保主库上的 MySQL 服务器正在运行&#xff0c;以便备份数据的一致性。…...

scala基础入门

一、Scala安装 下载网址&#xff1a;Install | The Scala Programming Language ideal安装 &#xff08;1&#xff09;下载安装Scala plugins &#xff08;2&#xff09;统一JDK环境&#xff0c;统一为8 &#xff08;3&#xff09;加载Scala &#xff08;4&#xff09;创建工…...

【Java-LangChain:面向开发者的提示工程-5】推断

第五章 推断 推断任务可以看作是模型接收文本作为输入&#xff0c;并执行某种分析的过程。其中涉及提取标签、提取实体、理解文本情感等等。如果你想要从一段文本中提取正面或负面情感&#xff0c;在传统的机器学习工作流程中&#xff0c;需要收集标签数据集、训练模型、确定如…...

【C++】手撕vector(vector的模拟实现)

手撕vector目录&#xff1a; 一、基本实现思路方针 二、vector的构造函数剖析&#xff08;构造歧义拷贝构造&#xff09; 2.1构造函数使用的歧义问题 2.2 vector的拷贝构造和赋值重载&#xff08;赋值重载不是构造哦&#xff0c;为了方便写在一起&#xff09; 三、vector的…...

智能指针那些事

​《Effective Modern C》学习笔记之条款二十一&#xff1a;优先选用std::make_unique和std::make_shared,而非直接new - 知乎...

云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?

大家好&#xff0c;欢迎来到《云原生核心技术》系列的第七篇&#xff01; 在上一篇&#xff0c;我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在&#xff0c;我们就像一个拥有了一块崭新数字土地的农场主&#xff0c;是时…...

微信小程序之bind和catch

这两个呢&#xff0c;都是绑定事件用的&#xff0c;具体使用有些小区别。 官方文档&#xff1a; 事件冒泡处理不同 bind&#xff1a;绑定的事件会向上冒泡&#xff0c;即触发当前组件的事件后&#xff0c;还会继续触发父组件的相同事件。例如&#xff0c;有一个子视图绑定了b…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;Ingress是一个API对象&#xff0c;它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress&#xff0c;你可…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

在Ubuntu中设置开机自动运行(sudo)指令的指南

在Ubuntu系统中&#xff0c;有时需要在系统启动时自动执行某些命令&#xff0c;特别是需要 sudo权限的指令。为了实现这一功能&#xff0c;可以使用多种方法&#xff0c;包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法&#xff0c;并提供…...

【单片机期末】单片机系统设计

主要内容&#xff1a;系统状态机&#xff0c;系统时基&#xff0c;系统需求分析&#xff0c;系统构建&#xff0c;系统状态流图 一、题目要求 二、绘制系统状态流图 题目&#xff1a;根据上述描述绘制系统状态流图&#xff0c;注明状态转移条件及方向。 三、利用定时器产生时…...

三体问题详解

从物理学角度&#xff0c;三体问题之所以不稳定&#xff0c;是因为三个天体在万有引力作用下相互作用&#xff0c;形成一个非线性耦合系统。我们可以从牛顿经典力学出发&#xff0c;列出具体的运动方程&#xff0c;并说明为何这个系统本质上是混沌的&#xff0c;无法得到一般解…...

【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统

目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索&#xff08;基于物理空间 广播范围&#xff09;2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...