当前位置: 首页 > article >正文

【设计模式】【行为型模式(Behavioral Patterns)】之责任链模式(Chain of Responsibility Pattern)

1. 设计模式原理说明

责任链模式(Chain of Responsibility Pattern) 是一种行为设计模式,它允许你将请求沿着处理者链进行发送。每个处理者都可以处理请求,或者将其传递给链上的下一个处理者。这种模式使得多个对象都有机会处理请求,而无需提前指定具体的处理者。这样可以减少请求发送者和接收者之间的耦合。

主要角色
  1. Handler(抽象处理者):定义了一个处理请求的接口,通常包含一个后继连接,用于指向下一个处理者。
  2. ConcreteHandler(具体处理者):实现了处理请求的方法,判断是否处理该请求,如果不能处理则将请求转发给下一个处理者。
  3. Client(客户端):创建处理者对象并组织成一条链,向链中的第一个处理者提交请求。

2. UML 类图及解释

UML 类图
+-----------------+
|    Handler      |
|-----------------|
| - successor: Handler |
| - setSuccessor(successor: Handler) |
| - handleRequest(request: Request) |
+-----------------+
           ^
           |
           |
           v
+-----------------+
| ConcreteHandlerA|
|-----------------|
| - handleRequest(request: Request) |
+-----------------+
           ^
           |
           |
           v
+-----------------+
| ConcreteHandlerB|
|-----------------|
| - handleRequest(request: Request) |
+-----------------+
类图解释
  • Handler:定义了处理请求的接口,包含一个后继连接(successor),用于指向下一个处理者。
  • ConcreteHandlerA 和 ConcreteHandlerB:实现了处理请求的方法,判断是否处理该请求,如果不能处理则将请求转发给下一个处理者。
  • Client:创建处理者对象并组织成一条链,向链中的第一个处理者提交请求。

3. 代码案例及逻辑详解

Java 代码案例
// 抽象处理者
abstract class Handler {
    protected Handler successor;

    public void setSuccessor(Handler successor) {
        this.successor = successor;
    }

    public abstract void handleRequest(int request);
}

// 具体处理者 A
class ConcreteHandlerA extends Handler {
    @Override
    public void handleRequest(int request) {
        if (request >= 0 && request < 10) {
            System.out.println("ConcreteHandlerA handled request " + request);
        } else if (successor != null) {
            successor.handleRequest(request);
        }
    }
}

// 具体处理者 B
class ConcreteHandlerB extends Handler {
    @Override
    public void handleRequest(int request) {
        if (request >= 10 && request < 20) {
            System.out.println("ConcreteHandlerB handled request " + request);
        } else if (successor != null) {
            successor.handleRequest(request);
        }
    }
}

// 客户端
public class Client {
    public static void main(String[] args) {
        Handler handlerA = new ConcreteHandlerA();
        Handler handlerB = new ConcreteHandlerB();

        handlerA.setSuccessor(handlerB);

        handlerA.handleRequest(5);  // 应由 ConcreteHandlerA 处理
        handlerA.handleRequest(15); // 应由 ConcreteHandlerB 处理
        handlerA.handleRequest(25); // 没有处理者可以处理
    }
}
C++ 代码案例
#include <iostream>

// 抽象处理者
class Handler {
protected:
    Handler* successor;
public:
    void setSuccessor(Handler* successor) {
        this->successor = successor;
    }
    virtual void handleRequest(int request) = 0;
};

// 具体处理者 A
class ConcreteHandlerA : public Handler {
public:
    void handleRequest(int request) override {
        if (request >= 0 && request < 10) {
            std::cout << "ConcreteHandlerA handled request " << request << std::endl;
        } else if (successor != nullptr) {
            successor->handleRequest(request);
        }
    }
};

// 具体处理者 B
class ConcreteHandlerB : public Handler {
public:
    void handleRequest(int request) override {
        if (request >= 10 && request < 20) {
            std::cout << "ConcreteHandlerB handled request " << request << std::endl;
        } else if (successor != nullptr) {
            successor->handleRequest(request);
        }
    }
};

// 客户端
int main() {
    Handler* handlerA = new ConcreteHandlerA();
    Handler* handlerB = new ConcreteHandlerB();

    handlerA->setSuccessor(handlerB);

    handlerA->handleRequest(5);  // 应由 ConcreteHandlerA 处理
    handlerA->handleRequest(15); // 应由 ConcreteHandlerB 处理
    handlerA->handleRequest(25); // 没有处理者可以处理

    delete handlerA;
    delete handlerB;
    return 0;
}
Python 代码案例
# 抽象处理者
class Handler:
    def __init__(self):
        self.successor = None

    def set_successor(self, successor):
        self.successor = successor

    def handle_request(self, request):
        pass

# 具体处理者 A
class ConcreteHandlerA(Handler):
    def handle_request(self, request):
        if 0 <= request < 10:
            print(f"ConcreteHandlerA handled request {request}")
        elif self.successor is not None:
            self.successor.handle_request(request)

