精华内容
下载资源
问答
  • Java设计模式实现一个责任链设计模式,从数据结构可以理解为单向链表
    千次阅读 热门讨论
    2021-05-18 09:31:28

    这个责任链是我用在项目中对标题的一些过滤处理,例如中英文数量、违禁词、特殊字符等

    定义一个抽象类,具体的过滤需要实现这个抽象类中的doFilter抽象方法

    public abstract class TitleFilterChain {
    
        protected static Logger logger = LoggerFactory.getLogger(com.rocket.copy.chain.TitleFilterChain.class);
    
        protected TitleFilterChain node;//节点,也就是在创建多个任务链时用于存储任务节点对象
    
        public void setNode(TitleFilterChain node) {
            this.node = node;
        }
    
        /**
         * false表示没有通过过滤, true表示通过过滤
         *
         * @param model
         * @param templateBo
         * @return
         */
        public abstract boolean doFilter(GoodsBaseModel model, CopyItemTemplate templateBo);
    
        /**
         * 每次子类执行完doFilter方法后会调用此方法
         *
         * @param filterResult 为false则断掉任务链
         * @param model        需要处理的数据模型
         * @param template     处理的规则模型
         * @return true则表示可以继续执行, false则表示没有通过过滤
         */
        protected boolean returnResult(boolean filterResult, GoodsBaseModel model, CopyItemTemplate template) {
            return filterResult ? (this.node == null ? true : node.doFilter(model, template)) : filterResult;
        }
    }
    

    写一个责任链创建的简单工厂类
    此方法可以生成链表的核心就是第二个私有方法,方法编写解释:
    这里从1开始的原因是需要返回的是一个链表,例如将2号子实现类设置到1号子实现类的节点中,假设当前i=1的i-1得到数组的0号下标的对象,然后0号调用setNode将1号设置为自己的节点,以此类推成为一个单向链表的数据结构,最终只需要将0号下标的实例返回出去即可得到一个责任链

    public class ChainFactory {
    
    
        public static TitleFilterChain getTitleFilterChain(Class<? extends TitleFilterChain>... classes) {
            TitleFilterChain[] chain = new TitleFilterChain[classes.length];
            for (int i = 0; i < classes.length; i++) {
                try {
                    chain[i] = classes[i].newInstance();//创建实例
                } catch (Exception e) {
                    //避免链条中断,设个默认通过过滤的节点
                    chain[i] = new TitleFilterChain() {
                        @Override
                        public boolean doFilter(GoodsBaseModel model, CopyItemTemplate templateBo) {
                            return true;
                        }
                    };
    
                }
            }
            return getTitleFilterChain(chain);
        }
    
        private static TitleFilterChain getTitleFilterChain(TitleFilterChain[] chain) {
            for (int i = 1; i < chain.length; i++) chain[i - 1].setNode(chain[i]);
            return chain[0];
        }
    
    }
    

    具体使用如下
    具体实现类中的业务代码就不进行展示了,这些类都继承了TitleFilterChain抽象类,实现了doFilter方法

     TitleFilterChain filterChain = ChainFactory.getTitleFilterChain(
                    TitleCharNumFilter.class, TitleEnglishAlphabetNumFilter.class,
                    TitleSpecialSymbolNumFilter.class, TitleKeyWordFilter.class);
     filterChain.doFilter(baseModel, copyParamModel.getTemplate());
    

    创建后的filterChain 如下图
    在这里插入图片描述

    更多相关内容
  • 责任链设计模式

    千次阅读 2020-04-19 15:55:20
    责任链模式(Responsibility Pattern), 是行为型设计模式之一。这种模型结构有点类似现实生活中铁链,由一个个铁环首尾相接构成一条链,如果这种结构用在编程领域,则每个节点可以看做一个对象,每个对象有不同的处理...

    一、责任链模式定义

    责任链模式(Responsibility Pattern), 是行为型设计模式之一。这种模型结构有点类似现实生活中铁链,由一个个铁环首尾相接构成一条链,如果这种结构用在编程领域,则每个节点可以看做一个对象,每个对象有不同的处理逻辑,将一个请求从链的首端发出,沿着链的路径依次传递每个节点对象,直到有对象处理这个请求为止,我们将这样一种模式称为责任链模式。

    二、责任链模式的使用场景

    1.多个对象可以处理同一个请求,但具体由哪个对象处理则在运行时动态决定
    2. 在请求处理者不明确的情况下,向多个对象中的一个提交一个请求
    3. 需要动态处理一组对象处理请求

    三、责任链模式的实现

    需求说明:
    采购审批需求说明,要求如下:
    1、如果金额小于等于5000元,由教学主任审批
    2、如果金额小于等于10000元,由院长审批
    3、如果金额小于等于30000元,由副校长审批
    4、如果金额大于30000元,由校长审批
    在这里插入图片描述
    PurchaseRequest类

    /**
     * 请求类
     */
    public class PurchaseRequest {
    
        private Integer type = 0;// 请求类型
    
        private Integer price = 0;// 金额
    
        private int id = 0;
    
        public PurchaseRequest(Integer type, Integer price, int id) {
            this.type = type;
            this.price = price;
            this.id = id;
        }
    
        public Integer getType() {
            return type;
        }
    
        public Integer getPrice() {
            return price;
        }
    
        public int getId() {
            return id;
        }
    
    }
    
    

    Approver 抽象类

    /**
     * 审批人 -- 抽象类
     */
    public abstract class Approver {
    
        // 下一个处理者
        Approver approver;
    
        // 姓名
        String name;
    
        public Approver(String name) {
            this.name = name;
        }
    
        // 下一个处理者
        public void setApprover(Approver approver) {
            this.approver = approver;
        }
    
        // 处理审批请求的方法,得到一个请求,处理是子类完成的,因此该方法做成抽象的
        public abstract void processRequest(PurchaseRequest purchaseRequest);
    
    }
    

    DepartmentApprover类

    /**
     * 系主任
     */
    public class DepartmentApprover extends Approver{
    
        public DepartmentApprover(String name) {
            super(name);
        }
    
        @Override
        public void processRequest(PurchaseRequest purchaseRequest) {
            if(purchaseRequest.getPrice()<=5000){
                System.out.println("请求编号:"+purchaseRequest.getId()+"被--"+this.name+"--处理了");
            }else{
                // 让下一个请求者处理请求
                approver.processRequest(purchaseRequest);
            }
        }
    
    }
    

    CollegeApprover类

    public class CollegeApprover extends Approver{
    
        public CollegeApprover(String name) {
            super(name);
        }
    
        @Override
        public void processRequest(PurchaseRequest purchaseRequest) {
            if(purchaseRequest.getPrice()<=10000 && purchaseRequest.getPrice()>5000){
                System.out.println("请求编号:"+purchaseRequest.getId()+"被--"+this.name+"--处理了");
            }else{
                // 让下一个请求者处理请求
                approver.processRequest(purchaseRequest);
            }
        }
    }
    

    ViceSchoolMasterApprover类

    public class ViceSchoolMasterApprover extends Approver{
    
        public ViceSchoolMasterApprover(String name) {
            super(name);
        }
    
        @Override
        public void processRequest(PurchaseRequest purchaseRequest) {
            if(purchaseRequest.getPrice()<=30000 && purchaseRequest.getPrice()>10000){
                System.out.println("请求编号:"+purchaseRequest.getId()+"被--"+this.name+"--处理了");
            }else{
                // 让下一个请求者处理请求
                approver.processRequest(purchaseRequest);
            }
        }
    
    }
    

    SchoolMasterApprover类

    public class SchoolMasterApprover extends Approver{
    
        public SchoolMasterApprover(String name) {
            super(name);
        }
    
        @Override
        public void processRequest(PurchaseRequest purchaseRequest) {
            if(purchaseRequest.getPrice()>30000){
                System.out.println("请求编号:"+purchaseRequest.getId()+"被--"+this.name+"--处理了");
            }else{
                // 让下一个请求者处理请求
                approver.processRequest(purchaseRequest);
            }
        }
    }
    

    Clinet类

    public class Clinet {
    
        public static void main(String[] args){
    
            // 创建一个请求
            PurchaseRequest purchaseRequest = new PurchaseRequest(2,28000,1);
    
            // 创建相关的审批人
            DepartmentApprover departmentApprover = new DepartmentApprover("张主任");
            CollegeApprover collegeApprover = new CollegeApprover("李院长");
            ViceSchoolMasterApprover viceSchoolMasterApprover = new ViceSchoolMasterApprover("王校长");
            SchoolMasterApprover schoolMasterApprover = new SchoolMasterApprover("周校长");
    
            // 如果本对象处理不了该请求,则设置下一个处理者对象
            departmentApprover.setApprover(collegeApprover);
            collegeApprover.setApprover(viceSchoolMasterApprover);
            viceSchoolMasterApprover.setApprover(schoolMasterApprover);
            schoolMasterApprover.setApprover(departmentApprover);
    
            // 不同的角色对象处理同一个请求,最终被同一个角色处理
            departmentApprover.processRequest(purchaseRequest);
            collegeApprover.processRequest(purchaseRequest);
            viceSchoolMasterApprover.processRequest(purchaseRequest);
            schoolMasterApprover.processRequest(purchaseRequest);
        }
    
    }
    

    输出结果:
    在这里插入图片描述

    四、职责链模式的注意事项

    1、将请求和处理分开,实现解耦,提高系统的灵活性
    2、简化了对象,使对象不需要知道链的结构
    3、性能会受到影响,特别是链比较长的时候,因此需要控制链的最大节点数量,一般通过在handler中设置一个最大的节点数量,在setNext()方法中判断是否已经超过了阀值,超过则不允许该链建立,避免超过超长链无意识破坏系统性能
    4、调试不方便,采用了类似递归的方式,调试时逻辑可能比较复杂
    5、最佳应用场景:有多个对象可以处理同一个请求时,比如:多级请求,请假/加薪等审批流程

    展开全文
  • 一文弄懂责任链设计模式

    千次阅读 2021-12-12 13:37:26
    责任链模式是一种行为设计模式, 允许你将请求沿着处理者链进行发送。 收到请求后, 每个处理者均可对请求进行处理, 或将其传递给链上的下个处理者。 场景 责任链的使用场景还是比较多的 多条件流程判断:权限...

    Reference

    [1] zhuanlan.zhihu.com/p/99334096, 本文主要借鉴该篇文章,如有侵权,联系删除

    [2] refactoringguru.cn/design-patt…

    [3] c.biancheng.net/view/1383.h…

    什么是责任链

    责任链模式是一种行为设计模式, 允许你将请求沿着处理者链进行发送。 收到请求后, 每个处理者均可对请求进行处理, 或将其传递给链上的下个处理者。

    image-20211211232146370

    场景

    责任链的使用场景还是比较多的

    • 多条件流程判断:权限控制
    • ERP 系统流程审批:总经理、人事经理、项目经理
    • Java 过滤器 的底层实现 Filter

    如果不使用该设计模式,那么当需求有所改变时,就会使得代码臃肿或者难以维护,例如下面的例子

    反例

    假设现在有一个闯关游戏,进入下一关的条件是上一关的分数要高于xx

    1. 游戏一共 3 个关卡
    2. 进入第二关需要第一关的游戏得分大于等于 80
    3. 进入第三关需要第二关的游戏得分大于等于 90

    那么代码可以这样写

    //第一关
    public class FirstPassHandler {
        public int handler(){
            System.out.println("第一关-->FirstPassHandler");
            return 80;
        }
    }
    
    //第二关
    public class SecondPassHandler {
        public int handler(){
            System.out.println("第二关-->SecondPassHandler");
            return 90;
        }
    }
    
    
    //第三关
    public class ThirdPassHandler {
        public int handler(){
            System.out.println("第三关-->ThirdPassHandler,这是最后一关啦");
            return 95;
        }
    }
    
    
    //客户端
    public class HandlerClient {
        public static void main(String[] args) {
    
            FirstPassHandler firstPassHandler = new FirstPassHandler();//第一关
            SecondPassHandler secondPassHandler = new SecondPassHandler();//第二关
            ThirdPassHandler thirdPassHandler = new ThirdPassHandler();//第三关
    
            int firstScore = firstPassHandler.handler();
            //第一关的分数大于等于80则进入第二关
            if(firstScore >= 80){
                int secondScore = secondPassHandler.handler();
                //第二关的分数大于等于90则进入第二关
                if(secondScore >= 90){
                    thirdPassHandler.handler();
                }
            }
        }
    }
    复制代码

    那么如果这个游戏有100关,我们的代码很可能就会写成这个样子

    if(第1关通过){
        // 第2关 游戏
        if(第2关通过){
            // 第3关 游戏
            if(第3关通过){
               // 第4关 游戏
                if(第4关通过){
                    // 第5关 游戏
                    if(第5关通过){
                        // 第6关 游戏
                        if(第6关通过){
                            //...
                        }
                    }
                } 
            }
        }
    }
    复制代码

    这种代码不仅冗余,并且当我们要将某两关进行调整时会对代码非常大的改动,这种操作的风险是很高的,因此,该写法非常糟糕

    初步改造

    如何解决这个问题,我们可以通过链表将每一关连接起来,形成责任链的方式,第一关通过后是第二关,第二关通过后是第三关 ....,这样客户端就不需要进行多重 if 的判断了

    public class FirstPassHandler {
        /**
         * 第一关的下一关是 第二关
         */
        private SecondPassHandler secondPassHandler;
    
        public void setSecondPassHandler(SecondPassHandler secondPassHandler) {
            this.secondPassHandler = secondPassHandler;
        }
    
        //本关卡游戏得分
        private int play(){
            return 80;
        }
    
        public int handler(){
            System.out.println("第一关-->FirstPassHandler");
            if(play() >= 80){
                //分数>=80 并且存在下一关才进入下一关
                if(this.secondPassHandler != null){
                    return this.secondPassHandler.handler();
                }
            }
    
            return 80;
        }
    }
    
    public class SecondPassHandler {
    
        /**
         * 第二关的下一关是 第三关
         */
        private ThirdPassHandler thirdPassHandler;
    
        public void setThirdPassHandler(ThirdPassHandler thirdPassHandler) {
            this.thirdPassHandler = thirdPassHandler;
        }
    
        //本关卡游戏得分
        private int play(){
            return 90;
        }
    
        public int handler(){
            System.out.println("第二关-->SecondPassHandler");
    
            if(play() >= 90){
                //分数>=90 并且存在下一关才进入下一关
                if(this.thirdPassHandler != null){
                    return this.thirdPassHandler.handler();
                }
            }
    
            return 90;
        }
    }
    
    public class ThirdPassHandler {
    
        //本关卡游戏得分
        private int play(){
            return 95;
        }
    
        /**
         * 这是最后一关,因此没有下一关
         */
        public int handler(){
            System.out.println("第三关-->ThirdPassHandler,这是最后一关啦");
            return play();
        }
    }
    
    public class HandlerClient {
        public static void main(String[] args) {
    
            FirstPassHandler firstPassHandler = new FirstPassHandler();//第一关
            SecondPassHandler secondPassHandler = new SecondPassHandler();//第二关
            ThirdPassHandler thirdPassHandler = new ThirdPassHandler();//第三关
    
            firstPassHandler.setSecondPassHandler(secondPassHandler);//第一关的下一关是第二关
            secondPassHandler.setThirdPassHandler(thirdPassHandler);//第二关的下一关是第三关
    
            //说明:因为第三关是最后一关,因此没有下一关
            //开始调用第一关 每一个关卡是否进入下一关卡 在每个关卡中判断
            firstPassHandler.handler();
    
        }
    }
    
    复制代码

    缺点

    现有模式的缺点

    • 每个关卡中都有下一关的成员变量并且是不一样的,形成链很不方便
    • 代码的扩展性非常不好

    责任链改造

    • 既然每个关卡中都有下一关的成员变量并且是不一样的,那么我们可以在关卡上抽象出一个父类或者接口,然后每个具体的关卡去继承或者实现

    有了思路,我们先来简单介绍一下责任链设计模式的基本组成

    • 抽象处理者(Handler)角色:定义一个处理请求的接口,包含抽象处理方法和一个后继连接。
    • 具体处理者(Concrete Handler)角色:实现抽象处理者的处理方法,判断能否处理本次请求,如果可以处理请求则处理,否则将该请求转给它的后继者。
    • 客户类(Client)角色:创建处理链,并向链头的具体处理者对象提交请求,它不关心处理细节和请求的传递过程。

    image-20211211233740916

    public abstract class AbstractHandler {
    
        /**
         * 下一关用当前抽象类来接收
         */
        protected AbstractHandler next;
    
        public void setNext(AbstractHandler next) {
            this.next = next;
        }
    
        public abstract int handler();
    }
    
    public class FirstPassHandler extends AbstractHandler{
    
        private int play(){
            return 80;
        }
    
        @Override
        public int handler(){
            System.out.println("第一关-->FirstPassHandler");
            int score = play();
            if(score >= 80){
                //分数>=80 并且存在下一关才进入下一关
                if(this.next != null){
                    return this.next.handler();
                }
            }
            return score;
        }
    }
    
    public class SecondPassHandler extends AbstractHandler{
    
        private int play(){
            return 90;
        }
    
        public int handler(){
            System.out.println("第二关-->SecondPassHandler");
    
            int score = play();
            if(score >= 90){
                //分数>=90 并且存在下一关才进入下一关
                if(this.next != null){
                    return this.next.handler();
                }
            }
    
            return score;
        }
    }
    
    public class ThirdPassHandler extends AbstractHandler{
    
        private int play(){
            return 95;
        }
    
        public int handler(){
            System.out.println("第三关-->ThirdPassHandler");
            int score = play();
            if(score >= 95){
                //分数>=95 并且存在下一关才进入下一关
                if(this.next != null){
                    return this.next.handler();
                }
            }
            return score;
        }
    }
    
    public class HandlerClient {
        public static void main(String[] args) {
    
            FirstPassHandler firstPassHandler = new FirstPassHandler();//第一关
            SecondPassHandler secondPassHandler = new SecondPassHandler();//第二关
            ThirdPassHandler thirdPassHandler = new ThirdPassHandler();//第三关
    
            // 和上面没有更改的客户端代码相比,只有这里的set方法发生变化,其他都是一样的
            firstPassHandler.setNext(secondPassHandler);//第一关的下一关是第二关
            secondPassHandler.setNext(thirdPassHandler);//第二关的下一关是第三关
    
            //说明:因为第三关是最后一关,因此没有下一关
    
            //从第一个关卡开始
            firstPassHandler.handler();
    
        }
    }
    复制代码

    责任链工厂改造

    对于上面的请求链,我们也可以把这个关系维护到配置文件中或者一个枚举中。我将使用枚举来教会大家怎么动态的配置请求链并且将每个请求者形成一条调用链

    image-20211212113926778

    public enum GatewayEnum {
        // handlerId, 拦截者名称,全限定类名,preHandlerId,nextHandlerId
        API_HANDLER(new GatewayEntity(1, "api接口限流", "cn.dgut.design.chain_of_responsibility.GateWay.impl.ApiLimitGatewayHandler", null, 2)),
        BLACKLIST_HANDLER(new GatewayEntity(2, "黑名单拦截", "cn.dgut.design.chain_of_responsibility.GateWay.impl.BlacklistGatewayHandler", 1, 3)),
        SESSION_HANDLER(new GatewayEntity(3, "用户会话拦截", "cn.dgut.design.chain_of_responsibility.GateWay.impl.SessionGatewayHandler", 2, null)),
        ;
    
        GatewayEntity gatewayEntity;
    
        public GatewayEntity getGatewayEntity() {
            return gatewayEntity;
        }
    
        GatewayEnum(GatewayEntity gatewayEntity) {
            this.gatewayEntity = gatewayEntity;
        }
    }
    
    public class GatewayEntity {
    
        private String name;
    
        private String conference;
    
        private Integer handlerId;
    
        private Integer preHandlerId;
    
        private Integer nextHandlerId;
    }
    
    
    public interface GatewayDao {
    
        /**
         * 根据 handlerId 获取配置项
         * @param handlerId
         * @return
         */
        GatewayEntity getGatewayEntity(Integer handlerId);
    
        /**
         * 获取第一个处理者
         * @return
         */
        GatewayEntity getFirstGatewayEntity();
    }
    
    public class GatewayImpl implements GatewayDao {
    
        /**
         * 初始化,将枚举中配置的handler初始化到map中,方便获取
         */
        private static Map<Integer, GatewayEntity> gatewayEntityMap = new HashMap<>();
    
        static {
            GatewayEnum[] values = GatewayEnum.values();
            for (GatewayEnum value : values) {
                GatewayEntity gatewayEntity = value.getGatewayEntity();
                gatewayEntityMap.put(gatewayEntity.getHandlerId(), gatewayEntity);
            }
        }
    
        @Override
        public GatewayEntity getGatewayEntity(Integer handlerId) {
            return gatewayEntityMap.get(handlerId);
        }
    
        @Override
        public GatewayEntity getFirstGatewayEntity() {
            for (Map.Entry<Integer, GatewayEntity> entry : gatewayEntityMap.entrySet()) {
                GatewayEntity value = entry.getValue();
                //  没有上一个handler的就是第一个
                if (value.getPreHandlerId() == null) {
                    return value;
                }
            }
            return null;
        }
    }
    
    public class GatewayHandlerEnumFactory {
    
        private static GatewayDao gatewayDao = new GatewayImpl();
    
        // 提供静态方法,获取第一个handler
        public static GatewayHandler getFirstGatewayHandler() {
    
            GatewayEntity firstGatewayEntity = gatewayDao.getFirstGatewayEntity();
            GatewayHandler firstGatewayHandler = newGatewayHandler(firstGatewayEntity);
            if (firstGatewayHandler == null) {
                return null;
            }
    
            GatewayEntity tempGatewayEntity = firstGatewayEntity;
            Integer nextHandlerId = null;
            GatewayHandler tempGatewayHandler = firstGatewayHandler;
            // 迭代遍历所有handler,以及将它们链接起来
            while ((nextHandlerId = tempGatewayEntity.getNextHandlerId()) != null) {
                GatewayEntity gatewayEntity = gatewayDao.getGatewayEntity(nextHandlerId);
                GatewayHandler gatewayHandler = newGatewayHandler(gatewayEntity);
                tempGatewayHandler.setNext(gatewayHandler);
                tempGatewayHandler = gatewayHandler;
                tempGatewayEntity = gatewayEntity;
            }
    	// 返回第一个handler
            return firstGatewayHandler;
        }
    
        /**
         * 反射实体化具体的处理者
         * @param firstGatewayEntity
         * @return
         */
        private static GatewayHandler newGatewayHandler(GatewayEntity firstGatewayEntity) {
            // 获取全限定类名
            String className = firstGatewayEntity.getConference(); 
            try {
                // 根据全限定类名,加载并初始化该类,即会初始化该类的静态段
                Class<?> clazz = Class.forName(className);
                return (GatewayHandler) clazz.newInstance();
            } catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) {
                e.printStackTrace();
            }
            return null;
        }
    
    
    }
    
    public class GetewayClient {
        public static void main(String[] args) {
            GetewayHandler firstGetewayHandler = GetewayHandlerEnumFactory.getFirstGetewayHandler();
            firstGetewayHandler.service();
        }
    }
    
    复制代码

    聊聊其他

    很久没写文章,本文主要还是借鉴了 Reference [1] 该作者的图文,说实话,写的特别好,尤其是其中的责任链工厂,我觉得很有意思。

    设计模式确实是一门艺术,仍需努力呀!




     

    展开全文
  • 定义: 使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系...责任链模式 """ from abc import abstractmethod, ABCMeta class Handler(metaclass=ABCMeta): @abstractmethod def handler_lea
  • 主要介绍了Java责任链设计模式,结合实例形式详细分析了Java责任链设计模式的原理与相关操作技巧,需要的朋友可以参考下
  • Java责任链设计模式

    2020-09-02 16:23:46
    主要介绍了Java责任链设计模式的相关资料,需要的朋友可以参考下
  • 写了几个实现责任链模式的代码,仅供参考,环境jdk1.8,代码完成可用,经过测试的,对于初学者还是有一定的帮助,
  • 责任链设计模式的思想很简单,就是按照链的顺序执⾏⼀个个处理⽅法,链上的每⼀个任务都持有它后⾯那个任务的对象引⽤, 以⽅便⾃⼰这段执⾏完成之后,调⽤其后⾯的处理逻辑。
  • NULL 博文链接:https://stelin.iteye.com/blog/932101
  • NULL 博文链接:https://hnzhoujunmei.iteye.com/blog/1033330
  • 责任链设计模式: 在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这...
  • 主要介绍了Java经典设计模式责任链模式,简单说明了责任链模式的概念、原理,并结合实例形式分析了java实现责任链模式的具体用法与相关注意事项,需要的朋友可以参考下
  • 设计模式是一个老话题了,因为近在设计“网关API”组件(后续介绍),采用“责任链设计模式”进行设计,所以先进行回顾记录。  一、责任链模式介绍  责任链模式是指一个处理需要涉及多个过程或者角色参与处理,...
  • 本文以项目中的一个工作流模块,演示责任链模式、策略模式、命令模式的组合实现!最近在做的一个项目,涉及到的是一个流程性质的需求。关于工程机械行业的服务流程:服务任务流程和备件发运流程。项目之初,需求不是...
  • 主要介绍了Java设计模式责任链模式(Chain of Responsibility模式)介绍,本文讲解了如何使用责任链模式,并给出了4种使用实例,需要的朋友可以参考下
  • 八、责任链设计模式

    2016-04-28 22:40:06
    1. 责任链模式介绍使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。考虑到如下情景: 小李要出差,出差之后,...

    1. 责任链模式介绍

    使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。

    考虑到如下情景:
    小李要出差,出差之后,小李要报销经费,小李申请了50000块的经费。

    1. 首先向组长提出,组长,他只能报销2000元以内的。组长把小李的请求向主管提出。

    2. 主管收到申请后,主管说他也无法批准,他只能批准5000以内的,所以主管把请求又递交给了总经理。

    3. 总经理收到请求后,他只能批准10000以内的,所以主管把请求又递交给了老板。

    4. 老板收到请求后,把小李的请求给处理了。

    以上请求就是一个责任链模式,发出请求者并不知道谁会来处理请求,每个领导会根据自己的职责范围,来判断是处理还是把请求递交给更高级别的领导。只要有领导处理了,传递就结束了。

    2. 责任链模式使用场景

    • 多个对象可以处理同一请求,单具体由哪个对象处理则在运行时动态决定的。
    • 在请求矗立着不明确的情况下向多个对象中的一个提交一个请求。
    • 需要动态指定一组对象处理请求。

    3. 责任链模式UML类图

    责任链UML

    4. 责任链模式简单实现

    情景描述:介绍里面描述的申请经费案例。

    包结构:

    责任链模式包结构

    (1) 首先声明一个抽象的老板类:

    public abstract class Leader {
            protected Leader nextHandler;//上一级领导处理者
    
            public void handleRequest(int money) {
                if (money <= limit()) {
                    handleMoney(money);
                } else {
                    if (nextHandler != null) {
                        nextHandler.handleRequest(money);
                    }
                }
            }
    
            //处理
            protected abstract void handleMoney(int money);
    
            //每一级领导能够批准的额度
            protected abstract int limit();
        }
    

    在上述抽象类中,发起请求时,调用handleRequest()方法,步骤如下:

    1. 在handleRequest方法中,首先判断传递进来的money是否小于当前领导能够批准的额度。这个额度由 limit()这个方法返回,limit()是一个抽象方法,由具体的领导实现。

    2. 如果money小于当前领导所能处理的额度,调用handleMoney(money)方法,handleMOney(money)也是一个抽喜类,由具体的领导类实现。

    3. 如果money大于当前领导所能处理的额度,调用上一级领导的handleReqeust()方法。

    4. 重复以上1、2、3步骤,直到结束。

    (2)具体的领导类:Boos,DirectorLeader,GroupLeader,ManagerLeader:

    public class Boss extends Leader {
            @Override
            protected void handleMoney(int money) {
                System.out.println("老板报销: " + money);
            }
    
            @Override
            protected int limit() {
                return Integer.MAX_VALUE;
            }
    }
    

    (3)测试类:

    public class Person {
            public static void main(String[] args) {
                //构造各个级别领导
                GroupLeader groupLeader = new GroupLeader();
                DirectorLeader directorLeader = new DirectorLeader();
                ManagerLeader managerLeader = new ManagerLeader();
                Boss boss = new Boss();
    
                //设置上一级领导处理对象
                groupLeader.nextHandler = directorLeader;
                directorLeader.nextHandler = managerLeader;
                managerLeader.nextHandler = boss;
    
                //申请报销
                groupLeader.handleRequest(50000);
            }
    }
    • 对于责任链来说,一个请求最终只有两种情况:一是被某个处理对象处理,另一个是所有的对象均为对其处理。 对于前一种情况,我们称该对象为纯的责任链,对于后一种情况我们称为不纯的责任链,在实际应用中,我们所见的责任链模式大多为不纯的责任链模式。

    5. 责任链模式在Android系统中

    android触摸事件流程是一个典型的责任链模式,具体网上有很多优质的文章介绍,这里就不做赘述了。
    这里推荐一篇个人决定不错的文章。

    android触摸事件处理流程

    6. 责任链模式在Android开发中

    责任链模式可以替代各种分支和条件判断语句,这里就不做具体举例。

    7. 总结

    • 优点:
      • 可以对请求者和处理者关系解耦,提高代码的灵活性。
    • 缺点:
      • 对链中请求处理的遍历,如果处理者太多,那么遍历必定会影响性能。
    展开全文
  • 前言: 责任链模式(Chain of Responsibility): 使多个对象都有机会处理同一请求,从而避免请求的发送者和接受者之间的耦合关系... 一篇文章搞懂Java设计模式责任链模式_lzy_tinyjoy-CSDN博客_java责任链模式 ...
  • 本文实例讲述了JavaScript设计模式责任链模式。分享给大家供大家参考,具体如下: 介绍 责任链模式(Chain of responsibility)是使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将...
  • 主要为大家介绍了JavaScript设计模式中的责任链模式,对JavaScript设计模式感兴趣的小伙伴们可以参考一下
  • 设计模式责任链模式的例子,希望对大家有用~~~~~~~~
  • Spring 中使用责任链设计模式

    千次阅读 2020-04-24 17:10:44
    责任链设计模式作为我们常用的设计模式之一,用途非常的广,例如在一些流程化的执行中、或者是一些动态拦截中我们都可以使用责任链设计模式进行设计需求,从而使我们的项目无论是可用性还是可扩展性都会非常的好。...
  • Java Servlet : 1 FilterChain = n Filter + 1 Servlet Spring MVC DispatcherServlet : 1 HandlerExecutionChain = n HandlerInterceptor + 1 handler Spring AOP : 1 Proxy = n MethodInterceptor + 1 target bea....
  • 设计模式 | 责任链模式及典型应用

    千次阅读 多人点赞 2018-10-31 23:00:54
    介绍责任链模式 请假流程示例 责任链模式总结 源码分析Tomcat Filter中的责任链模式 责任链模式 一个事件需要经过多个对象处理是一个挺常见的场景,譬如采购审批流程,请假流程,软件开发中的异常处理流程,web请求...
  • Java实现责任链模式

    千次阅读 2022-01-16 18:53:52
    责任链设计模式是软件开发中常见的一种设计模式,在该模式中将一个请求进行递进处理,从而形成一条链,在链条的节点中处理请求,一个节点处理完自己的逻辑再传递到下一个节点中。 在许多开源库中,可以看到责任链...
  • 设计模式责任链模式源码 设计模式责任链模式源码 设计模式责任链模式源码
  • 主要介绍了JAVA设计模式责任链模式详解,需要的朋友可以参考下
  • 责任链设计模式例子

    千次阅读 2016-12-10 11:37:56
    原文地址: 1.http://www.cnblogs.com/manmanlu/p/5732979.html 2....将这些对象连成一条,并沿着这条传递该请求,直到有对象处理它为止。二、涉及角色抽象处理类:抽象处理类中主要包含
  • 设计模式C++学习之责任链模式(Chain of Responsibility)
  • 本篇文章是对PHP设计模式中的责任链模式进行了详细的分析介绍,需要的朋友参考下

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 88,552
精华内容 35,420
关键字:

责任链设计模式

友情链接: SYSTEM.rar