0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

什么是责任链?

汽车电子技术 来源:程序猿知秋 作者: 程序猿知秋 2023-02-16 14:41 次阅读

什么是责任链?

责任链模式是行为模式的一种,它将需要触发的Handler组成一条链,发送者将请求发给链的第一个接收者,并且沿着这条链传递,直到有一个Handler来处理它或者直到最后也没有对象处理而留在链末尾端;责任连模式的重点是在链上,由一条链去处理相似的请求,在链中决定谁来处理这个请求

责任链分为纯责任链与不纯责任链(一般实战应用较多)

**纯职责链 **

1.每个处理者接收到请求后,要么单纯转发请求,要么单纯处理请求。不允许既处理请求,又转发请求的情况。

2.请求必须被责任链上的某个处理者处理。不允许出现请求未被处理的情况。

**不纯职责链 **

1.每个处理者接收到请求后,除了单纯转发请求,或者单纯处理请求,还可以部分处理请求后,转发。

2.请求可以不被责任链上的任何处理者处理。

责任链优点

1.解耦请求者和处理者。

2.非常灵活,可以任意组装

3.各个节点的责任明确

缺点

1.每次都是从链头开始。

2. 可能造成死循环。责任链如果是环状的,可能会导致循环调用,造成死循环。

纯责任链的代码Demo:

/**
     * 在公司OA系统请假审批流程
如果请假小于3天只需要项目经理批复就行;
如果请假大于等于3天,小于7天需要人事经理批复了;
如果请假大于等于7天,小于15天需要总经理批复了;
如果申请请假大于等于15天,决绝批复......
     * @param args
     */
 public static void main(String[] args) {
        Leader manager = new Manager("张三");
        Leader hrManager = new HrManager("李四");
        Leader generalManager = new GeneralManager("王麻子");


        //组织责任链对象的关系
        manager.setNextLeader(hrManager);
        hrManager.setNextLeader(generalManager);
        //请假
        LeaveRequest request = new LeaveRequest("parry", 10, "回家相亲!");
        manager.dealLeaveRequest(request);
  }

public abstract class Leader {
    // 领导姓名
    protected String name;
    // 责任链上的后继对象
    protected Leader nextLeader;
    public Leader(String name) {
        super();
        this.name = name;
    }


    public void setNextLeader(Leader nextLeader) {
        this.nextLeader = nextLeader;
    }

    public abstract void dealLeaveRequest(LeaveRequest request);
}

  public class HrManager extends Leader{
      public HrManager(String name) {
          super(name);
      }


      @Override
      public void dealLeaveRequest(LeaveRequest request) {
        if (3 <= request.getLeaveDay() && request.getLeaveDay() < 7) {
            System.out.println("人事经理:" + name + " 审批了 " + request.getEmployee() + "请假" + request.getLeaveDay()
                    + "天的请求,请假原因:" + request.getReason());
        } else {
            if (this.nextLeader != null) {
                this.nextLeader.dealLeaveRequest(request);
            }
        }
    }
}


public class GeneralManager extends Leader {
    public GeneralManager(String name) {
        super(name);
    }


    @Override
    public void dealLeaveRequest(LeaveRequest request) {
        if (7 <= request.getLeaveDay() && request.getLeaveDay() <= 15) {
            System.out.println("总经理:" + name + " 审批了 " + request.getEmployee() + "请假" + request.getLeaveDay()
                    + "天的请求,请假原因:" + request.getReason());
        } else {
            System.out.println(
                    "总经理:" + name + " 拒绝了 " + request.getEmployee() + "请假" + request.getLeaveDay() + "天的请求,请假不能超过15天");
        }
    }
}


public class Manager extends Leader{
    public Manager(String name) {
        super(name);
    }


    @Override
    public void dealLeaveRequest(LeaveRequest request) {
        if (request.getLeaveDay() < 3) {
            System.out.println("经理:" + name + " 审批了 " + request.getEmployee() + "请假" + request.getLeaveDay()
                    + "天的请求,请假原因:" + request.getReason());
        } else {
            if (this.nextLeader != null) {
                this.nextLeader.dealLeaveRequest(request);
            }
        }
    }
}