# 具体处理者 B
class ConcreteHandlerB(Handler):
    def handle_request(self, request):
        if 10 <= request < 20:
            print(f"ConcreteHandlerB handled request {request}")
        elif self.successor is not None:
            self.successor.handle_request(request)

# 客户端
if __name__ == "__main__":
    handlerA = ConcreteHandlerA()
    handlerB = ConcreteHandlerB()

    handlerA.set_successor(handlerB)

    handlerA.handle_request(5)  # 应由 ConcreteHandlerA 处理
    handlerA.handle_request(15) # 应由 ConcreteHandlerB 处理
    handlerA.handle_request(25) # 没有处理者可以处理
Go 代码案例
package main

import (
	"fmt"
)

// 抽象处理者
type Handler interface {
	setSuccessor(successor Handler)
	handleRequest(request int)
}

// 具体处理者 A
type ConcreteHandlerA struct {
	successor Handler
}

func (h *ConcreteHandlerA) setSuccessor(successor Handler) {
	h.successor = successor
}

func (h *ConcreteHandlerA) handleRequest(request int) {
	if request >= 0 && request < 10 {
		fmt.Printf("ConcreteHandlerA handled request %d\n", request)
	} else if h.successor != nil {
		h.successor.handleRequest(request)
	}
}

// 具体处理者 B
type ConcreteHandlerB struct {
	successor Handler
}

func (h *ConcreteHandlerB) setSuccessor(successor Handler) {
	h.successor = successor
}

func (h *ConcreteHandlerB) handleRequest(request int) {
	if request >= 10 && request < 20 {
		fmt.Printf("ConcreteHandlerB handled request %d\n", request)
	} else if h.successor != nil {
		h.successor.handleRequest(request)
	}
}

// 客户端
func main() {
	handlerA := &ConcreteHandlerA{}
	handlerB := &ConcreteHandlerB{}

	handlerA.setSuccessor(handlerB)

	handlerA.handleRequest(5)  // 应由 ConcreteHandlerA 处理
	handlerA.handleRequest(15) // 应由 ConcreteHandlerB 处理
	handlerA.handleRequest(25) // 没有处理者可以处理
}

4. 总结

责任链模式 是一种行为设计模式,它允许你将请求沿着处理者链进行发送。每个处理者都可以处理请求,或者将其传递给链上的下一个处理者。这种模式使得多个对象都有机会处理请求,而无需提前指定具体的处理者。通过这种方式,可以减少请求发送者和接收者之间的耦合。

主要优点
  1. 解耦:请求的发送者和接收者之间没有直接的耦合关系,提高了系统的灵活性。
  2. 增强可扩展性:可以动态地增加或改变处理者的数量和顺序,而不会影响客户端。
  3. 支持多个处理者:多个处理者可以依次处理同一个请求,增加了系统的灵活性和可配置性。
主要缺点
  1. 调试困难:由于请求的处理过程是动态的,调试时可能难以跟踪请求的处理路径。
  2. 性能开销:如果链过长,可能会导致性能下降,尤其是在每个处理者都需要执行某些操作时。
适用场景
  • 当一个请求需要被多个对象中的一个或多个处理时。
  • 当处理者的选择需要在运行时动态决定时。
  • 当需要在不明确指定接收者的情况下,向多个对象中的一个发送请求时。
  • 当需要创建一个可灵活配置的处理流程时。

http://www.kler.cn/a/412318.html

相关文章:

  • ubuntu 安装 docker 记录
  • HTTP 管道传输与多路复用
  • 八股文-基础知识-面试题汇总(一)
  • Jmeter测试工具的安装和使用,mac版本,jmeter版本5.2.1
  • Elasticsearch中的节点(比如共20个),其中的10个选了一个master,另外10个选了另一个master,怎么办?
  • Vue.js 中 v-bind 和 v-model 的用法与异同
  • 极狐GitLab 17.6 正式发布几十项与 DevSecOps 相关的功能【二】
  • 【力扣】125. 验证回文串
  • 集成金蝶云星空数据至MySQL的完整案例解析
  • 【es6】原生js在页面上画矩形及删除的实现方法
  • 【Linux】基础IO-文件描述符
  • 【Linux学习】【Ubuntu入门】2-5 shell脚本入门
  • CentOS 环境使用代理下载数据失败-EOF occurred in violation of protocol (_ssl.c:1002)
  • 自主研发,基于PHP+ vue2+element+ laravel8+ mysql5.7+ vscode开发的不良事件管理系统源码,不良事件管理系统源码
  • 一篇文章了解Linux
  • react项目初始化配置步骤
  • 关于 Android LocalSocket、LocalServerSocket
  • C++中虚继承为什么可以解决菱形继承的数据冗余问题
  • EasyAnimate:基于Transformer架构的高性能长视频生成方法
  • LeetCode 2924. Find Champion II
  • CRTP mixins EBO
  • 代理模式 (Proxy Pattern)
  • C#基础36-40
  • 【大数据测试 Elasticsearch 的 四大 常见问题及处理方案】
  • 【模糊查询Redis的Key,过滤出其中ZSET类型中包含自定义字符串的元素并删除】
  • 老旧前端项目如何升级工程化的项目