做pc端的网站首页尺寸是多少/抖音关键词用户搜索排名靠前
一、策略模式
1.1策略模式定义
在策略模式(Strategy Pattern)中一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。
在策略模式定义了一系列算法或策略,并将每个算法封装在独立的类中,使得它们可以互相替换。通过使用策略模式,可以在运行时根据需要选择不同的算法,而不需要修改客户端代码。
在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。
1.2 使用场景
1、如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。
2、一个系统需要动态地在几种算法中选择一种。
3、如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。
二、工厂模式
2.1工厂模式定义
工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
工厂模式提供了一种将对象的实例化过程封装在工厂类中的方式。通过使用工厂模式,可以将对象的创建与使用代码分离,提供一种统一的接口来创建不同类型的对象。
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
2.2 使用场景
1、日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。
2、数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。
3、设计一个连接服务器的框架,需要三个协议,"POP3"、"IMAP"、"HTTP",可以把这三个作为产品类,共同实现一个接口。
注意事项:作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过 new 就可以完成创建的对象,无需使用工厂模式。如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。
三、实现
需求为用户在美团上购买物品后的核销业务,根据一个周期内(周期为时间,如一个月,一周等)不同核销完成后的返回结果进行核销限制添加积分等,例如是否是本公司app下的会员,是否添加本公司企微,是否关注本公司公众号来进行对应操作,(后续可能会添加其他核销方式),所以该处可利用策略模式实现,而不是一长串的if..else进行功能的实现,违反了开闭原则(对扩展开放,对修改封闭),
3.1 使用if...else实现功能伪代码
过多嵌套,后续扩展功能不利于维护,实现简单
public class StrategyTest {@Resourceprivate TbUserDao tbUserDao;@Resourceprivate TbActivityDao tbActivityDao;@Resourceprivate MtCouponService mtCouponService;@Testpublic Object verify (String userId,String receipt_code) {Map<String,Object> result = new HashMap<>();//1. 获取用户信息TbUser tbUser = tbUserDao.selectUserByUserId(userId);if (null == tbUser) {return null;}// 根据receipt_code 和 skuId 查询出需要核销的类型// 2. 根据不同的核销次数进行核销限制String callBackMsg = mtCouponService.getCoinByReceiptCode(receipt_code, userId, "杭州");Map callBackMap = JSON.parseObject(callBackMsg, Map.class);if ("200".equals(callBackMap.get("code"))) {//2.1. 判断次数进行选择if(.....) {...}else if(....){...} else if(....){...} else if(....){...} }result.put("code", "505");result.put("msg", callBackMap.get("msg"));return result;}
}
3.2 使用策略模式+工厂模式
涉及到实际业务,服务实现直接简化为打印相应核销策略
抽象策略类接口
public interface VerificationService {String verificationName();void verify();
}
实现具体策略服务
- MtCouponService 核销服务
- UserService 用户服务
- LinkedWeChatService RPC判断用户状态服务
@Service
public class OfficialAccountsVerifyServiceImpl implements VerificationService{@Resourceprivate UserService userService;@Resourceprivate MtCouponService mtCouponService;@Overridepublic String verificationName() {return VerificationEnum.OfficialAccounts.getName();}@Overridepublic Object verify(String receipt_code, String userId,String cityName) {Map<String, Object> resultMap = new HashMap<>();TbUser tbUser = userService.selectUserByUserId(userId);if (null == tbUser) {return JSON.toJSONString(new CommonView("500", "用户不存在", null));}String response = HttpUtil.get("http://localhost:9088/wx/wxUserTags/isSubcribe?unionId=" + tbUser.getThirdUserId());Map result = JSON.toJavaObject(JSON.parseObject(response), Map.class);Object data = result.get("data");if ("true".equals(data.toString())) {return mtCouponService.getCoinByReceiptCode(receipt_code, userId ,cityName);}resultMap.put("code", "501");resultMap.put("msg", "请关注公众号后再进行核销!");return resultMap;}
}
该功能还在完善
@Service
public class VipVerifyServiceImpl implements VerificationService{@Resourceprivate MtCouponService mtCouponService;@Overridepublic String verificationName() {return VerificationEnum.Vip.getName();}@Overridepublic Object verify(String receipt_code, String userId,String cityName) {System.out.println("会员核销 = ");Map<String, Object> resultMap = new HashMap<>();resultMap.put("code", "501");resultMap.put("msg", "请开通Vip后再进行核销!");return resultMap;}
}
@Service
public class WeComGroupVerifyServiceImpl implements VerificationService{@Resourceprivate LinkedWeChatService linkedWeChatService;@Resourceprivate MtCouponService mtCouponService;@Overridepublic String verificationName() {return VerificationEnum.WeComGroup.getName();}@Overridepublic Object verify(String receipt_code, String userId,String cityName) {Map<String, Object> resultMap = new HashMap<>();boolean status = linkedWeChatService.existsCustomerInGroup(userId);if (status) { //入群return mtCouponService.getCoinByReceiptCode(receipt_code, userId ,cityName);}resultMap.put("code", "501");resultMap.put("msg", "请加群后再进行核销!");return resultMap;}
}
@Service
public class WeComVerifyServiceImpl implements VerificationService{@Resourceprivate LinkedWeChatService linkedWeChatService;@Resourceprivate MtCouponService mtCouponService;@Overridepublic String verificationName() {return VerificationEnum.WeCom.getName();}@Overridepublic Object verify(String receipt_code, String userId,String cityName) {Map<String, Object> resultMap = new HashMap<>();boolean status = linkedWeChatService.existsUnionId(userId);if (status) { //添加企微return mtCouponService.getCoinByReceiptCode(receipt_code, userId ,cityName);}resultMap.put("code", "501");resultMap.put("msg", "请添加企微后再进行核销!");return resultMap;}
}
环境类
/*** 核销枚举类*/
public enum VerificationEnum {/*** 默认*/defaultVerify( "defaultVerify"),/*** 企微*/WeCom( "WeCom"),/*** 入群*/WeComGroup("WeComGroup"),/*** 公众号*/OfficialAccounts( "OfficialAccounts"),/*** 会员*/Vip("Vip");private String name;VerificationEnum(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}
/*** 初始化,并获取VerificationService所有服务bean*/
@Component
@Slf4j
public class StrategyHandler implements InitializingBean, ApplicationContextAware {/*** 存放策略的map,可以理解为策略的注册中心*/@Resourceprivate final Map<String, VerificationService> strategyServiceMap = new ConcurrentHashMap<>(16);/*** spring的上下文*/private ApplicationContext applicationContext;private static final Integer DAY_BETWEEN = -60;@Overridepublic void afterPropertiesSet() {//初始化把所有的策略bean放进ioc,使用的时候获取Map<String, VerificationService> matchBeans = applicationContext.getBeansOfType(VerificationService.class);//策略注入的bean做key,策略实现类做valuematchBeans.forEach((key, value) -> {strategyServiceMap.put(value.verificationName(), value);
// log.info("项目启动时初始化核销策略模式为: key={},value={}", key, value);});}/**** @param applicationContext spring的上下文* @throws BeansException 获取bean异常*/@Overridepublic void setApplicationContext(@NotNull(message = "bean不能为空") ApplicationContext applicationContext) throws BeansException {this.applicationContext = applicationContext;}/*** 通过key获取对应的策略实现** @param verifyNum 根据次数选择对应核销方式 (String类型或者整形都行,保持和策略接口一致就行)* @return VerificationService 具体的核销服务*/public Object getStrategy(int verifyNum, String receipt_code, String userId,String cityName) throws RuntimeException{switch (verifyNum) {case 0:case 1:log.info("使用默认核销");return strategyServiceMap.get(VerificationEnum.defaultVerify.getName()).verify(receipt_code,userId,cityName);case 2:log.info("当前核销次数为3次--->WeCom");return strategyServiceMap.get(VerificationEnum.WeCom.getName()).verify(receipt_code,userId,cityName);case 3:log.info("当前核销次数为4次--->WeComGroup");return strategyServiceMap.get(VerificationEnum.WeComGroup.getName()).verify(receipt_code,userId,cityName);case 4:log.info("当前核销次数为5次--->OfficialAccounts");return strategyServiceMap.get(VerificationEnum.OfficialAccounts.getName()).verify(receipt_code,userId,cityName);
// case 5:
// strategyServiceMap.get(VerificationEnum.Vip.getName()).verify(userId);
// break;default:log.info("当前核销次数为6次及以上--->禁止核销");break;}CouponResult result = new CouponResult();result.setCode("501");result.setMsg("当前验券次数超过6次,该周期禁止核销");result.setValue(0);return JSON.toJSONString(result);}
*初始化项目时直接注册服务,方便调用
调用方便,易扩展,但是实现过程较繁琐,
@PostMapping(value = "/verify")@SignCtrl@ResponseBody@ApiResponses(value = {@ApiResponse(code = 400, message = "验券未通过"),@ApiResponse(code = 500, message = "用户不存在"),@ApiResponse(code = 501, message = "禁止核验"),@ApiResponse(code = 501, message = "券码不存在"),@ApiResponse(code = 1003, message = "库存不足"),@ApiResponse(code = 1006, message = "券码输入错误"),@ApiResponse(code = 1008, message = "券码已使用过"),@ApiResponse(code = 1009, message = "券码已失效"),@ApiResponse(code = 1010, message = "退券中的消费券"),@ApiResponse(code = 1011, message = "已退券的消费券"),@ApiResponse(code = 1012, message = "此团购券不可在本店消费,请确认正确分店")})public Object verify(String receipt_code,String userId,String cityName) {Map mtCoupon = mongoTemplate.findOne(new Query(Criteria.where("receiptCode").is(receipt_code)),Map.class, "tbopen_shop_uuid");List<TbActivity> tbActivities;if (mtCoupon != null) {Calendar instance = Calendar.getInstance();instance.setTime(new Date());instance.add(Calendar.DATE, DAY_BETWEEN);tbActivities = activityDao.selectMTOrderByUserId(userId,DateUtils.getNowDate(instance.getTime()), DateUtils.formatDate(new Date()));int verify = 0;if (tbActivities != null) {Object[] receipt_codeArray = tbActivities.stream().map(TbActivity::getActivitySource).toArray();List<Map> verifyList = mongoTemplate.find(new Query(Criteria.where("receiptCode").in(receipt_codeArray).and("skuId").is(mtCoupon.get("skuId"))),Map.class, "tbopen_shop_uuid");verify = verifyList.size();}return strategyHandler.getStrategy(verify, receipt_code, userId, cityName);}HashMap<Object, Object> map = new HashMap<>();map.put("msg", "券码不存在");return JSON.toJSONString(new CommonView("502","成功", map));}
四 总结
4.1 优点
- 提高了代码的复用性和可维护性,将算法的定义与其具体实现进行解耦。
- 可以在运行时动态替换算法,提高了程序的灵活性。
- 符合开闭原则,新增算法无需修改现有代码。
4.2 缺点
- 客户端需要知道所有的策略类,并根据具体场景选择合适的策略,增加了客户端的复杂度。
- 如果策略类较多,会导致类的数量增多,增加系统的复杂度。
4.3 适用场景
- 当一个系统中存在多个类只有它们的行为或算法不同时。
- 当一个类定义了多种行为,而这些行为在这个类的操作中以多个条件语句的形式出现,可以将相关的条件分支移入它们各自的策略类中,以替换这些条件语句。
- 当系统需要动态地在几种算法中选择一种时,如根据不同的配置、用户选择或者环境条件等。
相关文章:

基于Spring自动注入快速实现策略模式+工厂模式优化过多的if..else
一、策略模式 1.1策略模式定义 在策略模式(Strategy Pattern)中一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。 在策略模式定义了一系列算法或策略,并将每个算法封装在独立的类中,使得它们可以互相…...

安装vcpkg管理opencv的安装+MFC缺失的解决
第一步,出现#include没有办法找到opencv头文件的问题,无法解决 在VC的提示下,安装了vcpkg,然后用vcpkg命令来帮助安装opencv,过程十分顺利。 1. cmd 到命令行窗口; 2. 建立src文件夹,并进入…...

了解树和学习二叉树
1.树 1.1 概念 树是一种 非线性 的数据结构,它是由 n ( n>0 )个有限结点组成一个具有层次关系的集合。 把它叫做树是因为它看 起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的 。 注意:树形结构中…...

Spring Boot学习随笔- 拦截器实现和配置(HandlerInterceptor、addInterceptors)、jar包部署和war包部署
学习视频:【编程不良人】2021年SpringBoot最新最全教程 第十三章、拦截器 拦截器 :Interceptor 拦截 中断 类似于javaweb中的Filter,不过没有Filter那么强大 作用 Spring MVC的拦截器是一种用于在请求处理过程中进行预处理和后处理的机制。拦…...

Pipelined-ADC设计二——结构指标及非理想因素(Part2)
接上文,本章将两个比较重要的非理想因素,因此各项指标制定。后续会对常见的非理想因素给出常见的解决方法,以及设计所采用的方法。 2.2.7. 比较器失调 在流水线 ADC 中,比较器的主要误差来源就是比较器失调,称为失调误…...

Ubuntu 常用命令之 clear 命令用法介绍
📑Linux/Ubuntu 常用命令归类整理 clear命令在Ubuntu系统下用于清除终端屏幕的内容。这个命令没有任何参数,它的主要作用就是清理终端屏幕上的所有信息,使得屏幕看起来像是新打开的一样。 使用clear命令非常简单,只需要在终端中…...

【JAVA面试题】什么是对象锁?什么是类锁?
🍎 个人博客 :个 人 主 页 🏆个人专栏:多线程JAVA ⛳️ 功 不 唐 捐 ,玉 汝 于 成 目录 前言 回答 对象锁(Object Lock): 类锁(Class Lock)࿱…...

飞天使-k8s知识点5-kubernetes基础名词扫盲
文章目录 deploymentspodNodeserviceskubectl 实现应用伸缩kubectl 实现滚动更新kubernetes架构 deployments 中文文档 http://docs.kubernetes.org.cn/251.htmldeployment是用来创建和更新应用的,master 会负责将创建好的应用实例调度到集群中的各个节点 应用实例…...

【视觉实践】使用Mediapipe进行目标检测:杯子检测和椅子检测实践
目录 1 Mediapipe 2 Solutions 3 安装mediapipe 4 实践 1 Mediapipe Mediapipe是google的一个开源项目,可以提供开源的、跨平台的常用机器学习(machine learning,ML)方案。MediaPipe是一个用于构建机器学习管道</...

C++之深拷贝进阶
目录 拷贝构造函数的深拷贝进阶版本 赋值运算符重载的深拷贝进阶 总结 上期我们学习了C中深拷贝的传统版本,今天我们将学习更为高效的版本。 拷贝构造函数的深拷贝进阶版本 传统版本代码如下: string(string& s):_str(new char[strlen(s._str)…...

导行电磁波从纵向场分量求其他方向分量的矩阵表示
导行电磁波从纵向场分量求解其他方向分量的矩阵表示 导行电磁波传播的特点 电磁波在均匀、线性、各向同性的空间中沿着 z z z轴传播,可用分离变量法将时间轴、 z z z轴与 x , y x,y x,y轴分离,电磁波的形式可表示为: E ⃗ E ⃗ ( x , y )…...

融资项目——swagger2的注解
1. ApiModel与ApiModelProperty(在实体类中使用) 如上图,ApiModel加在实体类上方,用于整体描述实体类。ApiModelProperty(value"xxx",example"xxx")放于每个属性上方,用于对属性进行描述。swagger2网页上的效果如下图&am…...

【性能优化】MySql数据库查询优化方案
阅读本文你的收获 了解系统运行效率提升的整体解决思路和方向学会MySQl中进行数据库查询优化的步骤学会看慢查询、执行计划、进行性能分析、调优 一、问题:如果你的系统运行很慢,你有什么解决方案? 关于这个问题,我们通常首先…...

Chrome浏览器http自动跳https问题
现象: Chrome浏览器访问http页面时有时会自动跳转https,导致一些问题。比如: 开发阶段访问dev环境网址跳https,后端还是http,导致接口跨域。 复现: 先访问http网址,再改成https访问…...

【C++进阶02】多态
一、多态的概念及定义 1.1 多态的概念 多态简单来说就是多种形态 同一个行为,不同对象去完成时 会产生出不同的状态 多态分为静态多态和动态多态 静态多态指的是编译时 在程序编译期间确定了程序的行为 比如:函数重载 动态多态指的是运行时 在程序运行…...

PHP开发日志——循环和条件语句嵌套不同,效率不同(循环内加入条件语句,条件语句判断后加入循环,array_map函数中加入条件语句)
十多年前开发框架时,为了效率不断试过各种代码写法,今天又遇到了,想想php8时代会不会有所变化,结果其实也还是和当年一样,但当年没写博客,但现在可以把数据记录下来了。 PHP_loop_ireflies_dark_forest 项目…...

【Seata源码学习 】 扫描@GlobalTransaction注解 篇一
1. SeataAutoConfiguration 自动配置类的加载 基于SpringBoot的starter机制,在应用上下文启动时,会加载SeataAutoConfiguration自动配置类 # Auto Configure org.springframework.boot.autoconfigure.EnableAutoConfigurationio.seata.spring.boot.aut…...

DBA-MySql面试问题及答案-上
文章目录 1.什么是数据库?2.如何查看某个操作的语法?3.MySql的存储引擎有哪些?4.常用的2种存储引擎?6.可以针对表设置引擎吗?如何设置?6.选择合适的存储引擎?7.选择合适的数据类型8.char & varchar9.Mysql字符集10.如何选择…...

网络爬虫之Ajax动态数据采集
动态数据采集 规则 有时候我们在用 requests 抓取页面的时候,得到的结果可能和在浏览器中看到的不一样,在浏览器中可以看到正常显示的页面教据,但是使用 requests 得到的结果并没有,这是因为requests 获取的都是原始的 HTML 文档…...

c语言的初始学习(练习)
##初学c语言---MOOC浙江大学翁恺先生学习c语言 那么我们先看看这个题目吧,这是初始语法的应用。 记住,我们的程序是按步骤执行的,并不是在不同的两行同时进行。 程序设计:1.了解题目的需要,几个变量需要用到&#x…...

研究论文 2022-Oncoimmunology:AI+癌RNA-seq数据 识别细胞景观
Wang, Xin, et al. "Deep learning using bulk RNA-seq data expands cell landscape identification in tumor microenvironment." Oncoimmunology 11.1 (2022): 2043662. https://www.tandfonline.com/doi/full/10.1080/2162402X.2022.2043662 被引次数࿱…...

ChatGPT4与ArcGIS Pro3助力AI 地理空间分析和可视化及助力科研论文写作
在地学领域,ArcGIS几乎成为了每位科研工作者作图、数据分析的必备工具,而ArcGIS Pro3除了良好地继承了ArcMap强大的数据管理、制图、空间分析等能力,还具有二三维融合、大数据、矢量切片制作及发布、任务工作流、时空立方体等特色功能&#x…...

okhttp系列-一些上限值
1.正在执行的任务数量最大值是64 异步请求放入readyAsyncCalls后,遍历readyAsyncCalls取出任务去执行的时候,如果发现runningAsyncCalls的数量大于等于64,就不从readyAsyncCalls取出任务执行。 public final class Dispatcher {private int …...

C++面向对象(OOP)编程-STL详解(vector)
本文主要介绍STL六大组件,并主要介绍一些容器的使用。 目录 1 泛型编程 2 CSTL 3 STL 六大组件 4 容器 4.1 顺序性容器 4.1.1 顺序性容器的使用场景 4.2 关联式容器 4.2.1 关联式容器的使用场景 4.3 容器适配器 4.3.1 容器适配器的使用场景 5 具体容器的…...

postman几种常见的请求方式
1、get请求直接拼URL形式 对于http接口,有get和post两种请求方式,当接口说明中未明确post中入参必须是json串时,均可用url方式请求 参数既可以写到URL中,也可写到参数列表中,都一样,请求时候都是拼URL 2&am…...

openai最新探索:超级对齐是否可行?
前言 今天来介绍一篇openai最新的paper:弱到强的对齐。 openai专门成立了一个团队来做大模型的超级对齐即superhuman model,之前chatgpt取得成功依赖RLHF即依赖人类反馈,但是作者期望的superhuman model将会是一个能够处理各种复杂问题的强…...

本地websocket服务端结合cpolar内网穿透实现公网访问
文章目录 1. Java 服务端demo环境2. 在pom文件引入第三包封装的netty框架maven坐标3. 创建服务端,以接口模式调用,方便外部调用4. 启动服务,出现以下信息表示启动成功,暴露端口默认99995. 创建隧道映射内网端口6. 查看状态->在线隧道,复制所创建隧道的公网地址加端口号7. 以…...

关于“Python”的核心知识点整理大全37
目录 13.6.2 响应外星人和飞船碰撞 game_stats.py settings.py alien_invasion.py game_functions.py ship.py 注意 13.6.3 有外星人到达屏幕底端 game_functions.py 13.6.4 游戏结束 game_stats.py game_functions.py 13.7 确定应运行游戏的哪些部分 alien_inva…...

Vivado中的FFT IP核使用(含代码)
本文介绍了Vidado中FFT IP核的使用,具体内容为:调用IP核>>配置界面介绍>>IP核端口介绍>>MATLAB生成测试数据>>测试verilogHDL>>TestBench仿真>>结果验证>>FFT运算。 1、调用IP核 该IP核对应手册pg109_xfft.pd…...

创新驱动,边缘计算领袖:亚马逊云科技海外服务器服务再进化
2022年亚马逊云科技re:Invent盛会于近日在拉斯维加斯成功召开,吸引了众多业界精英和创新者。亚马逊云科技边缘服务副总裁Jan Hofmeyr在演讲中分享了关于亚马逊云科技海外服务器边缘计算的最新发展和创新成果,引发与会者热烈关注。 re:Invent的核心主题是…...