责任链模式实现校验
·
背景
在我们的项目中,我们通过责任链模式实现订单下单时的各种前置校验。
责任链设计模式介绍
责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,可以通过将一系列处理器按顺序链接起来,使得每个处理器都有机会处理请求,从而实现请求的传递和处理。
代码实现
抽象接口
先定义一个接口,其中定义两个方法:
/**
* 订单校验
*
*/
public interface OrderCreateValidator {
/**
* 设置下一个校验器
*
* @param nextValidator
*/
void setNext(OrderCreateValidator nextValidator);
/**
* 校验
*
* @param request
* @throws Exception
*/
void validate(OrderCreateRequest request) throws Exception;
}
setNext用于设置下一个处理器,validate 方法用于做请求检验。接下来实现三个具体的校验器:
具体实现类
用户校验器
主要判断用户状态是否正常:
@Component
public class UserValidator implements OrderCreateValidator {
private OrderCreateValidator nextValidator;
@Autowired
private UserFacadeService userFacadeService;
@Override
public void setNext(OrderCreateValidator nextValidator) {
this.nextValidator = nextValidator;
}
@Override
public void validate(OrderCreateRequest request) throws Exception {
String buyerId = request.getBuyerId();
UserQueryRequest userQueryRequest = new UserQueryRequest();
userQueryRequest.setUserId(Long.valueOf(buyerId));
UserQueryResponse<UserInfo> userQueryResponse = userFacadeService.query(userQueryRequest);
if (userQueryResponse.getSuccess() && userQueryResponse.getData() != null) {
UserInfo userInfo = userQueryResponse.getData();
if (userInfo.getUserRole() != null && userInfo.getUserRole().equals(UserRole.CUSTOMER)) {
throw new Exception("买家不能是平台用户");
}
//判断买家状态
if (userInfo.getState() != null && !userInfo.getState().equals(UserStateEnum.ACTIVE.name())) {
throw new Exception("买家状态异常");
}
//判断买家状态
if (userInfo.getState() != null && !userInfo.getCertification()) {
throw new Exception("买家未完成实名认证");
}
}
}
}
库存校验器
主要校验库存情况:
@Component
public class StockValidator extends BaseOrderCreateValidator {
@Autowired
private InventoryWrapperService inventoryWrapperService;
@Override
public void doValidate(OrderCreateRequest request) throws OrderException {
BaseGoodsInventoryVO goodsInventoryVO = inventoryWrapperService.queryInventory(request);
if (goodsInventoryVO == null) {
throw new OrderException(INVENTORY_NOT_ENOUGH);
}
if (goodsInventoryVO.getInventory() == 0) {
throw new OrderException(INVENTORY_NOT_ENOUGH);
}
if (goodsInventoryVO.getQuantity() < request.getItemCount()) {
throw new OrderException(INVENTORY_NOT_ENOUGH);
}
if (goodsInventoryVO.getInventory() < request.getItemCount()) {
throw new OrderException(INVENTORY_NOT_ENOUGH);
}
}
}
商品校验器
主要校验商品可售情况:
@Component
public class GoodsValidator extends BaseOrderCreateValidator {
@Autowired
private GoodsFacadeService goodsFacadeService;
@Override
protected void doValidate(OrderCreateRequest request) throws OrderException {
BaseGoodsVO baseGoodsVO = goodsFacadeService.getGoods(request.getGoodsId(), request.getGoodsType());
if (!baseGoodsVO.available()) {
throw new OrderException(GOODS_NOT_AVAILABLE);
}
if (baseGoodsVO.getPrice().compareTo(request.getItemPrice()) != 0) {
throw new OrderException(GOODS_PRICE_CHANGED);
}
}
}
分别实现了商品、用户以及库存的校验,每一个校验器只关心自己要校验的数据即可,如果有需要更多的东西需要校验,可以扩展出更多的校验器即可。
编排责任链
接下来就是把他们编排到一起:
@Configuration
public class OrderCreateValidatorConfig {
@Autowired
private StockValidator stockValidator;
@Autowired
private GoodsValidator goodsValidator;
@Autowired
private UserValidator userValidator;
@Bean
public OrderCreateValidator orderValidatorChain() {
userValidator.setNext(goodsValidator);
goodsValidator.setNext(stockValidator);
return userValidator;
}
}
通过定义一个OrderCreateValidator的 bean,把他们连在一起,即先进行用户的校验、其次进行商品和库存的校验。
调用
接下来,就可以在我们想要做校验的地方调用orderValidatorChain.validate进行校验了:
@Override
@DistributeLock(keyExpression = "#request.identifier", scene = "ORDER_CREATE")
@Facade
public OrderResponse create(OrderCreateRequest request) {
try {
orderValidatorChain.validate(request);
} catch (Exception e) {
return new OrderResponse.OrderResponseBuilder().buildFail(ORDER_CREATE_VALID_FAILED.getCode(), e.getMessage());
}
Boolean preDeductResult = inventoryWrapperService.preDeduct(request);
if (preDeductResult) {
return orderService.create(request);
}
throw new OrderException(OrderErrorCode.INVENTORY_DEDUCT_FAILED);
}
更多推荐
所有评论(0)