設計模式是前人、大牛等在實際編程中對遇到的問題解決方案的抽象,也就是每一個設計模式都在編程實例中有體現。
1.責任鏈模式在編程中的小體現,看下面的情況:
(1)if else if ....
1 if(a<12){ 2 ... 3 } 4 else if (a<25){ 5 ... 6 } 7 else if(a<67){ 8 ... 9 } 10 else{ 11 ... 12 }
(2)switch case
1 switch(a) 2 { 3 case 1: ;break; 4 case 2: ;break; 5 case 3: ;break; 6 default: 7 }
(3)鏈表next
1 typedef struct node 2 { 3 int value; 4 struct node *next; 5 }TreeNode;
上面的三種情況中,共同特點就是必須依次掃描每個分支進行判斷,找到對應的分支進行處理。(C++、Java中switch也是要遍歷每個分支的)
2.責任鏈模式的定義
責任鏈模式是一種對象的行為模式。在責任鏈模式里,很多對象由每一個對象對其下家的引用而連接起來形成一條鏈。請求在這個鏈上傳遞,直到鏈上的某一個對象決定處理此請求。
責任鏈模式的重點在“鏈”上,有一條鏈去處理相似的請求在鏈中決定由誰去處理這個請求,並返回相應的結果。
在1中的3個例子中,第一個if、switch、Tree root節點就相當於“鏈的入口”,當每個分支都要進行復雜的業務邏輯處理時,使用責任鏈模式比較好。
3.責任鏈模式簡單實例
設計模式是不分語言的。雖然Java提供特有機制對應的關鍵字,如clone(原型模式)、Observable(觀察者模式)等。但是其他語言也可以實現這些,只可能是機制不同而已。
責任鏈模式C++實例代碼:
(1)Handler類是其他具體處理類A、B、D類的父類,提供抽象,公共代碼。
(2)代碼建立責任鏈A->B->D。(責任鏈末尾必須是默認處理類,也即switch中的default部分)
1 #include<iostream> 2 using namespace std; 3 class Handler{ ///處理類抽象 4 public: 5 Handler(int _value):value(_value){} ///設置自身能夠處理的編號 6 virtual ~Handler(){} 7 void setNextHandler(Handler *_nextHandler){ ///設置后繼處理者 8 this->nextHandler=_nextHandler; 9 } 10 virtual void putHandlerMesg(int _value)=0; ///處理者實現進行具體的處理過程 11 12 int value; 13 Handler *nextHandler; 14 }; 15 16 class A:public Handler{ ///處理類A 17 public: 18 A(int _value):Handler(_value){}; 19 ~A(){}; 20 void putHandlerMesg(int _value){ 21 cout<<"A handler this command:"<<_value<<endl; 22 } 23 }; 24 25 class B:public Handler{ ///處理類A 26 public: 27 B(int _value):Handler(_value){}; 28 ~B(){}; 29 void putHandlerMesg(int _value){ 30 cout<<"B handler this command:"<<_value<<endl; 31 } 32 }; 33 34 class D:public Handler{ ///默認處理類D,位於鏈尾部,當其他處理者不能處理時使用 35 public: 36 D(int _value):Handler(_value){}; 37 void putHandlerMesg(int _value){ 38 cout<<"default handler:"<<_value<<endl; 39 } 40 ~D(){}; 41 }; 42 43 int MainHandle(int handlerValue,Handler *a){ ///Main函數進行處理建立的責任鏈 44 Handler *tmp=a; 45 while(1){ 46 if(tmp->value == handlerValue){ 47 tmp->putHandlerMesg(handlerValue); 48 break; 49 } 50 else if(tmp->value == 0) 51 { 52 tmp->putHandlerMesg(handlerValue); 53 break; 54 } 55 else{ 56 tmp=tmp->nextHandler; 57 } 58 } 59 } 60 61 int main(){ 62 ///建立處理鏈,a(1)->b(2)->d(0,default) 63 Handler *a=new A(1); 64 Handler *b=new B(2); 65 Handler *d=new D(0); 66 a->setNextHandler(b); 67 b->setNextHandler(d); 68 69 ///處理的兩個例子 70 MainHandle(2,a); 71 MainHandle(4,a); 72 delete(a); 73 delete(b); 74 delete(d); 75 }
4.責任鏈模式的優缺點
4.1責任鏈模式的優點
實現了請求者與處理者代碼分離:發出這個請求的客戶端並不知道鏈上的哪一個對象最終處理這個請求,這使得系統可以在不影響客戶端的情況下動態地重新組織和分配責任。提高系統的靈活性和可擴展行。
4.2責任鏈模式的缺點
每次都是從鏈頭開始:這也正是鏈表的缺點。你也許會想到一種貌似不錯的解決方案,比如使用hash映射,將要處理的請求id與處理類對象關聯,但是這樣系統損失了可擴展性。
