【设计模式】责任链模式

责任链模式(Chain of Responsibility Pattern)

责任链模式是一种行为设计模式,它允许你将请求沿着处理者链进行传递,直到其中一个处理者能够处理该请求为止。这种模式使得多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。

一、责任链模式的定义

责任链模式的核心思想是将请求的处理者连成一条链,并沿着这条链传递请求,直到链中的某个处理者能够处理该请求为止。每个处理者都包含对下一个处理者的引用,如果当前处理者不能处理请求,它会将请求传递给下一个处理者。

二、责任链模式的结构

责任链模式主要包含以下几个角色:

• 抽象处理者(Handler):定义了一个处理请求的接口,通常包含一个指向下一个处理者的引用。

• 具体处理者(ConcreteHandler):实现抽象处理者接口的具体类,处理请求或将其传递给下一个处理者。

• 客户端(Client):发起请求的对象,通常不知道请求会被传递到哪个具体的处理者。

三、责任链模式的实现

以下是一个简单的实现示例:

1.抽象处理者

java 复制代码
public abstract class Handler {
    protected Handler nextHandler;

    public void setNextHandler(Handler nextHandler) {
        this.nextHandler = nextHandler;
    }

    public abstract void handleRequest(Request request);
}

2.具体处理者

java 复制代码
public class ConcreteHandlerA extends Handler {
    @Override
    public void handleRequest(Request request) {
        if (request.getType() == RequestType.TYPE_A) {
            System.out.println("ConcreteHandlerA handles request: " + request.getDescription());
        } else if (nextHandler != null) {
            nextHandler.handleRequest(request);
        }
    }
}

public class ConcreteHandlerB extends Handler {
    @Override
    public void handleRequest(Request request) {
        if (request.getType() == RequestType.TYPE_B) {
            System.out.println("ConcreteHandlerB handles request: " + request.getDescription());
        } else if (nextHandler != null) {
            nextHandler.handleRequest(request);
        }
    }
}

public class ConcreteHandlerC extends Handler {
    @Override
    public void handleRequest(Request request) {
        if (request.getType() == RequestType.TYPE_C) {
            System.out.println("ConcreteHandlerC handles request: " + request.getDescription());
        } else if (nextHandler != null) {
            nextHandler.handleRequest(request);
        }
    }
}

3.请求类

java 复制代码
public class Request {
    private RequestType type;
    private String description;

    public Request(RequestType type, String description) {
        this.type = type;
        this.description = description;
    }

    public RequestType getType() {
        return type;
    }

    public String getDescription() {
        return description;
    }
}

public enum RequestType {
    TYPE_A,
    TYPE_B,
    TYPE_C
}

4.客户端代码

java 复制代码
public class ChainOfResponsibilityDemo {
    public static void main(String[] args) {
        // 创建处理者链
        Handler handlerA = new ConcreteHandlerA();
        Handler handlerB = new ConcreteHandlerB();
        Handler handlerC = new ConcreteHandlerC();

        handlerA.setNextHandler(handlerB);
        handlerB.setNextHandler(handlerC);

        // 创建请求
        Request requestA = new Request(RequestType.TYPE_A, "Request A");
        Request requestB = new Request(RequestType.TYPE_B, "Request B");
        Request requestC = new Request(RequestType.TYPE_C, "Request C");
        Request requestD = new Request(RequestType.TYPE_A, "Request D");

        // 处理请求
        handlerA.handleRequest(requestA);
        handlerA.handleRequest(requestB);
        handlerA.handleRequest(requestC);
        handlerA.handleRequest(requestD);
    }
}

四、运行效果

运行上述代码后,输出如下:

复制代码
ConcreteHandlerA handles request: Request A
ConcreteHandlerB handles request: Request B
ConcreteHandlerC handles request: Request C
ConcreteHandlerA handles request: Request D

五、责任链模式的优点

• 降低耦合度:

• 请求的发送者和接收者之间没有直接的耦合关系,增加了系统的灵活性。

• 增强扩展性:

• 可以动态地添加或修改处理者的顺序,而无需修改客户端代码。

• 简化对象结构:

• 避免了复杂的条件语句,使代码更加清晰和易于维护。

六、责任链模式的缺点

• 性能问题:

• 如果链过长,可能会导致请求处理的延迟增加。

• 调试困难:

• 由于请求的处理路径可能不明确,调试时可能需要跟踪整个链。

• 无默认处理:

• 如果链中没有处理者能够处理请求,请求可能会被忽略,需要额外的机制来处理这种情况。

七、责任链模式的应用场景

• 多级审批流程:

