设计模式介绍之八:职责链模式(Chain of responsibility)

10 篇文章 1 订阅

    职责链模式使得一个软件系统中的多个对象都有机会处理请求,将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止,从而避免请求的发送者和接收者之间产生强耦合关系。

    常见的应用程序框架中有很多职责链模式的应用,比如 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 就停止,这里不再赘述了。


    回顾一哈:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

foruok

你可以选择打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值