文章目录
- 【设计模式】行为型模式:责任链模式
【设计模式】行为型模式:责任链模式
顾名思义,责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。
在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。
在工作中,遇到这么一个需求,有一个下单流程很复杂,其中某一个环节不通过,则直接返回失败,否则需要走完所有流程,例如下面几个步骤:
- 1、判断用户是否已经登录
- 2、判断用户是不是在系统黑名单
- 3、判断下单参数是否完整,并检查格式
- 4、判断收货地址是不是在配送范围内
- 5、判断用户能否使用优惠卷
- …
- …
- …
- 最后,创建订单,保存订单,并发送短信给客户
我们就以这个流程为案例来分析责任链模式在实际生产中的应用
1、创建一个订单上下文
package com.example.chain;
import lombok.Data;
@Data
public class OrderContext {
/**
* 请求唯一序列ID
*/
private String seqId;
/**
* 用户ID
*/
private String userId;
/**
* 产品skuId
*/
private Long skuId;
/**
* 下单数量
*/
private Integer amount;
/**
* 用户收货地址ID
*/
private String userAddressId;
}
2、创建抽象订单处理
package com.example.chain;
/**
* 抽象订单处理
*/
public abstract class AbstractOrderHandle {
/**
* 责任链,下一个链接节点
*/
private AbstractOrderHandle next;
/**
* 执行入口
*
* @param context
* @return
*/
public OrderContext execute(OrderContext context) {
context = handle(context);
// 判断是否还有下个责任链节点,没有的话,说明已经是最后一个节点
if (getNext() != null) {
getNext().execute(context);
}
return context;
}
/**
* 对参数进行处理
*
* @param context
* @return
*/
public abstract OrderContext handle(OrderContext context);
public AbstractOrderHandle getNext() {
return next;
}
public void setNext(AbstractOrderHandle next) {
this.next = next;
}
}
3、编写处理流程的节点,我这里写了三个为例
package com.example.chain.handle;
import com.example.chain.AbstractOrderHandle;
import com.example.chain.OrderContext;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Order(1)
@Component
public class OneOrderHandle extends AbstractOrderHandle {
@Override
public OrderContext handle(OrderContext context) {
System.out.println("责任链1");
return context;
}
}
package com.example.chain.handle;
import com.example.chain.AbstractOrderHandle;
import com.example.chain.OrderContext;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Order(2)
@Component
public class TwoOrderHandle extends AbstractOrderHandle {
@Override
public OrderContext handle(OrderContext context) {
System.out.println("责任链2");
return context;
}
}
package com.example.chain.handle;
import com.example.chain.AbstractOrderHandle;
import com.example.chain.OrderContext;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Order(3)
@Component
public class ThreeOrderHandle extends AbstractOrderHandle {
@Override
public OrderContext handle(OrderContext context) {
System.out.println("责任链3");
return context;
}
}
4、创建订单责任链管理
package com.example.chain;
import lombok.RequiredArgsConstructor;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.Collections;
import java.util.List;
/**
* 订单责任链管理
*/
@Component
@RequiredArgsConstructor
public class OrderHandleManager {
private final List<AbstractOrderHandle> orderHandleList;
@PostConstruct
public void init() {
//如果List没有按照@Order注解方式排序,可以通过如下方式手动排序
Collections.sort(orderHandleList, AnnotationAwareOrderComparator.INSTANCE);
int size = orderHandleList.size();
for (int i = 0; i < size; i++) {
if (i == size - 1) {
orderHandleList.get(i).setNext(null);
} else {
orderHandleList.get(i).setNext(orderHandleList.get(i + 1));
}
}
}
/**
* 执行处理
*
* @param context
* @return
*/
public OrderContext execute(OrderContext context) {
context = orderHandleList.get(0).execute(context);
return context;
}
}
5、 编写测试接口
package com.example.chain;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequiredArgsConstructor
public class TestController {
private final OrderHandleManager orderHandleManager;
@GetMapping("/test")
public void test() {
OrderContext context = orderHandleManager.execute(new OrderContext());
System.out.println(context.toString());
}
}
到此责任链模式就完成了