职责链模式使得多个对象都有机会处理请求,将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
结构图如下:
image.png
一个典型的对象结构可能如下图所示:
image.png
假设请求有多种,并且有多种handler动作与之对应。
头文件chainOfResponsibility.h定义如下:
#pragma once
#ifndef CHAIN_OF_RESPONSIBILITY_H
#define CHAIN_OF_RESPONSIBILITY_H
#include <string>
#include <iostream>
enum RequestType
{
REQ_HANDLER1 = 0,
REQ_HANDLER2,
REQ_HANDLER3
};
class Request
{
public:
Request(const std::string& desc, RequestType type):description(desc), reqType(type) {}
RequestType getReqType() const { return reqType; }
const std::string& getDescription() const { return description; }
private:
std::string description;
RequestType reqType;
};
class ChainHandler {
private:
ChainHandler* nextChain;
void sendRequestToNextHandler(const Request& req) {
if (nextChain != nullptr) {
nextChain->handle(req);
}
}
protected:
virtual bool canHandleRequest(const Request& req) = 0;
virtual void processRequest(const Request& req) = 0;
public:
ChainHandler() {
nextChain = nullptr;
}
void setNextChain(ChainHandler* next) {
nextChain = next;
}
void handle(const Request& req) {
if (canHandleRequest(req)) {
processRequest(req);
} else {
sendRequestToNextHandler(req);
}
}
};
class Handler1:public ChainHandler {
protected:
bool canHandleRequest(const Request& req) {
return req.getReqType() == RequestType::REQ_HANDLER1;
}
void processRequest(const Request& req) {
std::cout << "Handle1 is handle request!" << req.getDescription() << std::endl;
}
};
class Handler2 :public ChainHandler {
protected:
bool canHandleRequest(const Request& req) {
return req.getReqType() == RequestType::REQ_HANDLER2;
}
void processRequest(const Request& req) {
std::cout << "Handle2 is handle request!" << req.getDescription() << std::endl;
}
};
class Handler3 :public ChainHandler {
protected:
bool canHandleRequest(const Request& req) {
return req.getReqType() == RequestType::REQ_HANDLER3;
}
void processRequest(const Request& req) {
std::cout << "Handle3 is handle request!" << req.getDescription() << std::endl;
}
};
#endif // !CHAIN_OF_RESPONSIBILITY_H
定义了一个请求Request类,一个handle抽象基类,三个handle具体子类。每个子类重写了匹配请求类型的canHandleRequest方法和处理请求的processRequest方法。
调用程序main.cpp如下:
#include "chainOfResponsibility.h"
using namespace std;
int main()
{
Handler1 h1;
Handler2 h2;
Handler3 h3;
h1.setNextChain(&h2);
h2.setNextChain(&h3);
Request req("process task...", RequestType::REQ_HANDLER3);
h1.handle(req);
}
这里首先定义了三个具体handle对象,并通过setNextChain方法使得形成了h1->h2->h3结构的职责链。
接着定义了一个Request对象(handle3)。
h1.handle(req);语句调用函数顺序如下:
ChainHandler::handle
Handler1::canHandleRequest(false)
ChainHandler::sendRequestToNextHandler
ChainHandler::handle
Handler2::canHandleRequest(false)
ChainHandler::sendRequestToNextHandler
ChainHandler::handle
Handler3::canHandleRequest(true)
Handler3::processRequest
输出结果如下:
image.png
本文主要源于了李建忠的《设计模式》课程。
网友评论