此时学设计模式只能有个大致的了解,不能理解其到底要用在何处,但是先大概根据书中描述留个简单的印象,以后在设计代码时可以有点印象,遇到具体的问题可以类比实践下。
今天学习一下《大话设计模式》中的第24个设计模式,职责链模式,这种模式用在来了一个请求时,从已有的处理类中找到一个合适的类来处理这个请求。(现在肤浅的理解其实就是处理一个具体的对象,需要根据根据此对象不同的属性来确定到底要用哪个类来处理此对象),也可以扩展到消息的处理中,比如处理消息的类有好几个,这几个类组成一个职责链模式,那么对于到来的不同消息,可能需要这几个类中不同的类去处理,那么此时如何按照不同消息类型找到不同的处理类,就是职责链模式可以提供的功能。具体的实现代码如下:
.h 文件:
1 #ifndef _RES_CHAIN_PAT_
2 #define _RES_CHAIN_PAT_
3 #include <string>
4 using namespace std;
5 class Request
6 {
7 public:
8 Request (std::string reqtype, std::string reqCont, int reqNum) : \
9 requestType (reqtype), requestContent (reqCont), requestNum (reqNum) {}
10 std::string getRequestType () { return requestType; }
11 void setRequestType (std::string type) { requestType = type; }
12 std::string getRequestContent () { return requestContent; }
13 void setRequestContent (std::string content) { requestContent = content; }
14 int getRequestNum () { return requestNum; }
15 void setRequestNum ( int nums) { requestNum = nums; }
16 private:
17 std::string requestType;
18 std::string requestContent;
19 int requestNum;
20 };
21
22 class Handler
23 {
24 public:
25 void SetNextHandler (Handler *nHandler) { pNextHandler = nHandler; }
26 virtual void HandleRequest ( Request rqst) = 0;
27 protected:
28 Handler *pNextHandler;
29 };
30
31 class ConcreteHandler1 : public Handler
32 {
33 public:
34 void HandleRequest (Request rqst)
35 {
36 if (rqst.getRequestNum () <= 1000)
37 cout << "ConcreteHandler_1 do request!" << endl;
38 else if (pNextHandler != NULL)
39 pNextHandler->HandleRequest (rqst);
40 }
41 };
42
43 class ConcreteHandler2 : public Handler
44 {
45 public:
46 void HandleRequest (Request rqst)
47 {
48 int Edu = rqst.getRequestNum ();
49 if (Edu > 1000 && Edu <= 2000)
50 cout << "ConcreteHandler_2 do request!" << endl;
51 else if (pNextHandler != NULL)
52 pNextHandler->HandleRequest (rqst);
53 }
54 };
55
56 class ConcreteHandler3 : public Handler
57 {
58 public:
59 void HandleRequest (Request rqst)
60 {
61 int Edu = rqst.getRequestNum ();
62 if (Edu > 2000 && Edu <= 3000)
63 cout << "ConcreteHandler_3 do request!" << endl;
64 else
65 cout << "refuse the request!" << endl;
66 }
67 };
68
69
70 #endif
.cpp 文件:
1 #include <iostream>
2 #include "reschainpat.h"
3
4 using namespace std;
5
6 /* 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。
7 将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止 */
8
9
10
11 int main(void)
12 {
13 Handler *h1 = new ConcreteHandler1 ();
14 Handler *h2 = new ConcreteHandler2 ();
15 Handler *h3 = new ConcreteHandler3 ();
16
17 h1->SetNextHandler (h2);
18 h2->SetNextHandler (h3);
19
20 Request req1 ("word", "zhangxin", 1532);
21 Request req2 ("xxx", "zhangxin", 321);
22 Request req3 ("qiuqiu", "zhangxin", 5674);
23 Request req4 ("hello", "zhangxin", 2536);
24
25 h1->HandleRequest (req1);
26 h1->HandleRequest (req2);
27 h1->HandleRequest (req3);
28 h1->HandleRequest (req4);
29 return 0;
30 }
代码的大部分功能在.h中实现了,其中Request类表示请求类(当然此类也可以表示为其他的东西,比如处理消息请求等),然后为求简单,以不同的requestNum来区分不同的请求类型(同理如果是消息的话,此处可以是不同的消息id)。
注意定义的Handler类和其三个子类,ConcreteHandler1 ,ConcreteHandler12,ConcreteHandler3,其中Handler类是一个抽象类,它提供了处理请求的虚接口HandleRequest,并且它包含了一个Handler指针,此Handler指针被其各个子类继承,并且在子类对象创建时,将此指针设置为当此类不能处理请求时的下一个类。
先看HandleRequest函数,此函数为虚函数,其父类只提供借口,各子类提供具体的实现,本例中各个子类的处理大同小异,都是在处理请求时,如果属于自己处理的范围则简单的通过打印语句表示处理,如果不属于自己处理范围,则调用其pNextHandler所设置的类进行处理。
我们再看.cpp中的应用:首先new出3个具体处理子类,并将第一个子类的pNextHandler设置为第二个类,第二个子类的pNextHandler设置为第三个类,这样就形成了一个处理链条。
程序运行结果如下:
b@:ResponsibilityChain24$ ./resChainPat
ConcreteHandler_2 do request!
ConcreteHandler_1 do request!
refuse the request!
ConcreteHandler_3 do request!
自己对这种模式理解也不深刻,用语言描述也不精确,期待慢慢改善吧,下一个设计模式应该是第26个了。享元模式。