概述
程序中 if else 的判断本质是 条件和执行。
- 匹配:就是指条件判断,返回的值为 true, 比如:if(true), if(“a”.equals(“b”)) 等
- 执行:就是指符合条件判断后需要执行的代码
基于对 条件和执行 的认识,可以从结构上对程序进行改造,可以将 匹配 和 执行的部分拆开。
关键点
- 条件和执行逻辑上分离,有助于代码 解耦
- 条件可以通过 list 和 map 封装,借助 list 的遍历和 map 的 hash 找到需要执行的代码
- 执行的部分一般实现了函数式接口
- 条件和执行在 spring boot 项目中可以通过 @Configuration 进行初始化
具体做法
- 通过 list 结构
- 通过 map 结构
- 在 spring boot 项目中的应用
通过 list 结构
- KeyValuePair 类,封装了 条件和执行逻辑
@Data
@NoArgs Constructor
@AllArgsConstructor
@Builder
public static class KeyValuePair<Condition, Execution> {
private Condition mCondition;
private Execution mExecution;
}
- 订单实体类
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public static class OrderEntity {
private Long id;
private Long userId;
private OrderTypeEnum orderType;
private Date orderDate;
private BigDecimal orderAmount;
}
public static enum OrderTypeEnum {
online,
offline;
}
- 通过 list 来封装整个订单处理逻辑
@Test
public void test_order_list() {
List<KeyValuePair<OrderTypeEnum, Consumer<OrderEntity>>> orderHandlerList =
new ArrayList<KeyValuePair<OrderTypeEnum, Consumer<OrderEntity>>>() {{
add(KeyValuePair.<OrderTypeEnum, Consumer<OrderEntity>>builder()
.mCondition(OrderTypeEnum.online)
.mExecution(order -> {
System.out.println(
String .format("处理线上订单, 订单信息:%s", order.toString()));
})
.build());
add(KeyValuePair.<OrderTypeEnum, Consumer<OrderEntity>>builder()
.mCondition(OrderTypeEnum.offline)
.mExecution(order -> {
System.out.println(String.format("处理线下订单, 订单信息:%s",
order.toString()));
})
.build());
}};
final OrderEntity orderEntity = OrderEntity.builder()
.orderType(OrderTypeEnum.offline)
.orderAmount(BigDecimal.valueOf(23))
.build();
orderHandlerList.stream()
.filter(entity -> Objects.equals(entity.getMCondition(), orderEntity.getOrderType()))
.map(KeyValuePair::getMExecution)
.findAny()
.ifPresent(con -> con.accept(orderEntity));
}
通过 map 结构
- 通过 map 来封装订单处理逻辑
@Test
public void test_order_map() {
Map<OrderTypeEnum, Consumer<OrderEntity>> orderHandlerMap =
new HashMap <OrderTypeEnum, Consumer<OrderEntity>>() {{
put(OrderTypeEnum.online, order -> {
System.out.println(String.format("处理线上订单, 订单信息:%s",
order.toString()));
});
put(OrderTypeEnum.offline, order -> {
System.out.println(String.format("处理线下订单, 订单信息:%s",
order.toString()));
});
}};
OrderEntity orderEntity = OrderEntity.builder()
.orderType(OrderTypeEnum.online)
.orderAmount(BigDecimal.valueOf(23))
.build();
orderHandlerMap.get(orderEntity.getOrderType()).accept(orderEntity);
orderEntity = OrderEntity.builder()
.orderType(OrderTypeEnum.offline)
.orderAmount(BigDecimal.valueOf(23))
.build();
orderHandlerMap.get(orderEntity.getOrderType()).accept(orderEntity);
}
在 spring boot 项目中的应用
- 通过 @Configuration 类将订单处理逻辑 map 注册到 ioc 容器中,具体如下
package com.ckjava.test.config;
import com.ckjava.test.entity.OrderEntity;
import com.ckjava.test.entity.OrderTypeEnum;
import org.springframework.context. annotation .Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
import java.util. Function .Function;
/**
* Function: 订单处理器
*
* @author 执剑
* @date 2022/4/5
*/
@Configuration
public class OrderHandlerConfig {
@Bean
public Map<OrderTypeEnum, Function<OrderEntity, String>> orderHandlerMap() {
return new HashMap<OrderTypeEnum, Function<OrderEntity, String>>() {{
put(OrderTypeEnum.online, order -> {
return String.format("处理线上订单, 订单信息:%s",
order.toString());
});
put(OrderTypeEnum.offline, order -> {
return String.format("处理线下订单, 订单信息:%s",
order.toString());
});
}};
}
}
- 在 controller 中的使用如下
package com.ckjava.test.web;
import com.ckjava.test.entity.OrderEntity;
import com.ckjava.test.entity.OrderTypeEnum;
import com.ckjava.xutils.Constants;
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation. Request Body;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax .annotation.Resource;
import java.util.Map;
import java.util.function.Function;
@Api
@RestController
@RequestMapping(value = "/order", produces = "application/json; charset =utf-8")
public class OrderController implements Constants {
@Resource
private Map<OrderTypeEnum, Function<OrderEntity, String>> orderHandlerMap;
@PostMapping(value = "/handler")
public String orderHandler(@RequestBody OrderEntity orderEntity) {
return orderHandlerMap.get(orderEntity.getOrderType()).apply(orderEntity);
}
}