Chain Responsibility Pattern
1. Allows a request to be passed along the chain of handlers until it is processed.
2. used in Qt
2.1 Qt Event loop
2.2 Qt Event Loop Call Stack, using a mouse click as an example.
QWidgetWindow::handleMouseEvent
QWidget * QApplicationPrivate::pickMouseReceiver
QApplication::notify(QObject *receiver, QEvent *e)
while (w) {
res = d->notify_helper(...);
w = w->parentWidget();
}
QApplicationPrivate::notify_helper(QObject *receiver, QEvent * e)
QWidget::event(event);
3. example
3.1 Handler
#include <iostream>
#include <memory>
#include <string>
// 抽象处理者类
class Handler {
public:
virtual ~Handler() = default;
// 设置下一个处理者
void setNext(std::shared_ptr<Handler> next) {
nextHandler = next;
}
// 处理请求
virtual void handleRequest(const std::string& request) = 0;
protected:
std::shared_ptr<Handler> nextHandler;
};
3.2 ConcreteHandler
// 具体处理者1
class ConcreteHandlerA : public Handler {
public:
void handleRequest(const std::string& request) override {
if (request == "A") {
std::cout << "Handler A is handling the request." << std::endl;
} else if (nextHandler) {
nextHandler->handleRequest(request);
} else {
std::cout << "Request not handled." << std::endl;
}
}
};
// 具体处理者2
class ConcreteHandlerB : public Handler {
public:
void handleRequest(const std::string& request) override {
if (request == "B") {
std::cout << "Handler B is handling the request." << std::endl;
} else if (nextHandler) {
nextHandler->handleRequest(request);
} else {
std::cout << "Request not handled." << std::endl;
}
}
};
// 具体处理者3
class ConcreteHandlerC : public Handler {
public:
void handleRequest(const std::string& request) override {
if (request == "C") {
std::cout << "Handler C is handling the request." << std::endl;
} else if (nextHandler) {
nextHandler->handleRequest(request);
} else {
std::cout << "Request not handled." << std::endl;
}
}
};
3.3 main
int main() {
// 创建具体的处理者
std::shared_ptr<Handler> handlerA = std::make_shared<ConcreteHandlerA>();
std::shared_ptr<Handler> handlerB = std::make_shared<ConcreteHandlerB>();
std::shared_ptr<Handler> handlerC = std::make_shared<ConcreteHandlerC>();
// 设置责任链
handlerA->setNext(handlerB);
handlerB->setNext(handlerC);
// 发起请求
std::cout << "Sending request A:" << std::endl;
handlerA->handleRequest("A");
std::cout << "\nSending request B:" << std::endl;
handlerA->handleRequest("B");
std::cout << "\nSending request C:" << std::endl;
handlerA->handleRequest("C");
std::cout << "\nSending request D:" << std::endl;
handlerA->handleRequest("D");
return 0;
}
3.4 result
Sending request A:
Handler A is handling the request.
Sending request B:
Handler B is handling the request.
Sending request C:
Handler C is handling the request.
Sending request D:
Request not handled.