设计

职责链是行为型设计模式中的一种,关注的是请求发送对象和请求接收对象间的关系,目的是使一个请求被发出后,多个有关联的对象都可能有机会处理这个请求,避免了请求发送者和接收者间的耦合关系。让所有接收者连成一条链,然后请求在这条链上进行传播,直至有对象处理为止,而这些对象可以被动态地绑定。

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
enum class ReqType : char {
null,
type1,
type2,
type3
};

class ChainHandler {
public:
ChainHandler(ChainHandler* successor, ReqType type)
: m_successor(successor), m_type(type) { }

public:
virtual void handleReq(ReqType req) = 0;

protected:
virtual void nextHandler(ReqType req) {
if(m_successor != nullptr) {
m_successor->handleReq(req);
}
}

protected:
ReqType m_type{ ReqType::null };

private:
ChainHandler* m_successor{ nullptr };
};

class Chain1 : public ChainHandler {
public:
Chain1(ChainHandler* successor, ReqType type)
: ChainHandler(successor, type) { }

void handleReq(ReqType req) override {
if(req == m_type) {
cout << "Chain1" << endl;
}
else {
nextHandler(req);
}
}
};

class Chain2 : public ChainHandler {
public:
Chain2(ChainHandler* successor, ReqType type)
: ChainHandler(successor, type) { }

void handleReq(ReqType req) override {
if(req == m_type) {
cout << "Chain2" << endl;
}
else {
nextHandler(req);
}
}
};

class Chain3 : public ChainHandler {
public:
Chain3(ChainHandler* successor, ReqType type)
: ChainHandler(successor, type) { }

void handleReq(ReqType req) override {
if(req == m_type) {
cout << "Chain3" << endl;
}
else {
nextHandler(req);
}
}
};

int main() {
Chain1 c1(nullptr, ReqType::type1);
Chain2 c2(&c1, ReqType::type2);
Chain3 c3(&c2, ReqType::type3);

c3.handleReq(ReqType::type3);
c3.handleReq(ReqType::type2);
c3.handleReq(ReqType::type1);

return 0;
}

首先定义了一个职责链的基类,它负责将处理的请求传递给继承者。所有链上的职责对象在创建时都需要指定自己的继承者。
当一个请求被职责链上的对象处理时——简单起见,我们用一个枚举来表示当前对象可以处理的消息,以及发送的消息,当前对象首先判断自己是否可以处理这个请求,如果可以就处理——这里用打印当前类名来表示,不可以就传递给它的继承者,直至可以被处理或丢弃。
按照main函数中的调用,会得到如下结果:

1
2
3
Chain3
Chain2
Chain1

说明三次调用的请求都被正确地处理了。