@Data
public class LeaveRequest {
   //姓名
    private String name;
   //请假天数
    private int leaveDay;
    //请假原因
    private String reason;


    public LeaveRequest(String name, int leaveDay, String reason) {
        this.name=name;
        this.leaveDay=leaveDay;
        this.reason=reason;
    }  
}

电商售后使用责任链(不纯责任链)

售后业务梳理

电商售后常见三种模式:

仅退款、退款退货、退款换货

售后业务可分为

仅退款: 采购商申请——>商家审核——>完成

退款退货:采购商申请——>商家审核——>采购商发货——>商家确认收货——>完成

退款换货:采购商申请——>商家审核——>采购商发货——>商家确认收货——>商家发出新品——>采购商确认收货——>完成

仅退款的实际退款等操作在商家审核时,而退款退货和退款换货则在确认收货时。

以下为售后责任链流程:

售后->校验退款单状态->原路退款(以下单支付方式为准)->退积分或其它优惠->更新订单及对应商品退款信息->保存结算->保存财务流水->保存/更新退款日志->发送退款成功异步消息

三种售后的核心退款业务流程基本是一致的,少个别节点业务逻辑有所区别,将核心业务抽成责任链的各个节点,这对售后来说,代码的复用性提高了很多,同时业务处理更加清晰,犯错率大大降低。

以下为售后中代码使用Demo

定义一个节点的基类接口

public interface BaseRefundHandler {
    void handle(PipelineContext context); 
}

售后责任链组装,以下以仅退款为例

public class RefundPipeBean {
/**
 * 仅退款,责任链初始化节点
 */
public List<String> refundPipe = new ArrayList<>();


  public List<String> getRefundPipe() {
      refundPipe.add("checkRefundStatus"); //校验退款单状态
      refundPipe.add("refundMoney");  //原路退款(获取订单支付方式)
      refundPipe.add("returnScore");  //退积分或其它优惠券类
       ......
      return refundPipe;
  }


  @Bean
  @Scope("prototype")
  public CheckRefundStatus checkRefundStatus() {return new CheckRefundStatus();}

  @Bean
  @Scope("prototype")
  public RefundMoney refundMoney() {return new RefundMoney();}
  ......
}

** 注: 这个配置就等同于之前在xml里的配置**

"checkRefundStatus" class="com.xx.CheckRefundStatus"/>

创建一个启动监听器

@Component
public class RefundPipeListener extends ApplicationObjectSupport implements InitializingBean {
    private static Map<String, List> handlersMap = new HashMap<>();
     
   public static Map<String, List> getHandlersMap() {
        return handlersMap;
    }

    //最好定义成全局的,此处因演示 才在类中写 。 责任链的名称
   public static String ONLY_REFUND="ONLY_REFUND";
  @Override
  public void afterPropertiesSet() throws Exception {
    RefundPipeBean refundPipeBean=new RefundPipeBean();
     //装载退款业务链.....
    List normalHandlers=new ArrayList<>();

    for (String s : refundPipeBean.getRefundPipe()) {
        BaseRefundHandler normalHandler = (BaseRefundHandler) getApplicationContext().getBean(s);
        normalHandlers.add(normalHandler);
        handlersMap.put(ONLY_REFUND, normalHandlers);
    } 
  }
}

创建节点传递对象所用POJO类

@Data
public class PipelineContext<K, V> extends ConcurrentHashMap<K, V> {
    protected boolean success = false;
    //责任链结束标识
    protected boolean isEnd = false;
    protected String resultCode;
    private  Object data;


    public boolean isSuccess() {
        return success;
    }
    public void setSuccess(boolean success) {
        this.success = success;
    }


    public boolean isEnd() {
        return isEnd;
    }


    public void setEnd(boolean end) {
        isEnd = end;
    }
}


