目录
概念
责任链模式 是一种行为设计模式
可以通过将一系列处理器按照顺序连接起来
使每个处理器都有机会处理请求
我理解的责任链的实现类似于链表
每个节点跑向下一个节点 执行逻辑后
总体分为三步
- 定义责任链接口validator
- 实现责任链接口后写不同责任链实现类
- 使用一个validatorConfig把不同责任链编排在一起
我们定义责任链模式接口
我们接口中有三个方法
设置下一个校验器
返回下一个校验器
校验逻辑接口
package cn.hollis.nft.turbo.order.validator;
import cn.hollis.nft.turbo.api.order.request.OrderCreateRequest;
import cn.hollis.nft.turbo.order.OrderException;
/**
* 订单校验
* 责任链模式
* @author Hollis
*/
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;
}
这边使用了模版方法的设计模式进行了二次封装
package cn.hollis.nft.turbo.order.validator;
import cn.hollis.nft.turbo.api.order.request.OrderCreateRequest;
import cn.hollis.nft.turbo.order.OrderException;
/**
* 订单校验
*
* @author Hollis
*/
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;
}
各个节点的具体逻辑
用户校验器
package cn.hollis.nft.turbo.order.validator;
import cn.hollis.nft.turbo.api.order.request.OrderCreateRequest;
import cn.hollis.nft.turbo.api.user.constant.UserRole;
import cn.hollis.nft.turbo.api.user.constant.UserStateEnum;
import cn.hollis.nft.turbo.api.user.request.UserQueryRequest;
import cn.hollis.nft.turbo.api.user.response.UserQueryResponse;
import cn.hollis.nft.turbo.api.user.response.data.UserInfo;
import cn.hollis.nft.turbo.api.user.service.UserFacadeService;
import cn.hollis.nft.turbo.order.OrderException;
import static cn.hollis.nft.turbo.api.order.constant.OrderErrorCode.*;
/**
* 用户校验器,继承自 BaseOrderCreateValidator,用于校验订单创建请求中的买家信息。
* 主要校验买家的角色、状态以及认证情况,若不符合要求则抛出相应的订单异常。
*
* @author hollis
*/
public class UserValidator extends BaseOrderCreateValidator {
/**
* 用户服务接口,用于查询用户信息。
*/
private UserFacadeService userFacadeService;
/**
* 实现父类的抽象方法,对订单创建请求中的买家信息进行校验。
*
* @param request 订单创建请求对象,包含买家信息。
* @throws OrderException 当买家信息不符合要求时,抛出相应的订单异常。
*/
@Override
public void doValidate(OrderCreateRequest request) throws OrderException {
// 从订单创建请求中获取买家 ID
String buyerId = request.getBuyerId();
// 创建用户查询请求对象,将买家 ID 转换为 Long 类型
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);
}
}
}
/**
* 有参构造函数,用于注入用户服务接口。
*
* @param userFacadeService 用户服务接口实例,用于查询用户信息。
*/
public UserValidator(UserFacadeService userFacadeService) {
this.userFacadeService = userFacadeService;
}
/**
* 无参构造函数。
* 注意:此构造函数未被使用,若后续无使用需求可考虑移除。
*/
public UserValidator() {
}
}
库存校验器
package cn.hollis.nft.turbo.order.validator;
import cn.hollis.nft.turbo.api.inventory.request.InventoryRequest;
import cn.hollis.nft.turbo.api.inventory.service.InventoryFacadeService;
import cn.hollis.nft.turbo.api.order.request.OrderCreateRequest;
import cn.hollis.nft.turbo.base.response.SingleResponse;
import cn.hollis.nft.turbo.order.OrderException;
import static cn.hollis.nft.turbo.api.order.constant.OrderErrorCode.INVENTORY_NOT_ENOUGH;
/**
* 库存校验器,继承自 BaseOrderCreateValidator,用于在订单创建时校验商品库存是否充足。
* 如果库存不足,将抛出相应的订单异常。
*
* @author hollis
*/
public class StockValidator extends BaseOrderCreateValidator {
/**
* 库存服务接口,用于查询商品库存信息。
*/
private InventoryFacadeService inventoryFacadeService;
/**
* 实现父类的抽象方法,对订单创建请求进行库存校验。
*
* @param request 订单创建请求对象,包含商品相关信息。
* @throws OrderException 当库存不足时,抛出库存不足的订单异常。
*/
@Override
public void doValidate(OrderCreateRequest request) throws OrderException {
// 创建库存查询请求对象
InventoryRequest inventoryRequest = new InventoryRequest();
// 设置要查询的商品 ID
inventoryRequest.setGoodsId(request.getGoodsId());
// 设置要查询的商品类型
inventoryRequest.setGoodsType(request.getGoodsType());
// 设置要查询的商品标识
inventoryRequest.setIdentifier(request.getIdentifier());
// 设置要查询的商品数量,即订单中请求的商品数量
inventoryRequest.setInventory(request.getItemCount());
// 调用库存服务接口查询商品库存
SingleResponse<Integer> response = inventoryFacadeService.queryInventory(inventoryRequest);
// 如果库存查询失败
if (!response.getSuccess()) {
// 抛出库存不足的订单异常
throw new OrderException(INVENTORY_NOT_ENOUGH);
}
// 获取查询到的商品库存数量
Integer inventory = response.getData();
// 如果库存数量为 0
if (inventory == 0) {
// 抛出库存不足的订单异常
throw new OrderException(INVENTORY_NOT_ENOUGH);
}
// 如果库存数量小于订单请求的商品数量
if (inventory < request.getItemCount()) {
// 抛出库存不足的订单异常
throw new OrderException(INVENTORY_NOT_ENOUGH);
}
}
/**
* 有参构造函数,用于注入库存服务接口。
*
* @param inventoryFacadeService 库存服务接口实例,用于查询商品库存信息。
*/
public StockValidator(InventoryFacadeService inventoryFacadeService) {
this.inventoryFacadeService = inventoryFacadeService;
}
/**
* 无参构造函数。
* 注意:此构造函数未初始化 inventoryFacadeService,若使用可能会导致空指针异常,建议根据实际情况移除或完善。
*/
public StockValidator() {
}
}
商品校验器
package cn.hollis.nft.turbo.order.validator;
import cn.hollis.nft.turbo.api.goods.constant.GoodsState;
import cn.hollis.nft.turbo.api.goods.model.BaseGoodsVO;
import cn.hollis.nft.turbo.api.goods.service.GoodsFacadeService;
import cn.hollis.nft.turbo.api.order.request.OrderCreateRequest;
import cn.hollis.nft.turbo.order.OrderException;
import static cn.hollis.nft.turbo.api.order.constant.OrderErrorCode.GOODS_NOT_AVAILABLE;
import static cn.hollis.nft.turbo.api.order.constant.OrderErrorCode.GOODS_PRICE_CHANGED;
/**
* 商品校验器,继承自 BaseOrderCreateValidator,用于在订单创建时校验商品状态和价格。
* 若商品不可售或价格发生变化,则抛出相应的订单异常。
*
* @author hollis
*/
public class GoodsValidator extends BaseOrderCreateValidator {
/**
* 商品服务接口,用于获取商品信息。
*/
private GoodsFacadeService goodsFacadeService;
/**
* 实现父类的抽象方法,对订单创建请求中的商品信息进行校验。
*
* @param request 订单创建请求对象,包含商品 ID、商品类型和商品价格等信息。
* @throws OrderException 当商品不可售或商品价格发生变化时,抛出相应的订单异常。
*/
@Override
protected void doValidate(OrderCreateRequest request) throws OrderException {
// 调用商品服务接口,根据订单请求中的商品 ID 和商品类型获取商品信息
BaseGoodsVO baseGoodsVO = goodsFacadeService.getGoods(request.getGoodsId(), request.getGoodsType());
// 如果商品状态既不是在售状态,也不是已售罄状态,则认为商品不可售
// 说明:包含 SOLD_OUT 状态是因为商品查询接口会获取 Redis 中的最新库存,
// 下单时 Redis 库存可能已扣减至 0
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);
}
}
/**
* 有参构造函数,用于注入商品服务接口。
*
* @param goodsFacadeService 商品服务接口实例,用于获取商品信息。
*/
public GoodsValidator(GoodsFacadeService goodsFacadeService) {
this.goodsFacadeService = goodsFacadeService;
}
/**
* 无参构造函数。
* 注意:此构造函数未初始化 goodsFacadeService,使用时可能会导致空指针异常,
* 若后续无使用需求,可考虑移除。
*/
public GoodsValidator() {
}
}
把责任链编排在一起
调用每一个责任链节点的setNext方法
把下一个责任链节点对象放进去
类似于调用链表的set方法
package cn.hollis.nft.turbo.order.domain.validator;
import cn.hollis.nft.turbo.order.validator.GoodsBookValidator;
import cn.hollis.nft.turbo.order.validator.GoodsValidator;
import cn.hollis.nft.turbo.order.validator.OrderCreateValidator;
import cn.hollis.nft.turbo.order.validator.UserValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 订单创建校验器配置
*
* @author hollis
*/
@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;
}
}