【DP-策略+工厂+单例】Spring实战你的if/switch还多吗
业务场景:运营后台会审核用户提交的信息,审核人员在后台看数据的时候会根据提交信息的状态展示不同的页面。
状态如下:1: 未提交 2: 已提交(待审核) 3: 审核不通过 4: 审核通过
不同的逻辑需要渲染的数据不一样,处理逻辑也不一样,此处利用策略实现符合开闭原则的代码,后续再添加不同状态可灵活扩展
设计:
- 审核状态接口工厂类,内涵所有实现的容器,提供对外实例的输出
- 审核状态接口,定义功能以及一个标识策略的唯一key
- 审核状态枚举,用于限制代码越界行为
- 各自实现,后续新增时刻动态扩展
代码:
工厂类
package com.vip.qc.strategy; import org.junit.Assert;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component; import java.util.HashMap;
import java.util.Map; /**
* @author QuCheng on 2020/6/17.
*/
@Component
public class AuthStatusFactory implements ApplicationContextAware { private Map<Integer, IAuthStatus> authStatusMap = new HashMap<>(); @Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
Map<String, IAuthStatus> beansOfType = applicationContext.getBeansOfType(IAuthStatus.class);
for (Map.Entry<String, IAuthStatus> entry : beansOfType.entrySet()) {
IAuthStatus value = entry.getValue();
authStatusMap.put(value.getKey().getAuthStatus(), value);
}
} public void process(Integer key) {
IAuthStatus authStatus = authStatusMap.get(StrategyKeyEnum.getKeyByStatus(key).getAuthStatus());
Assert.assertNotNull("请检查策略接口是否实现", authStatus);
authStatus.view();
}
}
接口
package com.vip.qc.strategy; /**
* @author QuCheng on 2020/6/17.
*/
public interface IAuthStatus { /**
* 具体业务逻辑
*/
void view(); /**
* 定位策略 key
*
* @return 策略枚举
*/
StrategyKeyEnum getKey(); }
枚举
package com.vip.qc.strategy; /**
* @author QuCheng on 2020/6/17.
*/
public enum StrategyKeyEnum { /**
* 默认
*/
DEFAULT(0),
/**
* 未提交
*/
AUTH_UNCOMMIT(1),
/**
* 已提交-待审核
*/
AUTH_COMMIT(2),
/**
* 未通过
*/
AUTH_UNPASS(3),
/**
* 已通过
*/
AUTH_PASS(4),
; private Integer authStatus; StrategyKeyEnum(Integer authStatus) {
this.authStatus = authStatus;
} public Integer getAuthStatus() {
return authStatus;
} public static StrategyKeyEnum getKeyByStatus(Integer status) {
for (StrategyKeyEnum value : StrategyKeyEnum.values()) {
if (value.getAuthStatus().equals(status)) {
return value;
}
}
return DEFAULT;
}
}
实现
package com.vip.qc.strategy.impl; import com.vip.qc.strategy.IAuthStatus;
import com.vip.qc.strategy.StrategyKeyEnum;
import org.springframework.stereotype.Component; /**
* @author QuCheng on 2020/6/17.
*/
@Component
public class AuthDefault implements IAuthStatus {
@Override
public void view() {
System.out.println("默认处理");
} @Override
public StrategyKeyEnum getKey() {
return StrategyKeyEnum.DEFAULT;
}
} package com.vip.qc.strategy.impl; import com.vip.qc.strategy.IAuthStatus;
import com.vip.qc.strategy.StrategyKeyEnum;
import org.springframework.stereotype.Component; /**
* @author QuCheng on 2020/6/17.
*/
@Component
public class AuthUncommit implements IAuthStatus {
@Override
public void view() {
System.out.println("审核未提交");
} @Override
public StrategyKeyEnum getKey() {
return StrategyKeyEnum.AUTH_UNCOMMIT;
}
} package com.vip.qc.strategy.impl; import com.vip.qc.strategy.IAuthStatus;
import com.vip.qc.strategy.StrategyKeyEnum;
import org.springframework.stereotype.Component; /**
* @author QuCheng on 2020/6/17.
*/
@Component
public class AuthCommited implements IAuthStatus {
@Override
public void view() {
System.out.println("审核已提交");
} @Override
public StrategyKeyEnum getKey() {
return StrategyKeyEnum.AUTH_COMMIT;
}
} package com.vip.qc.strategy.impl; import com.vip.qc.strategy.IAuthStatus;
import com.vip.qc.strategy.StrategyKeyEnum;
import org.springframework.stereotype.Component; /**
* @author QuCheng on 2020/6/17.
*/
@Component
public class AuthUnpass implements IAuthStatus { @Override
public void view() {
System.out.println("审核未通过");
} @Override
public StrategyKeyEnum getKey() {
return StrategyKeyEnum.AUTH_UNPASS;
}
} package com.vip.qc.strategy.impl; import com.vip.qc.strategy.IAuthStatus;
import com.vip.qc.strategy.StrategyKeyEnum;
import org.springframework.stereotype.Component; /**
* @author QuCheng on 2020/6/17.
*/
@Component
public class AuthPass implements IAuthStatus { @Override
public void view() {
System.out.println("审核通过");
} @Override
public StrategyKeyEnum getKey() {
return StrategyKeyEnum.AUTH_PASS;
}
}
测试 - 生产中直接注入AuthStatusFactory即可
@Test
public void test() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("com.vip.qc.strategy");
AuthStatusFactory bean = context.getBean(AuthStatusFactory.class);
for (int i = 1; i < 6; i++) {
bean.process(i);
}
}
【DP-策略+工厂+单例】Spring实战你的if/switch还多吗的更多相关文章
- PHP设计模式之工厂/单例/注册者模式
工厂模式 简单工厂模式 [静态工厂方法模式](Static Factory Method)是类的创建模式 工厂模式的几种形态: 1.简单工厂模式(Simple Factory)又叫做 静态工厂方法模式 ...
- C# 工厂单例
public class BusinessFactory { private static BusinessFactory instance = null; pri ...
- 002-创建型-03-单例模式(Singleton)【7种】、spring单例及原理
一.概述 保证一个类仅有一个实例,并提供一个全局访问点 私有构造器.线程安全.延迟加载.序列化和反序列化安全.反射攻击 1.1.适用场景 1.在多个线程之间,比如servlet环境,共享同一个资源或者 ...
- Spring单例 和 Scope注解
关键字 @Scope @Qualifier Singleton 单例 Spring是单例模式.结合Springboot的例子. Controller @Autowired private Tes ...
- Unity3D中可中途释放的单例
Unity3D中可中途释放的单例 使用静态类,静态变量的坏处是从程序加载后就一直占用内存,想要释放比较麻烦,可是之前使用的单例,没有提供释放的方法,那是不是也同静态的一样直到程序结束菜释放?那单例的好 ...
- 我心中的核心组件(可插拔的AOP)~第十五回 我的日志组件Logger.Core(策略,模版方法,工厂,单例等模式的使用)
回到目录 之前的讲过两篇关于日志组件的文章,分别是<第一回 日志记录组件之自主的Vlog>和<第三回 日志记录组件之log4net>,而今天主要说一下我自己开发的另一种日志 ...
- 【Spring实战】—— 3 使用facotry-method创建单例Bean总结
如果有这样的需求: 1 不想再bean.xml加载的时候实例化bean,而是想把加载bean.xml与实例化对象分离. 2 实现单例的bean 以上的情况,都可以通过工厂方法factory-metho ...
- Spring深入浅出(二)IOC的单例 ,继承,依赖,JDBC,工厂模式以及自动装载
IOC的单例模式--Bean Spring中的bean是根据scope来决定的. scope有4种类型: 1.singleton:单例模型,表示通过Spring容器获取的该对象是唯一的.常用并且默认. ...
- oop的三种设计模式(单例、工厂、策略)
参考网站 单例模式: 废话不多说,我们直接上代码: <?php /** 三私一公 *私有的静态属性:保存类的单例 *私有的__construct():阻止在类的外部实例化 *私有的__clone ...
- Spring IOC(三)单例 bean 的注册管理
Spring IOC(三)单例 bean 的注册管理 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html) 在 Spring 中 ...
随机推荐
- 重磅消息,微软宣布 VS Code Copilot 开源,剑指 Cursor!
前言 微软宣布重磅消息将把 GitHub Copilot Chat 扩展的代码以 MIT 许可证协议开源,然后将扩展中的 AI 功能重构到 VS Code 核心中,这一举措是为了将 VS Code 成 ...
- 面试题:HashMap和Hashtable的区别和联系
摘要:从源码.特性和算法实现等几个角度归纳HashMap和Hashtable的区别和联系. HashMap与Hashtable的区别是面试中经常遇到的一个问题.此问题看似简单,但如若深挖,也可以学 ...
- cmake 简易教程
CMake 是一个跨平台的.开源的构建工具.cmake 是 makefile 的上层工具,它们的目的正是为了产生可移植的makefile,并简化自己动手写makefile时的巨大工作量,目前很多开源的 ...
- 2024杭电钉耙1-1003 HDOJ7435 树
本文同步发布于我的网站 Problem 给一棵根为 1 的有根树,点 \(i\) 具有一个权值 \(A_i\) . 定义一个点对的值 \(f(u, v)=\max \left(A_u, A_v\rig ...
- Castle Defense
你需要最大化被数量最少的弓箭手保护的墙被弓箭手保护的数量.想到什么,对了,二分答案. 对 $check$ 函数进行思考. 令答案为 $m$. 如果一个点的值小于 $m$,则考虑将其变成 $m$,那么将 ...
- ArkUI-X在Android上使用Fragment开发指南
本文介绍将ArkUI框架的UIAbility跨平台部署至Android平台Fragment的使用说明,实现Android原生Fragment和ArkUI跨平台Fragment的混合开发,方便开发者灵活 ...
- 开源项目丨Taier1.2版本发布,新增工作流、租户绑定简化等多项功能
2022年7月26日,Taier1.2版本正式发布! 本次版本发布更新功能: 新增工作流 新增OceanBase SQL 新增Flink jar任务 数据同步.实时采集支持脏数据管理 Hive UDF ...
- Web前端入门第 69 问:JavaScript Promise 提供的方法都使用过吗?
Promise 这个 API 曾在 JS 领域掀起过血雨腥风,以前的大佬们都喜欢手搓一个自己的 Promise 用以理解 Promise 的原理. Promise 的诞生,应该多少都有受到 jQuer ...
- vert.x 初识
中文文档:https://vertx-china.github.io/ 官方文档:https://vertx.io/ 客户端仓库模块:https://github.com/vert-x3/vertx- ...
- ET6.0运行Demo和工具使用
环境:Mac + Rider + ET6.0 一:运行Demo 1:下载ET6.0,get:https://github.com/egametang/ET 2:下载.net core 5.0.ET6. ...