public class RefundPipelineContext<K, V> extends PipelineContext<K, V> {
    /**
     * 封装退款单信息
    */
    private RefundInfoPipeVo refundInfoPipeVo;


    public RefundInfoPipeVo getRefundInfoPipeVo() {
        return refundInfoPipeVo;
    }


    public void setRefundInfoPipeVo(RefundInfoPipeVo refundInfoPipeVo) {
        this.refundInfoPipeVo = refundInfoPipeVo;
    }
}

创建节点

public class CheckRefundStatus implements BaseRefundHandler {
  @Override
  public void handle(PipelineContext<String, RefundInfoPipeVo> context) {
     //业务逻辑 todo
     ......
   //表示该节点运行正常,可以继续向下走
   context.setSuccess(true);
  }
}

业务调用层

@RestController
public class RefundInfoController {
  @Autowired
  RefundInfoService refundInfoService;

  @ApiOperation("仅退款")
  @RequestMapping(value = "/auditRefund", method = {RequestMethod.GET, RequestMethod.POST}, produces = "application/json;charset=UTF-8")
  public RespData<Boolean> auditRefund(xxx) {
      refundInfoService.auditRefund(xxx);
      return RespData.success("审核成功",true);
  }
}


public interface RefundInfoService {
  void auditRefund(xxx);
}


@Service("refundInfoService")
public class RefundInfoServiceImpl implements RefundInfoService {


    @Override
    public void auditRefund(xxx) {
        //业务逻辑 todo 
        RefundInfoResultVo refundInfoResultVo = refundInfoMapper.queryById(platformId, refundId);
        ......
        PipelineContext<String, RefundInfoPipeVo> refund = new RefundPipelineContext<>();
        //在责任链中传递参数对象
        refund.put("refund", refundInfoResultVo);
        Map<String, List> map = RefundPipelineChangeListener.getHandlersMap();
        //通过责任链的名称获取对应链 。 此处key值应为一个全局的常量,与上面监听器中的链条名一致
        List baseRefundHandlers = map .get(ONLY_REFUND); 
        for (BaseRefundHandler handler : baseRefundHandlers) {
            handler.handle(refund);
            if (refund.isEnd()) {
                System.out.println("责任链执行结束...");
                break;
            }
            if (!refund.isSuccess()) {
                        System.out.println("责任链执行失败...");
                break;
            }
        }
    }
}

整体总结

以上是责任链在业务中创建及使用的流程。

同时以上流程也还存在一些可优化点:

  1. 责任链节点硬编码问题
  2. 添加同步事务控制
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 模式
    +关注

    关注

    0

    文章

    63

    浏览量

    13291
  • handler
    +关注

    关注

    0

    文章

    7

    浏览量

    2992
