策略模式的应用——应对频繁的需求变更
秋招结束后,间接性堕落了一段时间,学习几乎停止下来了。内心甚是焦灼,感觉生活很无趣!为了在参加工作后能够快速上手和成为一名优秀的中级开发者,从这篇文章开始将不断学习优秀的编码经验,学习是永无止境的。需要静下来,慢慢来!下面进入新篇章,技术提升篇。
应用情景
在工作中,往往我们的需求是多变的,那么如果我们只是简单的硬编码解决暂时的需求,那么当需求进行变更的时候我们的接口就需要变更来应对新的需求。但是有些情况下我们可以写一些通用接口来因对这种变化,即把频繁变化的东西提取出来,交给接口调用者来设计。在这种情况下,我们的接口就无需变化,而当需求变化了只需要重写频繁变化的对象即可。这就是策略模型的一种应用,接下来将用具体的例子来说明这种编码方式的具体实现。
此时,我们有个实体集合,需要通过对实体类的属性进行过滤选择出符合我们条件的一些实体。例如,第一周产品经理要求对属性一进行过滤,第二周需求变更又要把属性二加进去过滤,第三周又要把属性三考虑进去。。。。。于是,为了应对这种变化,我们的接口应该使用策略模式。如下:
具体实现
假设我们的实体简单一些,使用经典Student作为实体,代码如下:
package strategy.demo.entity;public class Student {private String name;private int age;private int score;private String address;public Student(String name, int age, int score, String address){this.name = name;this.age = age;this.score = score;this.address = address;}public String getName() {return name;}public int getAge() {return age;}public int getScore() {return score;}public String getAddress() {return address;}public String toString(){return "Student [name=" + name + ", age=" + age + ", score=" + score + ", address=" + address + "]";}
}
首先,我们看下如果是硬编码的话,两个不同的需求应该会写下如下代码:
/*** 需求1:根据分数过滤学生* @param students* @param age* @return*/public List<Student> filterStudentByAge(List<Student> students, int age){ArrayList<Student> result = new ArrayList<>();for (Student student : students) {if (student.getAge() > age){result.add(student);}}return result;}/*** 需求2:根据分数和年龄过滤学生* @param students* @param age* @param score* @return*/public List<Student> filterStudentByScore(List<Student> students,int age , int score){ArrayList<Student> result = new ArrayList<>();for (Student student : students) {if (student.getScore() > score && student.getAge() > age){result.add(student);}}return result;}
上面的代码,需求2的代码是对需求1的升级维护,如果后面继续改动这个接口呢?所以,我们需要把频繁变动的东西提取出来作为一个策略对象,这里频繁变动的东西就是对实体Student属性的判断,因此我们抽取出一个接口:
package strategy.demo.service;
import strategy.demo.entity.Student;
public interface filterStrategy {/*** 根据stduent的不同属性进行谓词过滤* @param student* @return*/public boolean filterStudent(Student student);
}
这个接口只有一个待实现的方法,接受一个Student对象,返回是否符合过滤条件。而这个接口是由调用者实现的,其实这个设计思路在JDK中非常常见。我们需要对一个对象集合 sort 排序,需要按照自己的排序策略重写Comparator接口,还记得嘛?如下:
List<Student> allStudents = StudentHelps.getAllStudents();
allStudents.sort(new Comparator<Student>() {@Overridepublic int compare(Student o1, Student o2) {return o1.getAge()-o2.getAge;}
});
因此,使用策略模式,我们只需要写下一个过滤方法即可,其他的过滤策略由调用者去实现,如下:
public List<Student> filterStudentByStrategy(List<Student> students, filterStrategy strategy){ArrayList<Student> result = new ArrayList<>();for (Student student : students) {if (strategy.filterStudent(student)){result.add(student);}}return result;}
调用者实现时如下:
List<Student> allStudents = StudentHelps.getAllStudents();
List<Student> students3 = filterStudentByStrategy(allStudents, new filterStrategy() {@Overridepublic boolean filterStudent(Student student) {return student.getScore() > 80 && student.getAge() > 20;}
});
如此一来,无论对student的过滤需求如何变化,始终可以通过 filterStrategy 接口实现,因此就更大程度上遵守高内聚低耦合的开发原则。这就是设计模式的美妙之处。
扩展
其实,在很多情况下,接口开发者会提供一个基本功能的 filterStrategy 接口实现类,里面有常用的过滤策略,调用者只需要用即可不需要每次都自己定义。这在JDK源码和SpringBoot中有太多的例子了,简单常用的由接口方提供,复杂不常用的我允许调用者自定义!
另外一个扩展就是,调用者在这里写匿名类可以使用Lambda语法,具体参考我的博客 Lambda表达式常见用法 。Lambda语法也是提供工作效率的神器,有时间推荐学习!因此,调用者使用Lambda可以这样编写代码:
List<Student> students4 = filterStudentByStrategy(allStudents, student -> student.getScore() > 80 && student.getAge() > 20);
也就相当于把判断条件参数化了,这种做法叫做自定义函数接口(看起来是函数作为一个参数传递),看不懂的话去看下我的博客就会了,以上就是本期内容!共勉加油!
相关文章:
策略模式的应用——应对频繁的需求变更
秋招结束后,间接性堕落了一段时间,学习几乎停止下来了。内心甚是焦灼,感觉生活很无趣!为了在参加工作后能够快速上手和成为一名优秀的中级开发者,从这篇文章开始将不断学习优秀的编码经验,学习是永无止境的…...
qt-C++笔记之treeWidget初次使用
qt-C笔记之treeWidget初次使用 code review! 文章目录 qt-C笔记之treeWidget初次使用1.运行2.文件结构3.main.cpp4.widget.h5.widget.cpp6.widget.ui7.main.qrc8.qt_widget_test.pro9.options.png 1.运行 2.文件结构 3.main.cpp 代码 #include "widget.h"#include…...
SQL零基础入门教程,贼拉详细!贼拉简单! 速通数据库期末考!(八)
FULL OUTER JOIN 除了前面讲到的 INNER JOIN(内连接)、LEFT JOIN(左连接)、RIGHT JOIN(右连接),还有另外一种关联方式,即 FULL OUTER JOIN(全外连接) FULL O…...
C语言编程陷阱(八)
陷阱36:不要使用指针作为函数的返回值 有时候,我们可能想要用一个函数来返回一个指针,比如返回一个动态分配的内存,或者返回一个数组的某个元素的地址。但是,如果我们不小心,我们可能会犯一个很常见的错误,就是返回一个局部变量的地址。例如,看看下面的代码: #inclu…...
客户端性能优化实践
背景 双十一大促时,客户客服那边反馈商品信息加载卡顿,在不断有订单咨询时,甚至出现了商品信息一直处于加载状态的情况,显然,在这种高峰期接待客户时,是没法进行正常的接待工作的。 起初,页面一…...
mysql使用--表达式和函数
1.表达式 如:11,一般包含操作数,运算符。 _1.操作数 MYSQL中最常用的操作数有以下几种 (1).常数 (2).列名,针对某个具体的表,它的列名可被当作表达式的一部分 (3).函数调用 一个函数用于完成某个特定的功能。比如NOW()…...
<蓝桥杯软件赛>零基础备赛20周--第6周--数组和队列
报名明年4月蓝桥杯软件赛的同学们,如果你是大一零基础,目前懵懂中,不知该怎么办,可以看看本博客系列:备赛20周合集 20周的完整安排请点击:20周计划 每周发1个博客,共20周(读者可以按…...
软件开发、网络空间安全、人工智能三个方向的就业和前景怎么样?哪个方向更值得学习?
软件开发、网络空间安全、人工智能这三个方向都是当前及未来的热门领域,每个领域都有各自的就业前景和价值,以下是对这三个方向的分析: 1、软件开发: 就业前景:随着信息化的加速,软件开发的需求日益增长。…...
新增文章分类
pojo.Category package com.lin.springboot01.pojo;import jakarta.validation.constraints.NotEmpty; import lombok.Data;import java.time.LocalDateTime;Data public class Category {private Integer id;//主键NotEmptyprivate String categoryName;//分类名称NotEmptypr…...
选硬币该用动态规划
选硬币: 现有面值分别为1角1分,5分,1分的硬币,请给出找1角5分钱的最佳方案。 #include <iostream> #include <vector>std::vector<int> findChange(int amount) {std::vector<int> coins {11, 5, 1}; /…...
LeetCode 2342. 数位和相等数对的最大和:哈希表
【LetMeFly】2342.数位和相等数对的最大和:哈希表 力扣题目链接:https://leetcode.cn/problems/max-sum-of-a-pair-with-equal-sum-of-digits/ 给你一个下标从 0 开始的数组 nums ,数组中的元素都是 正 整数。请你选出两个下标 i 和 j&…...
Vulkan渲染引擎开发教程 一、开发环境搭建
一 安装 Vulkan SDK Vulkan SDK 就是我们要搞的图形接口 首先到官网下载SDK并安装 https://vulkan.lunarg.com/sdk/home 二 安装 GLFW 窗口库 GLFW是个跨平台的小型窗口库,也就是显示窗口,图形的载体 去主页下载并安装,https://www.glfw.…...
(带教程)商业版SEO关键词按天计费系统:关键词排名优化、代理服务、手机自适应及搭建教程
源码简介: 1、会员管理: 该系统分为三个级别的会员流程:总站管理员、代理与会员(会员有普通会员、中级会员和高级会员三个等级)。总站管理员可以添加代理用户并为其充值余额,代理用户可以为普通用户充值余…...
IDEA 快捷键汇总
目录 1、altinsert 2、ctrl/ 3、altenter 4、alt回车 5、ctrlD 6、ctrlaltL 7、ctrl点击 8、alt左键向下拉 9、ctrlaltv 10、ctrlaltwint 1、altinsert 快速创建代码,可以快速创建类中get set tostring等方法 2、ctrl/ 单行注释 3、altenter…...
目标检测YOLO实战应用案例100讲-基于机器视觉的水稻病虫害监测预警
目录 前言 国内外研究现状 国外研究现状 国内研究现状 2 相关理论与技术...
OrthoNets:正交信道注意网络
文章目录 摘要1、简介2、相关工作3、方法4、实验设置及结果5、论述6、结论摘要 链接:https://arxiv.org/pdf/2311.03071v2.pdf 设计有效的通道注意力机制要求人们找到一种有损压缩方法,以实现最佳特征表示。尽管该领域近年来取得了进展,但仍然存在一个未解决的问题。FcaNet…...
C_12练习题
一、单项选择题(本大题共20小题,每小题2分,共40分。在每小题给出的四个备选项中,选出一个正确的答案,并将所选项前的字母填写在答题纸的相应位置上。) C 风格的注释,也称块注释或多行注释,以()…...
导航守卫有哪三种?
导航守卫主要分为三种: 全局前置守卫:使用 router.beforeEach 注册,作用是在路由切换开始前进行拦截和处理,可以用来进行一些全局的权限校验、登录状态检查等操作。 全局解析守卫:使用 beforeResolve 注册,…...
强烈 推荐 13 个 Web前端在线代码IDE
codesandbox.io(国外,提供免费空间) 网址:https://codesandbox.io/ CodeSandbox 专注于构建完整的 Web 应用程序,支持多种流行的前端框架和库,例如 React、Vue 和 Angular。它提供了一系列增强的功能&…...
网络协议 WebSocket
一、介绍 WebSocket 是基于 TCP 的一种新的网络协议。它实现了浏览器与服务器全双工通信——浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接, 并进行双向数据传输 1、HTTP协议和WebSocket协议对比 HTTP 是短连接WebSocket 是长连接H…...
ARM Mali-T600系列GPU架构解析:移动GPU如何从图形渲染迈向异构计算
1. 从SIGGRAPH看移动GPU的暗流涌动:ARM Mali-T600系列深度拆解每年的SIGGRAPH(计算机图形图像特别兴趣小组)大会,聚光灯总是打在那些炫目的电影特效、逼真的游戏渲染和前沿的学术研究上,这很容易让人产生一种错觉&…...
LLMFarm性能优化技巧:提升模型推理速度和内存效率的10个方法
LLMFarm性能优化技巧:提升模型推理速度和内存效率的10个方法 【免费下载链接】LLMFarm llama and other large language models on iOS and MacOS offline using GGML library. 项目地址: https://gitcode.com/gh_mirrors/ll/LLMFarm LLMFarm是一款在iOS和ma…...
从桌面玩具到生产力工具:Dobot Magician机械臂的5个超实用项目实战(含代码)
从桌面玩具到生产力工具:Dobot Magician机械臂的5个超实用项目实战(含代码) 在创客圈里积灰的Dobot Magician机械臂,可能正等待一次真正的觉醒。这款被许多人当作"高级玩具"的六轴机械臂,实际上隐藏着足以改…...
开源首发:DocCenter — 本地 HTML 工作台,治好 AI 时代的文档散落病
Tags:Python aiohttp 开源项目 AI工具 前端工程 全栈 工具分享 一、痛点:AI 时代的文档散落病 (对比传统文档管理 vs AI 生成文档的区别,说明为什么 VSCode/Notion 都不合适) 二、技术选型:为什么是单 Pyth…...
VRoid Studio中文汉化终极指南:5步完成界面中文化
VRoid Studio中文汉化终极指南:5步完成界面中文化 【免费下载链接】VRoidChinese VRoidStudio汉化插件 项目地址: https://gitcode.com/gh_mirrors/vr/VRoidChinese VRoid Studio中文汉化插件是专为中文用户设计的开源解决方案,能够将VRoid Studi…...
springboot智能垃圾识别分类管理系统-计算机毕业设计源码11555
摘要 随着环保意识的提升和垃圾分类政策的推进,垃圾分类管理变得愈加重要。现有的垃圾分类管理系统存在人工识别准确性低、操作繁琐、信息流转效率低等问题,缺乏高效、智能化的解决方案。为了解决这些问题,本文提出了一种智能垃圾识别分类管理…...
从Xilinx 7系列FPGA看架构演进与工程选型实战
1. 项目概述:从一则旧闻看FPGA的演进与选型看到这个标题,很多朋友可能会觉得这是一则十多年前的“旧闻”了。确实,2011年Xilinx宣布其28nm 7系列FPGA在六个月内获得超过200个设计订单,这在当时是半导体行业的一个里程碑。但今天回…...
别再手撸流程图了!用Vue-super-flow + Element UI 10分钟搞定审批流原型
用Vue-super-flow Element UI快速构建企业级审批流原型 在企业内部管理系统中,审批流程是最常见的功能需求之一。传统的手工绘制流程图方式不仅效率低下,而且难以与业务系统无缝集成。现在,借助Vue-super-flow这一强大的Vue流程图组件&#…...
透明背景图片制作方法,一个小程序就能搞定!
最近,我被一个问题烦透了——每次需要制作透明背景图片时,总要在各种工具之间折腾半天。直到我发现了一个神器,才彻底改变了我的工作流程。今天,我就来分享一下我用过的所有透明背景图片制作方法,以及为什么我现在最常…...
100GbE技术演进:背板PAM4与光模块25G的路线之争
1. 高速以太网技术演进中的十字路口:100GbE的“戏剧性”挑战在通信与网络设备、半导体设计与制造这个圈子里待久了,你会发现技术标准的制定过程,其精彩程度丝毫不亚于一部精心编排的戏剧。尤其是当我们谈论到以太网,这个支撑起全球…...
