一. 概述
職責鏈模式:
使多個對象都有機會處理請求,從而避免請求的發送者和接收者之間的耦合關系。將這些對象連成一條鏈,並沿著這條鏈傳遞該請求,直到有一個對象處理它為止。
二. 舉個例子
員工要求加薪
公司的管理者一共有三級:總經理、總監、經理,如果一個員工要求加薪,應該向主管的經理申請,如果加薪的數量在經理的職權內,那麼經理可以直接批准,否則將申請上交給總監。總監的處理方式也一樣,總經理可以處理所有請求。這就是典型的職責鏈模式,請求的處理形成了一條鏈,直到有一個對象處理請求。
結構圖如下:
假設:
經理可以處理薪水的范圍在:0~500
總監可以處理薪水的范圍在:500~1000
總經理可以處理薪水的范圍在:1000~2000
則代碼如下:
[cpp] //////////////////////////////////////////////////////////////////////////
//抽象處理類
class Handle
{
public:
virtual ~Handle()
{
delete _succ;
}
virtual void HandleRequest(int request) = 0;
//設置其上級
void SetSuccessor(Handle* succ)
{
_succ = succ;
}
Handle* GetSuccessor()
{
return _succ;
}
protected:
Handle()
{
_succ = NULL;
}
private:
Handle* _succ;
};
//具體處理類 A
class ConcreteHandleA: public Handle
{
public:
void HandleRequest(int request)
{
if (request >= 0 && request < 500)
{
cout << "ConcreteHandleA deal with: " << request <<endl;
}
else if (this->GetSuccessor() != NULL)
{
this->GetSuccessor()->HandleRequest(request);
}
else
{
cout << "Can't deal with " << request << endl;
}
}
};
//具體處理類 B
class ConcreteHandleB: public Handle
{
public:
void HandleRequest(int request)
{
if (request >= 500 && request < 1000)
{
cout << "ConcreteHandleB deal with: " << request <<endl;
}
else if (this->GetSuccessor() != NULL)
{
this->GetSuccessor()->HandleRequest(request);
}
else
{
cout << "Can't deal with " << request << endl;
}
}
};
//具體處理類 C
class ConcreteHandleC: public Handle
{
public:
void HandleRequest(int request)
{
if (request >= 1000 && request < 2000)
{
cout << "ConcreteHandleC deal with: " << request <<endl;
}
else if (this->GetSuccessor() != NULL)
{
this->GetSuccessor()->HandleRequest(request);
}
else
{
cout << "Can't deal with " << request << endl;
}
}
};
//////////////////////////////////////////////////////////////////////////
//測試
int main()
{
Handle* h1 = new ConcreteHandleA();
Handle* h2 = new ConcreteHandleB();
Handle* h3 = new ConcreteHandleC();
//設置其上級
h1->SetSuccessor(h2);
h2->SetSuccessor(h3);
h1->HandleRequest(300);
h1->HandleRequest(600);
h1->HandleRequest(1500);
h1->HandleRequest(3000);
delete h1;
delete h2;
delete h3;
return 0;
}
//////////////////////////////////////////////////////////////////////////
//抽象處理類
class Handle
{
public:
virtual ~Handle()
{
delete _succ;
}
virtual void HandleRequest(int request) = 0;
//設置其上級 www.2cto.com
void SetSuccessor(Handle* succ)
{
_succ = succ;
}
Handle* GetSuccessor()
{
return _succ;
}
protected:
Handle()
{
_succ = NULL;
}
private:
Handle* _succ;
};
//具體處理類 A
class ConcreteHandleA: public Handle
{
public:
void HandleRequest(int request)
{
if (request >= 0 && request < 500)
{
cout << "ConcreteHandleA deal with: " << request <<endl;
}
else if (this->GetSuccessor() != NULL)
{
this->GetSuccessor()->HandleRequest(request);
}
else
{
cout << "Can't deal with " << request << endl;
}
}
};
//具體處理類 B
class ConcreteHandleB: public Handle
{
public:
void HandleRequest(int request)
{
if (request >= 500 && request < 1000)
{
cout << "ConcreteHandleB deal with: " << request <<endl;
}
else if (this->GetSuccessor() != NULL)
{
this->GetSuccessor()->HandleRequest(request);
}
else
{
cout << "Can't deal with " << request << endl;
}
}
};
//具體處理類 C
class ConcreteHandleC: public Handle
{
public:
void HandleRequest(int request)
{
if (request >= 1000 && request < 2000)
{
cout << "ConcreteHandleC deal with: " << request <<endl;
}
else if (this->GetSuccessor() != NULL)
{
this->GetSuccessor()->HandleRequest(request);
}
else
{
cout << "Can't deal with " << request << endl;
}
}
};
//////////////////////////////////////////////////////////////////////////
//測試
int main()
{
Handle* h1 = new ConcreteHandleA();
Handle* h2 = new ConcreteHandleB();
Handle* h3 = new ConcreteHandleC();
//設置其上級
h1->SetSuccessor(h2);
h2->SetSuccessor(h3);
h1->HandleRequest(300);
h1->HandleRequest(600);
h1->HandleRequest(1500);
h1->HandleRequest(3000);
delete h1;
delete h2;
delete h3;
return 0;
}
三. 說明
1. 職責鏈的特點是:當客戶提交一個請求時,請求是沿鏈傳遞直至有一個ConcreteHandler對象負責處理它。
2. 職責鏈的好處是:請求者不用管哪個對象來處理,反正該請求會被處理。它只需保持一個後繼者即可。
3. 要注意的是:一個請求到鏈的最後可能也沒有處理,所以一定要配置得當。
作者 lwbeyond