收藏 人收藏

    评论

    相关推荐

    谈工程事故的监理责任

    谈工程事故的监理责任,工程监理是我国改革开放以后,推行的工程建设管理制度。它是国家工程管理走向集约化、法制化、规范化的基础。这项制度的建立需要一个不断的充实和
    发表于 01-12 14:07 6次下载

    监理责任的错位

    关于监理责任,目前,建筑市场上很多问题正在引起业内人士的思考。我们感觉到在当前的建筑市场管理中,对违章责任的追究上,有错位的现象,而对于监理的要求几近苛刻,这
    发表于 01-23 14:09 9次下载

    电池车间生产之如何培养员工责任

    电池车间生产之如何培养员工责任心  很多人应该都听说过这样一个故事:从前,有两个石匠为建造寺庙而打凿石头,一位道人问他们正在做什
    发表于 10-30 14:21 846次阅读

    物联网技术正在重组保险报价索赔和责任业务

    毫无疑问,自动机器和汽车将围绕责任展开新的对话,在美国47个州,法律要求道路上的所有车辆都必须投保。目前,司机既负责购买保险,也承担事故责任,随着自动驾驶汽车的出现,责任问题变得异常复杂。产品
    发表于 11-12 10:15 1223次阅读

    AI智能测温系统担起企业社会责任 旷视获2020年度责任创新企业

      12月16日,“2020年责任中国·CSR年度盛典”在广州举办,年度热心公益、参与抗疫救灾、助力扶贫攻坚、坚守质量创新、维护消费者责任的优秀企业代表等评选结果正式揭晓。凭借在科技抗疫方面的成效
    的头像 发表于 12-28 11:44 2052次阅读

    高通公司发布《2020年企业责任报告》

    2月4日消息,日前,高通公司发布《2020年企业责任报告》,公布了公司在2020年的环境、社会与治理(ESG)表现。
    的头像 发表于 02-04 09:12 1472次阅读

    积极践行社会责任,编程猫荣获“2021年度新锐责任企业”奖项

    近日,由南方周末主办的第十三届中国企业社会责任年会举行,围绕“绿色发展”、乡村教育等热点领域展开,并重磅揭晓年度各大责任奖项获奖名单。编程教育品牌编程猫凭借在公益方面的创新实践,荣获“2021年度
    发表于 08-04 09:31 419次阅读
    积极践行社会<b class='flag-5'>责任</b>,编程猫荣获“2021年度新锐<b class='flag-5'>责任</b>企业”奖项

    中兴通讯A股和H股均被纳入富时社会责任指数系列

    近日,中兴通讯A股入选富时社会责任指数系列(FTSE4Good Index Series)。至此,中兴通讯A股和H股均被纳入富时社会责任指数系列。
    的头像 发表于 12-24 16:20 1616次阅读

    中兴通讯荣获“2022年度责任治理”奖项

    近日,中兴通讯在南方周末报社主办的第十四届中国企业社会责任年会上荣获“2022年度责任治理”奖项。
    的头像 发表于 08-03 10:12 1221次阅读

    光峰科技荣获社会责任先锋企业奖

    日前,由上海报业集团指导,权威财经媒体财联社主办,2022年财联社第三届ESG企业高峰论坛在上海顺利举行。会上,2022财联社ESG致远奖重磅发布,光峰科技以高质量社会责任履责,荣获“社会责任先锋
    的头像 发表于 12-21 17:36 1082次阅读

    紫光展锐荣膺责任商业联盟(RBA)银牌认证,获国际认可

    近日,紫光展锐成功通过责任商业联盟(Responsible Business Alliance,简称RBA)的审核验证,成为RBA银牌会员,这标志着紫光展锐的企业社会责任管理及可持续性发展获得国际知名联盟的权威认可。
    的头像 发表于 01-29 15:43 930次阅读

    如何用责任链默认优雅地进行参数校验

    那么有什么更好的参数校验的方式呢?本文就推荐一种通过责任链设计模式来优雅地实现参数的校验功能,我们通过一个用户注册的例子来讲明白如何实现。
    的头像 发表于 04-06 15:00 321次阅读

    责任链设计模式详解

    责任链模式是一种行为设计模式, 允许你将请求沿着处理者链进行发送。收到请求后, 每个处理者均可对请求进行处理, 或将其传递给链上的下个处理者。
    的头像 发表于 05-22 15:12 252次阅读
    <b class='flag-5'>责任</b>链设计模式详解

    AMD借助创新与合作推进企业责任

    — AMD的节能、高性能产品和深度合作助力解决全球最重要的挑战— 加利福尼亚州圣克拉拉市, 2023年8月24日—AMD(纳斯达克:AMD)今日发布年度企业责任报告,详细阐述了公司在环境可持续发展
    的头像 发表于 08-25 12:58 231次阅读

    芯原股份正式发布《2023年社会责任报告》

    芯原股份正式发布《2023年社会责任报告》,叙述了芯原2023年在追求经营绩效的同时,积极践行社会责任的工作成果,主动回应利益相关方及社会各界的关注重点。
    的头像 发表于 04-01 09:32 156次阅读
    芯原股份正式发布《2023年社会<b class='flag-5'>责任</b>报告》