您的位置:首页 > 编程语言 > C语言/C++

【C++】Chapter20:职责链模式

2010-07-17 13:30 267 查看
职责链模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

职责链的好处是当客户提交一个请求时,请求时沿链传递直至有一个ConcreteHandler对象负责处理它。这就使得接收者和发送者都没有对方的明确信息,且链中的对象自己也并不知道链的结构。结果是职责链可简化对象的相互连接,他们仅需保持一个指向其后继者的引用,而不需保持它所有的候选接收者的引用。由于是在客户端来定义链的结构,那么可以随时地增加或修理处理一个请求的结构。增强了给对象指派职责的灵活性。不过也要小心,一个请求极有可能到了链的末尾都得不到处理,或者因为没有正确的配置而得不到处理。







模式框架

工程结构:

(1)抽象处理请求接口类 Handler.h

(2)具体的处理请求类 ConcreteHandler.h

(3)客户端 ChainApp.cpp







(1)抽象处理请求接口类 Handler.h

#ifndef _HANDLER_H_
#define _HANDLER_H_
class Handler
{
public:
    // 设置继任者
    void setSuccessor(Handler* pSuccessor)
    {
        m_pSuccessor = pSuccessor;
    }
    // 处理请求的抽象方法
    virtual void HandlerRequest(int nRequest) = 0;
protected:
    Handler*    m_pSuccessor;
};
#endif// _HANDLER_H_


(2)具体的处理请求类 ConcreteHandler.h

#ifndef _CONCRETE_HANDLER_H_
#define _CONCRETE_HANDLER_H_
#include "Handler.h"
#include <iostream>
using namespace std;
class ConcreteHandler1 : public Handler
{
public:
    virtual void HandlerRequest(int nRequest)
    {
        // 处理此请求0-10的
        if (nRequest >= 0 && nRequest < 10)
        {
            cout << "ConcreteHandler1 处理请求" << nRequest << endl;
        }
        else if (NULL != m_pSuccessor)// 转移到下一个
        {
            m_pSuccessor->HandlerRequest(nRequest);
        }
    }
};
class ConcreteHandler2 : public Handler
{
public:
    virtual void HandlerRequest(int nRequest)
    {
        // 处理此请求10-20的
        if (nRequest >= 10 && nRequest < 20)
        {
            cout << "ConcreteHandler2 处理请求" << nRequest << endl;
        }
        else if (NULL != m_pSuccessor)// 转移到下一个
        {
            m_pSuccessor->HandlerRequest(nRequest);
        }
    }
};
class ConcreteHandler3 : public Handler
{
public:
    virtual void HandlerRequest(int nRequest)
    {
        // 处理此请求20-30的
        if (nRequest >= 20 && nRequest < 30)
        {
            cout << "ConcreteHandler3 处理请求" << nRequest << endl;
        }
        else if (NULL != m_pSuccessor)// 转移到下一个
        {
            m_pSuccessor->HandlerRequest(nRequest);
        }
    }
};
#endif// _CONCRETE_HANDLER_H_


(3)客户端 ChainApp.cpp



// ChainApp.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "ConcreteHandler.h"
void FreePtr(void* ptr)
{
    if (NULL != ptr)
    {
        delete ptr;
        ptr = NULL;
    }
}
int _tmain(int argc, _TCHAR* argv[])
{
    Handler* pHandler1 = new ConcreteHandler1();
    Handler* pHandler2 = new ConcreteHandler2();
    Handler* pHandler3 = new ConcreteHandler3();
    if (NULL != pHandler1 && NULL != pHandler2 && NULL != pHandler3)
    {
        // 设置职责链上家与下家
        pHandler1->setSuccessor(pHandler2);
        pHandler2->setSuccessor(pHandler3);
        pHandler3->setSuccessor(NULL);
        int nRequest[] = {2, 5, 15, 19, 25, 36};
        int n = (sizeof(nRequest) / sizeof(int));
        for (int nEach = 0; nEach < (sizeof(nRequest) / sizeof(int)); nEach++)
        {
            pHandler1->HandlerRequest(nRequest[nEach]);
        }
    }
    system("pause");
    FreePtr(pHandler3);
    FreePtr(pHandler2);
    FreePtr(pHandler1);
	return 0;
}






实际应用

工程结构:

(1)抽象处理请求接口类 Manager.h

(2)具体的处理请求类 ConcreteManager.h

(3)请求类 Request.h

(4)客户端 ChainApp2.cpp









(1)抽象处理请求接口类 Manager.h

#ifndef _MANAGER_H_
#define _MANAGER_H_
#include "Request.h"
class Manager
{
public:
    Manager(const string& strName)
    {
        m_strName = strName;
    }
    // 设置管理者的上级
    void SetSuperior(Manager* pSuperior)
    {
        m_Superior = pSuperior;
    }
    // 申请请求
    virtual void RequestApp(const Request& request) = 0;
protected:
    string      m_strName;
    Manager*    m_Superior;
};
#endif// _MANAGER_H_


