【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 中 ...
随机推荐
- 题解:P4586 [FJOI2015] 最小覆盖双圆问题
写了这么久终于过了,发篇题解记录一下. 第一次写黑题题解,写的不好请见谅. 目录 本题思路 三点定圆 最小圆覆盖 关于最小圆覆盖时间复杂度 回到本题 二分法划分点集 总时间复杂度 最小覆盖双圆问题代码 ...
- RBMQ案例二:工作队列模式
工作队列模式 工作队列(又名:任务队列)背后的主要思想是避免立即执行资源密集型任务而不得不等待它完成.相反,我们安排任务稍后完成.我们将任务封装 为消息并将其发送到队列.在后台运行的工作进程将弹出任务 ...
- windows环境下的常用命令
1.appwiz.cpl 程序和功能 2.certmgr.msc 证书管理实用程序 3.control 控制面板 4.firewall.cpl 防火墙 5.fsmgmt.msc 共享文件夹管理器 6. ...
- AI面试助手面试精灵重磅发布“双栏模式”:极速和精准可以兼得
引言 面试中的每一秒都至关重要,许多求职者反馈:面对面试官的犀利提问,要么因"卡壳"错失良机,要么因追求准确而延误回答时机.作为以顶级GPT为核心的AI面试助手,面试精灵始终致力于 ...
- Spring扩展接口-BeanFactoryPostProcessor
.markdown-body { line-height: 1.75; font-weight: 400; font-size: 16px; overflow-x: hidden; color: rg ...
- 一文搞懂K8s中的RBAC认证授权
概述 官方文档: https://kubernetes.io/zh-cn/docs/reference/access-authn-authz/authorization/ https://kubern ...
- Go mod/work/get ... Golang 提供的项目管理工具该怎么用?
自 Go 1.11 版本引入 模块(modules) 的概念以来,Go 语言的项目管理和依赖管理方式发生了根本性的变革.这一变化旨在解决早期 GOPATH 模式带来的种种不便,让项目结构更加清晰,依赖 ...
- SRv6 验证实验
本文分享自天翼云开发者社区<SRv6 验证实验>,作者:f****n 引言 Segment Routing over IPv6 (SRv6) 是一种基于 IPv6 的新兴网络架构,其通过在 ...
- Java 开发者无痛迁移到 Cursor 开启AI编程新生涯
习惯了IntelliJ IDEA的Java开发者,想尝试Cursor.Windsurf或Trae这类新兴的AI IDE,却担心迁移成本? 本文分享我的实战经验,帮助你高效切换开发环境,保留核心效率.效 ...
- 层次分析法的Python实现--数学建模学习日志
数学建模比赛即将到来,大家应该都投身于学习当中了,b站上比较热门的一个课程是 b站数学建模学习视频 在这里讲解了数学建模常见的方法和写论文的要点,同时up主贴心地有所有方法的源码实现,但是全部都是ma ...