责任链模式样例(基于SpringBoot)
责任链模式,简而言之,就是将多个操作组装成一条链路进行处理。请求在链路上传递,链路上的每一个节点就是一个处理器,每个处理器都可以对请求进行处理,或者传递给链路上的下一个处理器处理。一、AbstractCheckHandler抽象类处理器/*** 抽象类处理器*/@Componentpublic abstract class AbstractCheckHandler {/*** 当前处理器持有下一个
总体来说设计模式分为三大类:
创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
行为型模式 -> 责任链模式,简而言之,就是将多个操作组装成一条链路进行处理。请求在链路上传递,链路上的每一个节点就是一个处理器,每个处理器都可以对请求进行处理,或者传递给链路上的下一个处理器处理。
一、责任链模式Demo1
1、AbstractCheckHandler抽象类处理器
/**
* 抽象类处理器
*/
@Component
public abstract class AbstractCheckHandler {
/**
* 当前处理器持有下一个处理器的引用
*/
@Getter
@Setter
private AbstractCheckHandler nextHandler;
/**
* 处理器执行方法
* @param param
* @return
*/
public abstract Result handle(ProductVO param);
/**
* 处理器配置
*/
@Setter
@Getter
protected ProductCheckHandlerConfig config;
/**
* 链路传递
* @param param
* @return
*/
protected Result next(ProductVO param) {
//下一个链路没有处理器了,直接返回
if (Objects.isNull(nextHandler)) {
return Result.success();
}
//执行下一个处理器
return nextHandler.handle(param);
}
}
AbstractCheckHandler表示处理器抽象类,负责抽象处理器行为。其有3个子类,分别是:
NullValueCheckHandler:空值校验处理器
PriceCheckHandler:价格校验处理
StockCheckHandler:库存校验处理器
AbstractCheckHandler 抽象类中,handle()定义了处理器的抽象方法,其子类需要重写handle()方法以实现特殊的处理器校验逻辑;
protected ProductCheckHandlerConfig config 是处理器的动态配置类,使用protected声明,每个子类处理器都持有该对象。该对象用于声明当前处理器、以及当前处理器的下一个处理器nextHandler,另外也可以配置一些特殊属性,比如说接口降级配置、超时时间配置等。
AbstractCheckHandler nextHandler 是当前处理器持有的下一个处理器的引用,当前处理器执行完毕时,便调用nextHandler执行下一处理器的handle()校验方法;
protected Result next() 是抽象类中定义的,执行下一个处理器的方法,使用protected声明,每个子类处理器都持有该对象。当子类处理器执行完毕(通过)时,调用父类的方法执行下一个处理器nextHandler。
HandlerClient 是执行处理器链路的客户端,HandlerClient.executeChain()方法负责发起整个链路调用,并接收处理器链路的返回值。
2、ProductCheckHandlerConfig处理器配置类
/**
* 处理器配置类
*/
@AllArgsConstructor
@Data
public class ProductCheckHandlerConfig {
/**
* 处理器Bean名称
*/
private String handler;
/**
* 下一个处理器,递归设计方式
*/
private ProductCheckHandlerConfig next;
/**
* 是否降级
*/
private Boolean down = Boolean.FALSE;
}
3、HandlerClient
/**
* 责任链模式之客户端
*/
public class HandlerClient {
/**
* 执行链路
* @param handler 处理器
* @param param 商品参数
* @return
*/
public static Result executeChain(AbstractCheckHandler handler, ProductVO param) {
//执行处理器
Result handlerResult = handler.handle(param);
if (!handlerResult.isSuccess()) {
System.out.println("HandlerClient 责任链执行失败返回:" + handlerResult.toString());
return handlerResult;
}
return Result.success();
}
}
4、校验处理器
/**
* 空值校验处理器
*/
@Component
public class NullValueCheckHandler extends AbstractCheckHandler {
@Override
public Result handle(ProductVO param) {
System.out.println("空值校验 NullValueCheckHandler 开始...");
//降级:如果配置了降级,则跳过此处理器,执行下一个处理器
if (super.getConfig().getDown()) {
System.out.println("空值校验 NullValueCheckHandler 已降级,跳过空值校验 NullValueCheckHandler...");
return super.next(param);
}
//参数必填校验
if (Objects.isNull(param)) {
return Result.failure(ErrorCode.PARAM_NULL_ERROR);
}
//SkuId商品主键参数必填校验
if (Objects.isNull(param.getSkuId())) {
return Result.failure(ErrorCode.PARAM_SKU_NULL_ERROR);
}
//Price价格参数必填校验
if (Objects.isNull(param.getPrice())) {
return Result.failure(ErrorCode.PARAM_PRICE_NULL_ERROR);
}
//Stock库存参数必填校验
if (Objects.isNull(param.getStock())) {
return Result.failure(ErrorCode.PARAM_STOCK_NULL_ERROR);
}
System.out.println("空值校验 NullValueCheckHandler 通过...");
//执行下一个处理器
return super.next(param);
}
}
/**
* 价格校验处理器
*/
@Component
public class PriceCheckHandler extends AbstractCheckHandler {
@Override
public Result handle(ProductVO param) {
System.out.println("价格校验 PriceCheckHandler 开始...");
//非法价格校验
boolean illegalPrice = param.getPrice().compareTo(BigDecimal.ZERO) <= 0;
if (illegalPrice) {
return Result.failure(ErrorCode.PARAM_PRICE_ILLEGAL_ERROR);
}
//其他校验逻辑...
System.out.println("价格校验 PriceCheckHandler 通过...");
//执行下一个处理器
return super.next(param);
}
}
/**
* 库存校验处理器
*/
@Component
public class StockCheckHandler extends AbstractCheckHandler {
@Override
public Result handle(ProductVO param) {
System.out.println("库存校验 StockCheckHandler 开始...");
//非法库存校验
boolean illegalStock = param.getStock() < 0;
if (illegalStock) {
return Result.failure(ErrorCode.PARAM_STOCK_ILLEGAL_ERROR);
}
//其他校验逻辑..
System.out.println("库存校验 StockCheckHandler 通过...");
//执行下一个处理器
return super.next(param);
}
}
5、ProductService
@Component
public class ProductService {
/**
* 使用Spring注入:所有继承了AbstractCheckHandler抽象类的Spring Bean都会注入进来。Map的Key对应Bean的name,Value是name对应相应的Bean
*/
@Resource
private Map<String, AbstractCheckHandler> handlerMap;
/**
* 创建商品
* @return
*/
public Result createProduct(ProductVO param) {
//参数校验,使用责任链模式
Result paramCheckResult = this.paramCheckChain(param);
if (!paramCheckResult.isSuccess()) {
return paramCheckResult;
}
//创建商品
return this.saveProduct(param);
}
/**
* 参数校验:责任链模式
* @param param
* @return
*/
private Result paramCheckChain(ProductVO param) {
//获取处理器配置:通常配置使用统一配置中心存储,支持动态变更
ProductCheckHandlerConfig handlerConfig = this.getHandlerConfigFile();
//获取处理器
AbstractCheckHandler handler = this.getHandler(handlerConfig);
//责任链:执行处理器链路
Result executeChainResult = HandlerClient.executeChain(handler, param);
if (!executeChainResult.isSuccess()) {
System.out.println("创建商品 失败...");
return executeChainResult;
}
//处理器链路全部成功
return Result.success();
}
/**
* 获取处理器配置:通常配置使用统一配置中心存储,支持动态变更
* @return
*/
private ProductCheckHandlerConfig getHandlerConfigFile() {
//模拟配置中心存储的配置
String configJson = "{\"handler\":\"nullValueCheckHandler\",\"down\":false,\"next\":{\"handler\":\"priceCheckHandler\",\"next\":{\"handler\":\"stockCheckHandler\",\"next\":null}}}";
//转成Config对象,含有下一节点的handler
ProductCheckHandlerConfig handlerConfig = JSON.parseObject(configJson, ProductCheckHandlerConfig.class);
return handlerConfig;
}
/**
* 获取处理器
* @param config
* @return
*/
private AbstractCheckHandler getHandler (ProductCheckHandlerConfig config) {
//配置检查:没有配置处理器链路,则不执行校验逻辑
if (Objects.isNull(config)) {
return null;
}
//配置错误,则返回空
String handler = config.getHandler();
if (StringUtils.isBlank(handler)) {
return null;
}
//配置了不存在的处理器,则返回空
AbstractCheckHandler abstractCheckHandler = handlerMap.get(config.getHandler());
if (Objects.isNull(abstractCheckHandler)) {
return null;
}
//处理器设置配置Config
abstractCheckHandler.setConfig(config);
//递归设置链路处理器
abstractCheckHandler.setNextHandler(this.getHandler(config.getNext()));
return abstractCheckHandler;
}
private Result saveProduct(ProductVO param) {
System.out.println("保存商品 成功...");
return Result.success(param);
}
}
configJson转换后JSON格式为
6、测试类ChainTests
场景1:正确输入商品参数
@SpringBootTest
public class ChainTests {
@Resource
ProductService productService;
@Test
void test1() {
ProductVO param = ProductVO.builder()
.skuId(123L)
.skuName("测试商品")
.imgPath("http://..")
.price(new BigDecimal(1))
.stock(1)
.build();
productService.createProduct(param);
}
}
场景2:创建商品参数中有空值(如下skuId参数为null),链路被空值处理器截断,返回错误信息
@Test
void contextLoads() {
ProductVO param = ProductVO.builder()
.skuId(null)
.skuName("测试商品")
.imgPath("http://..")
.price(new BigDecimal(12))
.stock(1)
.build();
productService.createProduct(param);
}
场景3:创建商品价格参数异常(如下price参数),被价格处理器截断,返回错误信息
@Test
void contextLoads() {
ProductVO param = ProductVO.builder()
.skuId(11L)
.skuName("测试商品")
.imgPath("http://..")
.price(new BigDecimal(-101))
.stock(1)
.build();
productService.createProduct(param);
}
场景4:创建商品库存参数异常(如下stock参数),被库存处理器截断,返回错误信息
@Test
void contextLoads() {
ProductVO param = ProductVO.builder()
.skuId(11L)
.skuName("测试商品")
.imgPath("http://..")
.price(new BigDecimal(13))
.stock(-13)
.build();
productService.createProduct(param);
}
7、项目结构及代码
代码地址下载
二、责任链模式Demo2
原文–> 策略模式和责任链模式
责任链模式主要是解耦了请求与处理,客户只需将清求发送到链上即可,无需关心请求的具体内容
和处理细节,请求会自动进行传递直至有节点对象进行处理。
适用于以下应用场景 :
1)多个对象可以处理同一清求,但具体由哪个对象处理则在运行时动态决定;
2)不明确指定接收者的情况下,向多个对象中的—个提交—个请求;
3)可动态指定一组对象处理请求。
1、Member
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Member{
private String loginName;
private String loginPass;
private String roleName;
public Member(String loginName, String loginPass) {
this.loginName = loginName;
this.loginPass = loginPass;
}
}
2、Handler
public abstract class Handler {
protected Handler next;
public void next(Handler next){
this.next = next;
}
public abstract void doHandler(Member member);
}
3、ValidateHandler
public class ValidateHandler extends Handler {
@Override
public void doHandler(Member member) {
if (StringUtils.isEmpty(member.getLoginName()) || StringUtils.isEmpty(member.getLoginPass())) {
System.out.println("用户名和密码为空");
return;
}
System.out.println("用户名和密码不为空,可以往下执行");
next.doHandler(member);
}
}
4、LoginHandler
public class LoginHandler extends Handler {
@Override
public void doHandler(Member member) {
System.out.println("登录成功,可以往下执行");
member.setRoleName("管理员");
next.doHandler(member);
}
}
5、AuthHandler
public class AuthHandler extends Handler {
@Override
public void doHandler(Member member) {
if (!"管理员".equals(member.getRoleName())) {
System.out.println("您不是管理员,没有操作权限");
return;
}
System.out.println("允许操作");
}
}
6、MemberService
public class MemberService {
public void login(String loginName, String loginPass) {
Handler validateHandler = new ValidateHandler();
Handler loginHandler = new LoginHandler();
Handler authHandler = new AuthHandler();
validateHandler.next(loginHandler);
loginHandler.next(authHandler);
validateHandler.doHandler(new Member(loginName, loginPass));
}
}
7、测试
@Test
public void TestMemberService() {
MemberService memberService = new MemberService();
memberService.login("tom","666");
}
8、测试
9、项目
代码下载
原文链接
「实战设计模式专栏」之责任链模式
更多推荐
所有评论(0)