• 在多级审批系统中,每个审批级别可以作为一个处理者,请求沿着审批链传递,直到某个级别批准或拒绝。

• 日志处理:

• 在日志系统中,不同级别的日志可以由不同的处理者处理,请求沿着日志链传递,直到某个处理者处理日志。

• 事件处理:

• 在事件驱动的系统中,事件可以沿着处理者链传递,直到某个处理者处理事件。

八、总结

责任链模式是一种非常实用的设计模式,通过将请求的处理者连成一条链,实现了请求的灵活传递和处理。通过合理使用责任链模式,可以降低系统的耦合度,增强系统的扩展性,同时避免使用复杂的条件语句。

java 复制代码
// 责任链模式
    static class Solution_20250529213945_6080a9ac877d41a3a0812221e07a4754 {
        static public abstract class Handler {
            protected Handler nextHandler;

            public void setNextHandler(Handler nextHandler) {
                this.nextHandler = nextHandler;
            }

            public abstract void handleRequest(Request request);
        }

        static public class ConcreteHandlerA extends Handler {
            @Override
            public void handleRequest(Request request) {
                if (request.getType() == RequestType.TYPE_A) {
                    System.out.println("ConcreteHandlerA handles request: " + request.getDescription());
                } else if (nextHandler != null) {
                    nextHandler.handleRequest(request);
                }
            }
        }

        static public class ConcreteHandlerB extends Handler {
            @Override
            public void handleRequest(Request request) {
                if (request.getType() == RequestType.TYPE_B) {
                    System.out.println("ConcreteHandlerB handles request: " + request.getDescription());
                } else if (nextHandler != null) {
                    nextHandler.handleRequest(request);
                }
            }
        }

        static public class ConcreteHandlerC extends Handler {
            @Override
            public void handleRequest(Request request) {
                if (request.getType() == RequestType.TYPE_C) {
                    System.out.println("ConcreteHandlerC handles request: " + request.getDescription());
                } else if (nextHandler != null) {
                    nextHandler.handleRequest(request);
                }
            }
        }

        static public class Request {
            private RequestType type;
            private String description;

            public Request(RequestType type, String description) {
                this.type = type;
                this.description = description;
            }

            public RequestType getType() {
                return type;
            }

            public String getDescription() {
                return description;
            }
        }

        static public enum RequestType {
            TYPE_A,
            TYPE_B,
            TYPE_C
        }

        public static void main(String[] args) {
            // 创建处理者链
            Handler handlerA = new ConcreteHandlerA();
            Handler handlerB = new ConcreteHandlerB();
            Handler handlerC = new ConcreteHandlerC();

            handlerA.setNextHandler(handlerB);
            handlerB.setNextHandler(handlerC);

            // 创建请求
            Request requestA = new Request(RequestType.TYPE_A, "Request A");
            Request requestB = new Request(RequestType.TYPE_B, "Request B");
            Request requestC = new Request(RequestType.TYPE_C, "Request C");
            Request requestD = new Request(RequestType.TYPE_A, "Request D");

            // 处理请求
            handlerA.handleRequest(requestA);
            handlerA.handleRequest(requestB);
            handlerA.handleRequest(requestC);
            handlerA.handleRequest(requestD);
        }
    }
相关推荐
How_doyou_do4 分钟前
Agent设计模式与工程化
设计模式
楠枬13 分钟前
OpenFeign
java·spring cloud·微服务
是席木木啊16 分钟前
基于MinIO Java SDK实现ZIP文件上传的方案与实践
java·开发语言
计算机毕设指导620 分钟前
基于微信小程序的垃圾分类信息系统【源码文末联系】
java·spring boot·mysql·微信小程序·小程序·tomcat·maven
毕设源码-赖学姐23 分钟前
【开题答辩全过程】以 高校就业系统的实现为例,包含答辩的问题和答案
java·eclipse
一起养小猫26 分钟前
《Java数据结构与算法》第四篇(四):二叉树的高级操作查找与删除实现详解
java·开发语言·数据结构·算法
Coder_Boy_37 分钟前
【人工智能应用技术】-基础实战-小程序应用(基于springAI+百度语音技术)智能语音控制-单片机交互代码
java·人工智能·后端·嵌入式硬件
a努力。1 小时前
国家电网Java面试被问:二叉树的前序、中序、后序遍历
java·开发语言·后端·面试
賬號封禁中miu1 小时前
图论之最小生成树
java·数据结构·算法·图论
月明长歌1 小时前
Java数据结构:PriorityQueue堆与优先级队列:从概念到手写大根堆
java·数据结构·python·leetcode·