前言
一直负责部门的订单模块,从php转到Java也是如此,换了一种语言来实现订单相关功能。那么Spring里有很多已经搭建好基础模块的设计模式来帮助我们解耦实际业务中的逻辑,用起来非常的方便!就比如我们的订单操作模块。生成订单后,有很多操作。比如:取消、支付、关闭....等等。那么用设计模式的思想去处理这些不同的操作,最好用的就是策略模式来解决它们!把不同的操作分配到不同的实现类里去。这不,我发现了一个不错的东西Spring plugin
!
Spring Plugin
Spring plugin
这个小东西我也是在看一些开源项目才看到的,感觉还不错。就立马拿来用了下,把它带到我们业务场景里去。这不,带大家体验下。
下面用Spring plugin
来重构下订单的相关操作实现。这里我们只模拟,支付和关闭的操作。最后再来简单分析下Spring plugin
的原理
实战
首先呢、定义一个操作类型的枚举类,来边界下当前我们系统支持的操作类型!
public enum OrderOperatorType {
/**
* 关闭
*/
CLOSED,
/**
* 支付
*/
PAY
;
}
第二步、定义操作接口,实现Spring plugin
的Plugin<S>
接口,和配置插件
public interface OrderOperatorPlugin extends Plugin<OrderOperatorDTO> {
/**
* 定义操作动作
* @param operator
* @return
*/
public Optional<?> apply(OrderOperatorDTO operator);
}
//配置插件,插件写好了,我们要让插件生效!
@Configuration
@EnablePluginRegistries({OrderOperatorPlugin.class})
public class OrderPluginConfig {
}
第三步 、定义具体的实现类(支付操作、关闭操作)
@Component
public class PayOperator implements OrderOperatorPlugin {
@Override
public Optional<?> apply(OrderOperatorDTO operator) {
//支付操作
//doPay()
return Optional.of("支付成功");
}
@Override
public boolean supports(OrderOperatorDTO operatorDTO) {
return operatorDTO.getOperatorType() == OrderOperatorType.PAY;
}
}
@Component
public class ClosedOperator implements OrderOperatorPlugin {
@Override
public Optional<?> apply(OrderOperatorDTO operator) {
//关闭操作
//doClosed()
return Optional.of("关闭订单成功");
}
@Override
public boolean supports(OrderOperatorDTO operatorDTO) {
return operatorDTO.getOperatorType() == OrderOperatorType.CLOSED;
}
}
这里要注意的是实现 supports
方法,此方法返回的是一个boolean
值,直观的看起来就是一个选择器的条件,这里可直接认为,当Support
返回True
的时候,就找到了当前操作的实现类!
两个不同的实现类定义好,那么我们怎么找到具体的实现类呢?
最后、定义业务接口,和业务实现类
public interface OrderService {
/**
* 操作订单接口
* @param operator
* @return
*/
Optional<?> operationOrder(OrderOperatorDTO operator);
}
@Service
public class OrderServiceImpl implements OrderService {
@Resource
PluginRegistry<OrderOperatorPlugin, OrderOperatorDTO> orderOperatorPluginRegistry;
@Override
public Optional<?> operationOrder(OrderOperatorDTO operator) {
OrderOperatorPlugin pluginFor = orderOperatorPluginRegistry.getPluginFor(operator);
return pluginFor.apply(operator);
}
}
在业务接口实现类里我们注入了
@Resource
PluginRegistry<OrderOperatorPlugin, OrderOperatorDTO> orderOperatorPluginRegistry;
名字一定是 接口名 + Registry,我这里是orderOperatorPluginRegistry
至于为什么要这样写,等回我们分析源码的时候看一下。目前这样写就对了。
接下来我们测试下
@RunWith(SpringRunner.class)
@SpringBootTest
public class OrderOperatorPluginTest {
@Resource
OrderService orderService;
@Resource
ApplicationContext applicationContext;
@Test
public void test_operation_closed() {
final OrderOperatorDTO operator = new OrderOperatorDTO();
operator.setOperatorType(OrderOperatorType.CLOSED);
Optional<?> optionalO = orderService.operationOrder(operator);
Assertions.assertEquals("关闭订单成功", optionalO.get());
}
@Test
public void test_operation_pay() {
final OrderOperatorDTO operator = new OrderOperatorDTO();
operator.setOperatorType(OrderOperatorType.PAY);
Optional<?> optionalO = orderService.operationOrder(operator);
Assertions.assertEquals("支付成功", optionalO.get());
}
}
这个运行结果是没有问题的,可以自己把代码下载下来,跑一下~~