1. 程式人生 > >設計模式(十八)——職責鏈模式

設計模式(十八)——職責鏈模式

設計模式 職責鏈模式

設計模式(十八)——職責鏈模式

一、職責鏈模式簡介

1、職責鏈模式簡介

職責鏈模式(Chain Of Responsibility)使多個對象都有機會處理請求,從而避免請求的發送者和接收者之間的耦合。將可能處理請求的對象連成一條鏈,並沿著這條鏈傳遞請求,直到有一個對象處理請求為止。

技術分享

2、職責連模式角色

Handle

r類:職責對象抽象類,定義一個處理請求的接口。

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;
}


本文出自 “生命不息,奮鬥不止” 博客,謝絕轉載!

設計模式(十八)——職責鏈模式