在 Spring Boot 中,如何干掉 if else 呢?
原文链接:https://blog.csdn.net/hncu1306602liuqiang
看到crossover Jie的文章《利用策略模式优化过多if else 代码》后受到启发,可以利用策略模式简化过多的if else代码。
需求
这里虚拟一个业务需求,让大家容易理解。假设有一个订单系统,里面的一个概念是根据订单的不同类型做出不同的处理。
项目结构
订单实体
/**
* 订单实体
*/
publicclassOrderDTO {
private String code;
private BigDecimal price;
/*
* 订单类型:
* 1:普通订单
* 2:团购订单
* 3:促销订单
*/
private String type;
//getter,setter自己实现
}
service接口
/**
* 订单处理
*/
publicinterfaceIOrderService{
/**
* 根据订单的不同类型做出不同的处理
*
* @param dto 订单实体
* @return 为了简单,返回字符串
*/
String orderHandler(OrderDTO dto);
}
//实现类1
@Component
publicclassOrderServiceImplimplementsIOrderService{
@Override
public String orderHandler(OrderDTO dto){
if ("1".equals(dto.getType())) {
//普通订单处理
} elseif ("2".equals(dto.getType())) {
//团购订单处理
} elseif ("3".equals(dto.getType())) {
//促销订单处理
}
//未来订单类型增加
}
}
//实现类二
@Component
publicclassOrderServiceImplimplementsIOrderService{
//使用策略模式实现
@Autowired
private HandlerContext handlerContext;
@Override
public String orderHandler(OrderDTO dto){
/*
* 1:使用if..else实现
* 2:使用策略模式实现
*/
AOrderTypeHandler instance = handlerContext.getInstance(dto.getType());
return instance.handler(dto);
}
}
利用策略模式只需要2行代码就可以搞定(也可以用工厂)
HandlerContext和HandlerProccessor
/**
* 订单策略模式环境
* 这个类的注入由HandlerProccessor实现
*/
publicclassHandlerContext {
private Map<String, AOrderTypeHandler> handlerMap;
/**
* 构造传参不能直接使用注解扫入
*/
publicHandlerContext(Map<String, AOrderTypeHandler> handlerMap) {
this.handlerMap = handlerMap;
}
/**
* 获得实例
*
* @param type
* @return
*/
public AOrderTypeHandler getInstance(String type) {
if (type == null) {
thrownew IllegalArgumentException("type参数不能为空");
}
AOrderTypeHandler clazz = handlerMap.get(type);
if (clazz == null) {
thrownew IllegalArgumentException("该类型没有在枚举OrderTypeHandlerAnno中定义,请定义:" + type);
}
return clazz;
}
}
/**
* 策略模式,处理type与实现类的映射关系
*/
@Component
publicclassHandlerProccessorimplementsBeanFactoryPostProcessor{
/**
* 扫描@OrderTypeHandlerAnno注解,初始化HandlerContext,将其注册到spring容器
*
* @param beanFactory bean工厂
* @throws BeansException
*/
@Override
publicvoidpostProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)throws BeansException {
Map<String, AOrderTypeHandler> handlerMap = new HashMap<>();
for (OrderTypeEnum temp : OrderTypeEnum.values()) {
AOrderTypeHandler beanInstacle = getBeansWithAnnotation(beanFactory, AOrderTypeHandler.class, OrderTypeHandlerAnno.class, temp.getCode());
handlerMap.put(temp.getCode(), beanInstacle);
}
HandlerContext context = new HandlerContext(handlerMap);
//单例注入
beanFactory.registerSingleton(HandlerContext.class.getName(), context);
}
/*
* 通过父类+注解找到实体类
*/
private <T> T getBeansWithAnnotation(ConfigurableListableBeanFactory beanFactory, Class<T> manager, Class<? extends OrderTypeHandlerAnno> annotation, String code)throws BeansException {
if (ObjectUtils.isEmpty(code)) {
thrownew RuntimeException("code is null ");
}
Collection<T> tCollection = beanFactory.getBeansOfType(manager).values();
for (T t : tCollection) {
OrderTypeHandlerAnno orderTypeHandlerAnno = t.getClass().getAnnotation(annotation);
if (ObjectUtils.isEmpty(orderTypeHandlerAnno)) {
thrownew RuntimeException("该注解没有写入值 :" + code);
}
//注解值是否与code相等
if (code.equals(orderTypeHandlerAnno.value().getCode())) {
return t;
}
}
thrownew RuntimeException("通过code没有找到该注解对应的实体类 :" + code);
}
}
父抽象类+注解+枚举
/**
* 订单类型处理定义
* 使用抽象类,那么子类就只有一个继承了
*/
publicabstractclassAOrderTypeHandler{
/**
* 一个订单类型做一件事
*
* @param dto 订单实体
* @return 为了简单,返回字符串
*/
abstractpublic String handler(OrderDTO dto);
}
/**
* 订单类型注解
* 使用方式:
* 1:普通订单 @OrderTypeHandlerAnno("1")
* 2:团购订单 @OrderTypeHandlerAnno("2")
* 3:促销订单 @OrderTypeHandlerAnno("3")
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public@interface OrderTypeHandlerAnno {
OrderTypeEnum value();
}
/**
* 订单类型枚举
*/
publicenum OrderTypeEnum {
Normal("1", "普通"),
Group("2", "团队"),
Promotion("3", "促销");
private String code; //代码
private String name; //名称,描述
OrderTypeEnum(String code, String name) {
this.code = code;
this.name = name;
}
public String getCode(){
return code;
}
publicvoidsetCode(String code){
this.code = code;
}
public String getName(){
return name;
}
publicvoidsetName(String name){
this.name = name;
}
/**
* 根据code属性获取name属性
*
* @param code
* @return
*/
publicstatic String getNameByCode(String code){
for (OrderTypeEnum temp : OrderTypeEnum.values()) {
if (temp.getCode().equals(code)) {
return temp.getName();
}
}
returnnull;
}
}
业务人员实现类
//业务代码
/**
* 普通订单处理
*/
@Component
@OrderTypeHandlerAnno(OrderTypeEnum.Normal)
publicclassNormalOrderHandlerextendsAOrderTypeHandler{
@Override
public String handler(OrderDTO dto){
return"处理普通订单";
}
}
/**
* 团队订单处理
*/
@Component
@OrderTypeHandlerAnno(OrderTypeEnum.Group)
publicclassGroupOrderHandlerextendsAOrderTypeHandler{
@Override
public String handler(OrderDTO dto){
return"处理团队订单";
}
}
/**
* 促销订单处理
*/
@Component
@OrderTypeHandlerAnno(OrderTypeEnum.Promotion)
publicclassPromotionOrderHandlerextendsAOrderTypeHandler{
@Override
public String handler(OrderDTO dto){
return"处理促销订单";
}
}
测试结果(使用chrome浏览器测试结果)
如果类型不存在
controller
/**
* 策略模式
*/
@RestController
public classStrategyController{
@Resource(name = "orderServiceImpl")
private IOrderService orderService;
@GetMapping("/api/order")
@ResponseBody
public String orderSave(OrderDTO dto) {
String str = orderService.orderHandler(dto);
return"{\"status\":1,\"msg\":\"保存成功\",\"data\":\"" + str + "\"}";
}
}
pom.xml文档
<?xml version="1.0" encoding="UTF-8"?>
<projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/><!-- lookup parent from repository -->
</parent>
<groupId>com.kayak</groupId>
<artifactId>study-design</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>study-design</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
总结:
利用策略模式可以简化复杂的if else代码,方便维护,而利用自定义注解和自注册的方式,可以方便应对需求的变更。
主要是方便了业务人员编写代码。
这个就是个人笔记,不喜勿喷。
—————END—————
PS:如果觉得我的分享不错,欢迎大家随手点赞、在看。
关注公众号:Java后端编程,回复下面关键字
要Java学习完整路线,回复 路线
缺Java入门视频,回复: 视频
要Java面试经验,回复 面试
缺Java项目,回复: 项目
进Java粉丝群: 加群
PS:如果觉得我的分享不错,欢迎大家随手点赞、在看。
请备注:666,不然不通过~
最近好文
最新评论
推荐文章
作者最新文章
你可能感兴趣的文章
Copyright Disclaimer: The copyright of contents (including texts, images, videos and audios) posted above belong to the User who shared or the third-party website which the User shared from. If you found your copyright have been infringed, please send a DMCA takedown notice to [email protected]. For more detail of the source, please click on the button "Read Original Post" below. For other communications, please send to [email protected].
版权声明:以上内容为用户推荐收藏至CareerEngine平台,其内容(含文字、图片、视频、音频等)及知识版权均属用户或用户转发自的第三方网站,如涉嫌侵权,请通知[email protected]进行信息删除。如需查看信息来源,请点击“查看原文”。如需洽谈其它事宜,请联系[email protected]。
版权声明:以上内容为用户推荐收藏至CareerEngine平台,其内容(含文字、图片、视频、音频等)及知识版权均属用户或用户转发自的第三方网站,如涉嫌侵权,请通知[email protected]进行信息删除。如需查看信息来源,请点击“查看原文”。如需洽谈其它事宜,请联系[email protected]。