基于责任链模式的参数校验
- 介绍
- 接口定义
- 根实现类
- 具体校验器的实现
-
- 用户校验器
- 商品校验器
- 预定校验器
- 库存校验器
- 责任链的编排
- 使用
介绍
责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,可以通过将一系列处理器按顺序链接起来,使得每个处理器都有机会处理请求,从而实现请求的传递和处理。
此处我们用一个创建订单的例子 在创建订单前进行各种的前置校验
接口定义
java
public interface OrderCreateValidator {
/**
* 设置下一个校验器
*
* @param nextValidator
*/
public void setNext(OrderCreateValidator nextValidator);
/**
* 返回下一个校验器
*
* @return
*/
public OrderCreateValidator getNext();
/**
* 校验
*
* @param request
* @throws OrderException 订单异常
*/
public void validate(OrderCreateRequest request) throws OrderException;
}
根实现类
java
public abstract class BaseOrderCreateValidator implements OrderCreateValidator {
protected OrderCreateValidator nextValidator;
@Override
public void setNext(OrderCreateValidator nextValidator) {
this.nextValidator = nextValidator;
}
@Override
public OrderCreateValidator getNext() {
return nextValidator;
}
/**
* 校验
*
* @param request
* @throws Exception
*/
@Override
public void validate(OrderCreateRequest request) throws OrderException {
doValidate(request);
if (nextValidator != null) {
nextValidator.validate(request);
}
}
/**
* 校验方法的具体实现
*
* @param request
* @throws OrderException
*/
protected abstract void doValidate(OrderCreateRequest request) throws OrderException;
}
具体校验器的实现
用户校验器
java
public class UserValidator extends BaseOrderCreateValidator {
private UserFacadeService userFacadeService;
@Override
public void doValidate(OrderCreateRequest request) throws OrderException {
String buyerId = request.getBuyerId();
UserQueryRequest userQueryRequest = new UserQueryRequest(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 OrderException(BUYER_IS_PLATFORM_USER);
}
//判断买家状态
if (userInfo.getState() != null && !userInfo.getState().equals(UserStateEnum.ACTIVE.name())) {
throw new OrderException(BUYER_STATUS_ABNORMAL);
}
//判断买家状态
if (userInfo.getState() != null && !userInfo.getCertification()) {
throw new OrderException(BUYER_NOT_AUTH);
}
}
}
public UserValidator(UserFacadeService userFacadeService) {
this.userFacadeService = userFacadeService;
}
public UserValidator() {
}
}
商品校验器
java
public class GoodsValidator extends BaseOrderCreateValidator {
private GoodsFacadeService goodsFacadeService;
@Override
protected void doValidate(OrderCreateRequest request) throws OrderException {
BaseGoodsVO baseGoodsVO = goodsFacadeService.getGoods(request.getGoodsId(), request.getGoodsType());
// 如果商品不是可售状态,则返回失败
// PS:可售状态为什么要包含SOLD_OUT呢?因为商品查询的接口中去查询了 Redis 的最新库存,而 Redis 的库存在下单时可能已经扣减过刚好为0了,所以这里要包含 SOLD_OUT
if (baseGoodsVO.getState() != GoodsState.SELLING && baseGoodsVO.getState() != GoodsState.SOLD_OUT) {
throw new OrderException(GOODS_NOT_AVAILABLE);
}
if (baseGoodsVO.getPrice().compareTo(request.getItemPrice()) != 0) {
throw new OrderException(GOODS_PRICE_CHANGED);
}
}
public GoodsValidator(GoodsFacadeService goodsFacadeService) {
this.goodsFacadeService = goodsFacadeService;
}
public GoodsValidator() {
}
}
预定校验器
java
public class GoodsBookValidator extends BaseOrderCreateValidator {
private GoodsFacadeService goodsFacadeService;
@Override
protected void doValidate(OrderCreateRequest request) throws OrderException {
BaseGoodsVO baseGoodsVO = goodsFacadeService.getGoods(request.getGoodsId(), request.getGoodsType());
if(baseGoodsVO.canBook()){
Boolean hasBooked = goodsFacadeService.isGoodsBooked(request.getGoodsId(), request.getGoodsType(), request.getBuyerId());
if (!hasBooked) {
throw new OrderException(GOODS_NOT_BOOKED);
}
}
}
public GoodsBookValidator(GoodsFacadeService goodsFacadeService) {
this.goodsFacadeService = goodsFacadeService;
}
public GoodsBookValidator() {
}
}
库存校验器
java
public class GoodsBookValidator extends BaseOrderCreateValidator {
private GoodsFacadeService goodsFacadeService;
@Override
protected void doValidate(OrderCreateRequest request) throws OrderException {
BaseGoodsVO baseGoodsVO = goodsFacadeService.getGoods(request.getGoodsId(), request.getGoodsType());
if(baseGoodsVO.canBook()){
Boolean hasBooked = goodsFacadeService.isGoodsBooked(request.getGoodsId(), request.getGoodsType(), request.getBuyerId());
if (!hasBooked) {
throw new OrderException(GOODS_NOT_BOOKED);
}
}
}
public GoodsBookValidator(GoodsFacadeService goodsFacadeService) {
this.goodsFacadeService = goodsFacadeService;
}
public GoodsBookValidator() {
}
}
责任链的编排
实现配置类
java
@Configuration
public class OrderCreateValidatorConfig {
@Autowired
private GoodsValidator goodsValidator;
@Autowired
private UserValidator userValidator;
@Autowired
private GoodsBookValidator goodsBookValidator;
@Bean
public OrderCreateValidator orderValidatorChain() {
userValidator.setNext(goodsValidator);
goodsValidator.setNext(goodsBookValidator);
return userValidator;
}
}
使用
java
//责任链模式 订单创建前的参数校验
orderPreValidatorChain.validate(orderCreateRequest);