Chain of Responsibility(职责链)模式总结
- 前言
- 一、职责链模式总结
- 1、模式意图
- 2、参与者
- 3、结构、适用性及效果
- 二、职责链模式应用示例
- 1、用例背景描述
- 2、用例结构图
- 3、类说明
- 总结
前言
本周五参加了Chain of Responsibility(职责链)模式研讨会,本文的目的是对这个模式的总结和分享,希望对需要学习这个设计模式的同学有所帮助。本文一共分为两个部分,第一个部分是职责链模式的基础知识总结;第二个部分是职责链模式的一个例子分享。一、职责链模式总结
1、模式意图
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。2、参与者
Handler-- 定义一个处理请求的接口;
-- 实现后继链;
ConcreteHandler
-- 处理它所负责的请求;
-- 可访问它的后继者;
-- 如果可以请求,则处理并返回,否则将请求转发给它的后继者;
Client
-- 向链上的具体处理者对象提交请求;
3、结构、适用性及效果
结构图:1、有多个对象可以处理一个请求,哪个对象处理请求运行时自动确定;
2、你想在不明确指定接收者的情况下,向多个对象中的一个提交一个请求;
3、可处理一个请求的对象的集合需要动态指定时;
效果:
1、降低耦合度;职责链模式使得一个对象不用知道是哪一个对象处理它的请求。对象仅需要知道该请求会被正确的处理。接收者和发送者都没有对方的明确的信息,且链中的对象不需要知道链的结构。
2、增强了给对象指派职责的灵活性;当在对象中分派职责时,职责链给你更多的灵活性。你可以通过在运行时对该链进行动态的增加或修改来增加或改变处理一个请求的那些职责。
3、不保证请求被处理;既然一个请求没有明确的接收者,那么就不能保证它一定会被处理;该请求可能一直到链的末端都得不到处理。一个请求也可能因该链没有被正确配置而得不到处理。
二、职责链模式应用示例
1、用例背景描述
职责链模式经常用于网络开发,下面举的一个例子是关于充值返利方面的应用。在一个网络应用中,我们可以对用户进行等级划分,等级越高的用户,充值返利越多,等级越低的用户,充值返利则相对较少。2、用例结构图
3、类说明
1、RebateHandler :定义抽象充值返利接口,后继节点维护接口及业务相关公共接口:复制代码
2、RebateHandlerVip0 ~ RebateHandlerVip2 ·:具体处理节点类,实现具体的充值返利功能: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
61class RebateHandler { public: RebateHandler(int level); //充值返利接口,根据输入用户对象及充值金额,返回返利后的总充值额。 virtual double getRebate(User* user, double count); //设置后继节点 void set_next_handler(RebateHandler* handler); protected: //根据用户等级获取返利比率 double get_level_rate(int level); //获取后继节点 RebateHandler* get_next_handler(); //设置相应等级的返利比率 void set_level_rate(int level, double rate); //获取当前处理节点的用户等级 int get_level(); private: std::map<int,double> m_rate_table; RebateHandler* m_next_handler; int m_lever; }; RebateHandler::RebateHandler(int level) : m_lever(level){ m_next_handler = NULL; } double RebateHandler:: getRebate(User* user, double count) { if (m_next_handler != NULL) { return m_next_handler->getRebate(user, count); } else { double rate = this->get_level_rate(user->get_level()); return rate*count; } } double RebateHandler::get_level_rate(int level) { if (m_rate_table.find(level) != m_rate_table.end()) { return m_rate_table[level]; } else { return 1.0; } } RebateHandler* RebateHandler::get_next_handler() { return m_next_handler; } void RebateHandler::set_next_handler(RebateHandler *handler) { m_next_handler = handler; } int RebateHandler::get_level() { return m_lever; } void RebateHandler::set_level_rate(int level, double rate) { m_rate_table[level] = rate; }
复制代码
3、User :用户类,用于发送请求,处理节点会根据用户的等级做相应的处理。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
65class RebateHandlerVip0 : public RebateHandler { public: RebateHandlerVip0(); virtual double getRebate(User* user, double count); }; RebateHandlerVip0::RebateHandlerVip0() : RebateHandler(0) { this->set_level_rate(this->get_level(), 1.0); } double RebateHandlerVip0::getRebate(User *user, double count) { (void)user; double rate = this->get_level_rate(this->get_level()); return rate*count; } class RebateHandlerVip1 : public RebateHandler { public: RebateHandlerVip1(); virtual double getRebate(User* user, double count); }; RebateHandlerVip1::RebateHandlerVip1() : RebateHandler(1) { this->set_level_rate(this->get_level(), 1.1); } double RebateHandlerVip1::getRebate(User* user, double count) { if (user->get_level() >= this->get_level()) { double rate = this->get_level_rate(this->get_level()); return rate*count + 10; } else { RebateHandler* next_handler = get_next_handler(); if (next_handler != NULL) { return next_handler->getRebate(user, count); } else { return RebateHandler::getRebate(user, count); } } } class RebateHandlerVip2 : public RebateHandler { public: RebateHandlerVip2(); virtual double getRebate(User* user, double count); }; RebateHandlerVip2::RebateHandlerVip2() : RebateHandler(2) { this->set_level_rate(this->get_level(), 1.2); } double RebateHandlerVip2::getRebate(User *user, double count) { if (user->get_level() >= this->get_level()) { double rate = this->get_level_rate(this->get_level()); return rate*count + 20; } else { RebateHandler* next_handler = get_next_handler(); if (next_handler != NULL) { return next_handler->getRebate(user, count); } else { return RebateHandler::getRebate(user, count); } } }
复制代码
4、用户代码。三个不同等级的处理节点及三个不同等级的用户,它们充值相同的金额,但返利数量不同,用户等级越高,返利越多,反之则越少。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23class User { public: User(int level); int get_level(); void set_level(int level); private: int m_level; }; User::User(int level) : m_level(level) { } User::get_level() { return m_level; } void User::set_level(int level) { m_level = level; }
复制代码
5、运行结果。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
29RebateHandler* header = NULL; // 处理节点 RebateHandlerVip2* vip2 = new RebateHandlerVip2(); RebateHandlerVip1* vip1 = new RebateHandlerVip1(); RebateHandlerVip0* vip0 = new RebateHandlerVip0(); // 处理链 header = vip2; vip2->set_next_handler(vip1); vip1->set_next_handler(vip0); // 用户 User* vip2_player = new User(2); User* vip1_player = new User(1); User* vip0_player = new User(0); //充值100 double vip2_count = header->getRebate(vip2_player, 100); double vip1_count = header->getRebate(vip1_player, 100); double vip0_count = header->getRebate(vip0_player, 100); //充值返利后实际额度 printf("vip2_count : %fn", vip2_count); printf("vip1_count : %fn", vip1_count); printf("vip0_count : %fn", vip0_count);
总结
根据上述例子,我们可以看到,对于相同的请求,处理请求的节点可以不同,这样就把请求对象和处理对象完全解耦,增加了程序的灵活性。最后
以上就是高贵火龙果最近收集整理的关于Chain of Responsibility(职责链)模式前言一、职责链模式总结二、职责链模式应用示例总结的全部内容,更多相关Chain内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复