(2)具体的处理请求类 ConcreteManager.h

#ifndef _CONCRETE_MANAGER_H_
#define _CONCRETE_MANAGER_H_
#include "Manager.h"
#include <iostream>
using namespace std;
// 经理类
class CommonManager : public Manager
{
public:
    CommonManager(const string& strName)
        : Manager(strName)
        , m_strName(strName)
    {
    }
    virtual void RequestApp(const Request& request)
    {
        if ((0 == (request.GetRequestType()).compare("请假")) && request.GetRequestNumber() <= 2)
        {
            cout << m_strName << ":" << request.GetRequestContent() << "数量" << request.GetRequestNumber() << "被批准" << endl;
        }
        else if (NULL != m_Superior)
        {
            m_Superior->RequestApp(request);
        }
    }
private:
    string m_strName;
};
// 总监类
class Inspector : public Manager
{
public:
    Inspector(const string& strName)
        : Manager(strName)
        , m_strName(strName)
    {
    }
    virtual void RequestApp(const Request& request)
    {
        if ((0 == (request.GetRequestType()).compare("请假")) && request.GetRequestNumber() <= 5)
        {
            cout << m_strName << ":" << request.GetRequestContent() << "数量" << request.GetRequestNumber() << "被批准" << endl;
        }
        else if (NULL != m_Superior)
        {
            m_Superior->RequestApp(request);
        }
    }
private:
    string m_strName;
};
// 总经理
class GeneralManager : public Manager
{
public:
    GeneralManager(const string& strName)
        : Manager(strName)
        , m_strName(strName)
    {
    }
    virtual void RequestApp(const Request& request)
    {
        if ((0 == (request.GetRequestType()).compare("请假")) && request.GetRequestNumber() <= 5)
        {
            cout << m_strName << ":" << request.GetRequestContent() << "数量" << request.GetRequestNumber() << "被批准" << endl;
        }
        else if ((0 == (request.GetRequestType()).compare("加薪")) && request.GetRequestNumber() <= 500)
        {
            cout << m_strName << ":" << request.GetRequestContent() << "数量" << request.GetRequestNumber() << "被批准" << endl;
        }
        else if ((0 == (request.GetRequestType()).compare("加薪")) && request.GetRequestNumber() > 500)
        {
            cout << m_strName << ":" << request.GetRequestContent() << "数量" << request.GetRequestNumber() << "再说吧" << endl;
        }
    }
private:
    string m_strName;
};
#endif// _CONCRETE_MANAGER_H_


(3)请求类 Request.h

#ifndef _REQUEST_H_
#define _REQUEST_H_
#include <string>
using namespace std;
class Request
{
public:
    string GetRequestType(void) const
    {
        return m_strRequestType;
    }
    void SetRequestType(const string& strRequestType)
    {
        m_strRequestType = strRequestType;
    }
    string GetRequestContent(void) const
    {
        return m_strRequestContent;
    }
    void SetRequestContent(const string& strRequestContent)
    {
        m_strRequestContent = strRequestContent;
    }
    int GetRequestNumber(void) const
    {
        return m_nRequestNumber;
    }
    void SetRequestNumber(const int nRequestNumber)
    {
        m_nRequestNumber = nRequestNumber;
    }
private:
    string m_strRequestType;
    string m_strRequestContent;
    int    m_nRequestNumber;
};
#endif// _REQUEST_H_


(4)客户端 ChainApp2.cpp

// ChainApp2.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "ConcreteManager.h"
void freePtr(void* ptr)
{
    if (NULL != ptr)
    {
        delete ptr;
        ptr = NULL;
    }
}
int _tmain(int argc, _TCHAR* argv[])
{
    CommonManager* CM = new CommonManager("经理");
    Inspector*     In = new Inspector("总监");
    GeneralManager*GM = new GeneralManager("总经理");
    if (NULL != CM && NULL != In && NULL != GM)
    {
        // 设置完上级,完全可以根据实际需求来更改设置
        CM->SetSuperior(In);
        In->SetSuperior(GM);
        Request request;
        request.SetRequestType("请假");
        request.SetRequestContent("小王请假");
        request.SetRequestNumber(1);
        CM->RequestApp(request);
        
        request.SetRequestType("请假");
        request.SetRequestContent("小兰请假");
        request.SetRequestNumber(4);
        CM->RequestApp(request);
        
        request.SetRequestType("加薪");
        request.SetRequestContent("小王要求加薪");
        request.SetRequestNumber(500);
        CM->RequestApp(request);
        
        request.SetRequestType("加薪");
        request.SetRequestContent("小王要求加薪");
        request.SetRequestNumber(1000);
        CM->RequestApp(request);
        system("pause");
        freePtr(GM);
        freePtr(In);
        freePtr(CM);
    }
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: