职责链模式使得一个软件系统中的多个对象都有机会处理请求,将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止,从而避免请求的发送者和接收者之间产生强耦合关系。
常见的应用程序框架中有很多职责链模式的应用,比如 MFC 中的消息处理机制、 Android 中的按键处理流程、Qt 中的事件处理机制等等。
下图是职责链模式的 UML 图示:
这里举一个简单的示例。是这样的,某个家庭有一个小菇凉,有爸爸、妈妈、奶奶,小菇凉想要吃巧克力,就挨个问,直到有人同意就开吃。
头文件:
class Child {
Child();
void eatChocolate();
void setHandler(Handler *handler);
private:
Handler * m_pHandler;
};
class Handler {
Handler();
virtual ~Handler();
virtual bool canIEatChocolate() = 0;
void setSuccessor(Handler * handler){ m_pSuccessor = handler;}
Handler * successor(){ return m_pSuccessor;}
private:
Handler * m_pSuccessor;
};
class Mother : public Handler{
bool canIEatChocolate();
};
class Father : public Handler{
bool canIEatChocolate();
};
class Grandmother : public Handler{
bool canIEatChocolate();
};
源文件(这里设定爸爸、妈妈都不让吃,奶奶让吃):
Child::Child():m_handler(0)
{}
void Child::eatChocolate(){
if(m_pHandler->canIEatChocolate()){
laughThenEat();
}else{
cry();
}
}
void Child::setHandler(Handler * handler){
m_pHandler = handler;
}
Handler::Handler():m_pSuccessor(0){
}
bool Mother::canIEatChocolate(){
if(successor()){
return successor->canIEatChocolate();
}else{
return false;
}
}
bool Father::canIEatChocolate(){
if(successor()){
return successor->canIEatChocolate();
}else{
return false;
}
}
bool Grandmother::canIEatChocolate(){
if(successor()){
return successor->canIEatChocolate();
}else{
return true;
}
}
驱动代码, main() 函数:
int main(int argc, char**argv)
{
Child * child = new Child;
Mother * mother = new Mother;
Father * father = new Father;
Grandmother * grandmother = new Grandmother;
mother->setSuccessor(father);
father->setSuccessor(grandmother);
child->setHandler(mother);
child->eatChocolate();
return 0;
}
好啦,以上就是职责链模式的一个简单实现。这里手动建立了一个链表,将链表头指针设置给 Child 。另一个更常用的做法,是在 Child 内部维护一个链表,在Child::eatChocolate() 函数内部使用循环遍历链表,遇到 canIEatChocolate() 返回 true 就停止,这里不再赘述了。
回顾一哈: