设计模式(十八)——职责链模式

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式(十八)——职责链模式相关的知识,希望对你有一定的参考价值。

设计模式(十八)——职责链模式

一、职责链模式简介

1、职责链模式简介

职责链模式(Chain Of Responsibility)使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合。将可能处理请求的对象连成一条链,并沿着这条链传递请求,直到有一个对象处理请求为止。

技术分享

2、职责连模式角色

        Handler类:职责对象抽象类,定义一个处理请求的接口。

        ConcreteHandler类:职责对象具体类,实现具体的处理请求的接口。

3、职责链模式优缺点

      职责链模式的优点:

    A当客户提交一个请求时,请求沿链传递直至有一个ConcreteHandler对象负责处理请求

    B接收者和发送者都没有对方的明确信息,且链中的对象自己也并不知道链的结构。结果是职责链可简化对象的相互连接,仅需要保持一个指向其后继者的引用,而不需要保持所有的候选接收者的引用。

    C由于是在客户端来定义链的结构,所以用户可以随时地增加或者修改处理一个请求的结构增强了给对象指派职责的灵活性。

职责链模式的缺点:

一个请求极有可能到了链的末端都得不到处理,或者因为没有正确配置而得不到处理。

4、职责链模式使用场景

职责链模式使用场景:

A有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定。

B、在不明确指定接收者的情况下,向多个对象中的一个提交请求。

C可处理一个请求的对象集合应被动态指定。

二、职责连模式实现

Handler抽象类:

#ifndef HANDLER_H
#define HANDLER_H
#include <iostream>
using namespace std;
 
//处理请求的抽象类
class Handler
{
public:
    //设置后继处理请求者
    void setSuccessor(Handler* successor)
    {
        m_successor = successor;
    }
    //处理请求的接口
    virtual void handleRequest(int n) = 0;
protected:
    Handler(){}
protected:
    Handler* m_successor;//后继者
};
 
#endif // HANDLER_H


ConcreteHandlerA具体处理类:

#ifndef CONCRETEHANDLERA_H
#define CONCRETEHANDLERA_H
#include "Handler.h"
 
//处理请求的具体实现类
class ConcreteHandlerA : public Handler
{
public:
    void handleRequest(int n)
    {
        if(n < 1000)
        {
            cout << "ConcreteHandlerA::handleRequest n = " << n << endl;
        }
        else//如果n>1000,由后继者处理请求
        {
            if(m_successor)
                m_successor->handleRequest(n);
        }
    }
};
 
#endif // CONCRETEHANDLERA_H


ConcreteHandlerB具体处理类:

#ifndef CONCRETEHANDLERB_H
#define CONCRETEHANDLERB_H
#include "Handler.h"
 
//处理请求的具体实现类
class ConcreteHandlerB : public Handler
{
public:
    void handleRequest(int n)
    {
        cout << "ConcreteHandlerB::handleRequest n = " << n << endl;
    }
};
 
#endif // CONCRETEHANDLERB_H


 

客户调用程序:

#include "Handler.h"
#include "ConcreteHandlerA.h"
#include "ConcreteHandlerB.h"
 
int main()
{
    Handler* a = new ConcreteHandlerA();
    Handler* b = new ConcreteHandlerB();
 
    a->setSuccessor(b);
    a->handleRequest(200);
    a->handleRequest(1200);
 
    delete a,b;
 
    return 0;
}


三、职责链模式实例

公司中对于请假、加薪等请求有不同的处理流程,不同的请求需要由经理、技术总监、总经理处理。但所有的请求必须提交给经理,如果经理没有权限,转给技术总监,技术总监没有权限,转给总经理处理。

技术分享

Request请求类:

#ifndef REQUEST_H
#define REQUEST_H
#include <string>
using namespace std;
 
//请求
class Request
{
public:
    void setType(string type)
    {
        m_requestType = type;
    }
    string getType()
    {
        return m_requestType;
    }
    void setContent(string content)
    {
        m_requestContent = content;
    }
    string getContent()
    {
        return m_requestContent;
    }
    void setNumber(int n)
    {
        m_number = n;
    }
    int getNumber()
    {
        return m_number;
    }
private:
    string m_requestType;//请求类型
    string m_requestContent;//请求内容
    int m_number;//数量
};
 
#endif // REQUEST_H


Manager处理请求的抽象类:

#ifndef MANAGER_H
#define MANAGER_H
#include <string>
#include <iostream>
#include "Request.h"
using namespace std;
 
//Handler抽象类
class Manager
{
public:
    ~Manager()
    {
        if(m_superior != NULL)
            delete m_superior;
    }
    //处理请求接口
    virtual void requestApplication(Request* request) = 0;
    //设置上级
    void setSuperior(Manager* superior)
    {
        m_superior = superior;
    }
protected:
    Manager(string name)
    {
        m_name = name;
        m_superior = NULL;
    }
protected:
    string m_name;//管理者姓名
    Manager* m_superior;//管理者的上级
};
 
#endif // MANAGER_H


CommonManager处理请求的具体类:

#ifndef COMMONMANAGER_H
#define COMMONMANAGER_H
#include "Manager.h"
 
//Handler具体实现类,处理请求的具体对象,经理
class CommonManager : public Manager
{
public:
    CommonManager(string name):Manager(name){}
    //请求处理函数
    void requestApplication(Request* request)
    {
        if(request->getType() == "ask for leave" && request->getNumber() <= 2)
        {
            cout << m_name << ":" << request->getContent() << " number:"
                 << request->getNumber() << "day    approval" << endl;
        }
        else
        {
            if(m_superior != NULL)
                m_superior->requestApplication(request);
        }
    }
};
 
#endif // COMMONMANAGER_H


Majordomo处理请求的具体类:

#ifndef MAJORDOMO_H
#define MAJORDOMO_H
#include "Manager.h"
 
//Handler具体实现类,处理请求的具体对象,技术总监
class Majordomo : public Manager
{
public:
    Majordomo(string name):Manager(name){}
    //处理请求函数
    void requestApplication(Request* request)
    {
        if(request->getType() == "ask for leave" && request->getNumber() <= 5)
        {
            cout << m_name << ":" << request->getContent() << " number:"
                 << request->getNumber() << "day    approval" << endl;
        }
        else
        {
            if(m_superior != NULL)
                m_superior->requestApplication(request);
        }
    }
};
 
#endif // MAJORDOMO_H


GeneralManager处理请求的具体类:

#ifndef GENERALMANAGER_H
#define GENERALMANAGER_H
#include "Manager.h"
 
//Handler具体实现类,处理请求的具体对象,总经理
class GeneralManager : public Manager
{
public:
    GeneralManager(string name):Manager(name){}
    //处理请求函数
    void requestApplication(Request* request)
    {
        if(request->getType() == "ask for leave")
        {
            cout << m_name << ":" << request->getContent() << " number:"
                 << request->getNumber() << "day    approval" << endl;
        }
        else if(request->getType() == "ask for a raise" && request->getNumber() <= 1000)
        {
            cout << m_name << ":" << request->getContent() << " number:"
                 << request->getNumber() << "    approval" << endl;
        }
        else if(request->getType() == "ask for a raise" && request->getNumber() > 1000)
        {
            cout << m_name << ":" << request->getContent() << " number:"
                 << request->getNumber() << "    rejected" << endl;
        }
    }
};
 
#endif // GENERALMANAGER_H


客户调用程序:

#include "Manager.h"
#include "CommonManager.h"
#include "Majordomo.h"
#include "GeneralManager.h"
 
int main()
{
    Manager* li = new CommonManager("Li");
    Manager* zhang = new Majordomo("zhang");
    Manager* wang = new GeneralManager("wang");
 
    li->setSuperior(zhang);//设置CommonManager上级为Majordomo
    zhang->setSuperior(wang);//设置Majordomo上级为GeneralManager
 
    Request request1;
    request1.setType("ask for leave");//请假
    request1.setContent("xiaoming ask for leave");
    request1.setNumber(1);
    li->requestApplication(&request1);
 
    Request request2;
    request2.setType("ask for a raise");//加薪
    request2.setContent("xiaohong ask for a raise");
    request2.setNumber(1000);
    li->requestApplication(&request2);
 
    Request request3;
    request3.setType("ask for a raise");//加薪
    request3.setContent("xiaozhang ask for a raise");
    request3.setNumber(2000);
    li->requestApplication(&request3);
 
    Request request4;
    request4.setType("ask for leave");//请假
    request4.setContent("xiaozhang ask for leave");
    request4.setNumber(5);
    li->requestApplication(&request4);
 
    delete li,zhang,wang;
    return 0;
}


本文出自 “生命不息,奋斗不止” 博客,谢绝转载!

以上是关于设计模式(十八)——职责链模式的主要内容,如果未能解决你的问题,请参考以下文章

设计模式 职责链模式

职责链模式vs状态模式区别

设计模式 行为型模式 -- 职责链模式(JDK源码分析:FilterChain(过滤器))

JAVA设计模式大总结(二十三)--- b站尚硅谷设计模式之 职责链模式 图解 + 代码 整理(超详)

利用职责链模式分解If else

职责链模式