责任链模式实现为请求创建了一个接收者对象的链。当请求的直接执行者无法实现请求时,会将请求传递给链的上一级进行处理。这种传递往往可以通过让接收者包含另一个接收者的引用的方式实现。
责任链模式是一种对象行为型模式,其主要优点如下。
- 降低了对象之间的耦合度。该模式使得一个对象无须知道到底是哪一个对象处理其请求以及链的结构,发送者和接收者也无须拥有对方的明确信息。
- 增强了系统的可扩展性。可以根据需要增加新的请求处理类,满足开闭原则。
- 增强了给对象指派职责的灵活性。当工作流程发生变化,可以动态地改变链内的成员或者调动它们的次序,也可动态地新增或者删除责任。
- 责任链简化了对象之间的连接。每个对象只需保持一个指向其后继者的引用,不需保持其他所有处理者的引用,这避免了使用众多的 if 或者 if···else 语句。
- 责任分担。每个类只需要处理自己该处理的工作,不该处理的传递给下一个对象完成,明确各类的责任范围,符合类的单一职责原则。
其主要缺点如下。
- 不能保证每个请求一定被处理。由于一个请求没有明确的接收者,所以不能保证它一定会被处理,该请求可能一直传到链的末端都得不到处理。
- 对比较长的职责链,请求的处理可能涉及多个处理对象,系统性能将受到一定影响。
- 职责链建立的合理性要靠客户端来保证,增加了客户端的复杂性,可能会由于职责链的错误设置而导致系统出错,如可能会造成循环调用。
UML:
举例:当在公司中请假,公司规定根据请假的天数和事由调整批复对象,首先是项目经理Project Manager, 不能批复找Department Manager, 再不能上升到总经理President。
C++实现:
1 #include <iostream>
2
3 using namespace std;
4
5 class Request{
6 public:
7 int level;
8 };
9
10 class Manager{
11 public:
12 Manager(string _name){name = _name;}
13 void setSuccessor(Manager* manager){nextLevel = manager;}
14 virtual void GetRequest(Request* request)=0;
15 protected:
16 Manager* nextLevel;
17 string name;
18 };
19
20 class ProjectManager:public Manager{
21 public:
22 ProjectManager(string _name):Manager(_name){}
23 virtual void GetRequest(Request *request){
24 if (request->level <= 1){
25 cout << name << " handle it" << endl;
26 } else {
27 nextLevel->GetRequest(request);
28 }
29 }
30 };
31
32 class DepartmentManager:public Manager{
33 public:
34 DepartmentManager(string _name):Manager(_name){}
35 virtual void GetRequest(Request *request){
36 if (request->level <= 2){
37 cout << name << " handle it" << endl;
38 } else {
39 nextLevel->GetRequest(request);
40 }
41 }
42 };
43
44 class President:public Manager{
45 public:
46 President(string _name):Manager(_name){}
47 virtual void GetRequest(Request *request){
48 cout << name << " handle it" << endl;
49 }
50 };
51
52 int main()
53 {
54 Request *request = new Request();
55 request->level = 3;
56 Manager *projectManager = new ProjectManager("Project Manager: Alice");
57 Manager *departmentManager = new DepartmentManager("Department manager: Helen");
58 Manager *president = new President("President: Chalice");
59 projectManager->setSuccessor(departmentManager);
60 departmentManager->setSuccessor(president);
61 projectManager->GetRequest(request);
62 return 0;
63 }
Java:
1 public class Request {
2 int level;
3 }
4
5 public abstract class Manager {
6
7 private Manager next;
8
9 public void setNext(Manager next){
10 this.next = next;
11 }
12
13 public Manager getNext(){
14 return next;
15 }
16
17 public abstract void handleRequest(Request request);
18 }
19
20 public class ProjectManager extends Manager {
21
22 @Override
23 public void handleRequest(Request request) {
24 if (request.level <= 1){
25 System.out.println("Project Manager handle request");
26 } else {
27 this.getNext().handleRequest(request);
28 }
29 }
30 }
31
32 public class DepartmentManager extends Manager {
33
34 @Override
35 public void handleRequest(Request request) {
36 if (request.level <= 2){
37 System.out.println("Department manager handle request");
38 } else {
39 this.getNext().handleRequest(request);
40 }
41 }
42 }
43
44 public class President extends Manager {
45
46 @Override
47 public void handleRequest(Request request) {
48 System.out.println("President handle request");
49 }
50 }
51
52 public class Main {
53
54 public static void main(String[] args) {
55 Manager projectManager = new ProjectManager();
56 Manager departmentManager = new DepartmentManager();
57 Manager president = new President();
58 projectManager.setNext(departmentManager);
59 departmentManager.setNext(president);
60 Request request = new Request();
61 request.level = 3;
62 projectManager.handleRequest(request);
63 }
64 }