仅以自己理解的表述,有错误请指出!
责任链模式顾名思义是一个链!比如从1 - 9 有9条链路,如果使用责任链的话需要把每个使用的链路都走一遍。
举个例子:在商城系统里创建订单需要生产订单信息,其中包含商品与用户的信息,商品的基本信息,营销规则信息,商品打折后信息,员工信息,员工提成信息,最后生成完整的订单信息。
使用责任链的话获取各个模块信息的接口都可以定义为一个链路,然后注册相应的链路进行生产订单信息,接下来看代码。
1.注册链路类(负责注册链路,简单的讲就是把业务需要执行的模块添加到责任链的链中组成一个完整的链路)
/**
* 链路处理工程类
* @author houGJ
* @date 2022/06/24/10:27
*/
public abstract class OrdersAbsChainFactory extends OrdersAbsChainHandler {
public abstract void registerHandler(OrdersAbsChainHandler ordersAbsChainHandler);
}
2.链路具体处理方法类(主要负责按顺序执行注册好的链路)
/**
* @author houGJ
* @date 2022/06/24/10:48
*/
public class OrderImplFactory extends OrdersAbsChainFactory {
private Integer index = 0;
private List absChainHandlerList = new LinkedList<>();
@Override
public void registerHandler(OrdersAbsChainHandler ordersAbsChainHandler) {
absChainHandlerList.add(ordersAbsChainHandler);
}
@Override
public String createOrder(OrderParams orderParams, OrdersAbsChainFactory ordersAbsChainFactory) {
// 所有链路结束
if(index == absChainHandlerList.size()){
return "end";
}
OrdersAbsChainHandler ordersAbsChainHandler = absChainHandlerList.get(index);
index++;
return ordersAbsChainHandler.createOrder(orderParams, ordersAbsChainFactory);
}
}
3.每个链路要执行的父类方法(将每个链路要调用的方法放在一起)
/**
* 方法所属类
* @author houGJ
* @date 2022/06/24/10:29
*/
public interface OrdersAbsChainMethod {
String createOrder(OrderParams orderParams, OrdersAbsChainFactory ordersAbsChainFactory);
}
4.方法的实现类
/**
* 方法实现类
* @author houGJ
* @date 2022/06/24/10:31
*/
public class OrdersAbsChainHandler implements OrdersAbsChainMethod {
@Override
public String createOrder(OrderParams orderParams, OrdersAbsChainFactory ordersAbsChainFactory) {
return orderParams.getCode();
}
}
5.链路1
/**
* OrderItemLink
* @author houGJ
* @date 2022/06/24/10:37
*/
public class OrderItemLink extends OrdersAbsChainHandler {
@Override
public String createOrder(OrderParams orderParams, OrdersAbsChainFactory ordersAbsChainFactory) {
orderParams.setCode(orderParams.getCode() + "hgj1");
System.out.println("链路 1");
System.out.println("orderParams1 = " + orderParams);
return ordersAbsChainFactory.createOrder(orderParams, ordersAbsChainFactory);
}
}
6.链路2
/**
*
* @author houGJ
* @date 2022/06/24/10:40
*/
public class ShopLink extends OrdersAbsChainHandler {
@Override
public String createOrder(OrderParams orderParams, OrdersAbsChainFactory ordersAbsChainFactory) {
System.out.println("链路 2");
orderParams.setCode(orderParams.getCode() + "hgj2");
System.out.println("orderParams2 = " + orderParams);
return ordersAbsChainFactory.createOrder(orderParams, ordersAbsChainFactory);
}
}
7.链路3
/**
*
* @author houGJ
* @date 2022/06/24/10:42
*/
public class StaffLink extends OrdersAbsChainHandler {
@Override
public String createOrder(OrderParams orderParams, OrdersAbsChainFactory ordersAbsChainFactory) {
orderParams.setCode("冠军");
System.out.println("链路 2");
System.out.println("orderParams3 = " + orderParams);
return ordersAbsChainFactory.createOrder(orderParams, ordersAbsChainFactory);
}
}
8.实体
/**
* 参数
* @author houGJ
* @date 2022/06/24/10:35
*/
public class OrderParams {
private String code;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public OrderParams(String code) {
this.code = code;
}
@Override
public String toString() {
return "OrderParams{" +
"code='" + code + '\'' +
'}';
}
}
9.执行责任链
public class Clinet {
public static void main(String[] args) {
// 创建商品
OrderParams orderParams = new OrderParams("hgj");
System.out.println("orderParams = " + orderParams);
// 创建链路
OrderItemLink orderItemLink = new OrderItemLink();
ShopLink shopLink = new ShopLink();
StaffLink staffLink = new StaffLink();
// 注册处理器
OrdersAbsChainFactory ordersAbsChainFactory = new OrderImplFactory();
ordersAbsChainFactory.registerHandler(orderItemLink);
ordersAbsChainFactory.registerHandler(shopLink);
ordersAbsChainFactory.registerHandler(staffLink);
// 执行
String order = ordersAbsChainFactory.createOrder(orderParams, ordersAbsChainFactory);
System.out.println("执行结束 = " + order);
}
}
链的执行的顺序就是按照你注册处理器的顺序。最后通过链路工厂的实现类(2)调用具体方法实现类(4)获取到 链路1-链路2-链路3 依次处理过的返回值。
讲的可能不太清楚,不懂的可以把代码粘贴到本地跑一下就ok了!
谢谢!