對象模式所屬類別簡介
有些組件在內部具有特定的數據結構,如果讓客戶程序依賴這些特定的數據結構,將極大地破壞組件的複用。這時候,將這個特定數據結構封裝在內部,在外部提供統一的接口,來實現與特定數據結構無關的訪問,是一種行之有效的解決方案。
包括Composite、Iterator、Chain of Resposibility
當前模式簡介動機
一個請求可能被多個對象處理,但是每個請求在運行時只能有一個接受者,如果顯示指定,將必不可少的帶來請求者與接受者的緊耦合。
需求
有handle1、handle2、handle3,發送一個指令,如何處理該指令的handle來處理。
設計一。需求更改。設計一更改版本
違反原則
設計二
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
enum RequestType
{
REQ_HANDLE1,
REQ_HANDLE2,
REQ_HANDLE3
};
class Request
{
string m_des;
RequestType m_type;
public:
Request(const string &des, RequestType type):m_des(des),m_type(type){ }
RequestType GetRequest(){ return m_type;}
string GetDescription(){ return m_des; }
};
class ChainHandle
{
ChainHandle *m_next;
public:
void NextHanle(Request *h){ m_next->handle(h); }
virtual bool IsCanhandle(Request *h) = 0;
virtual void DoHanle(Request *h) = 0;
ChainHandle(){m_next = NULL;}
void SetNextHandle(ChainHandle *h){m_next = h;}
void handle(Request *h)
{
if (IsCanhandle(h))
{
DoHanle(h);
}
else
{
NextHanle(h);
}
}
};
class handle1 : public ChainHandle
{
public:
virtual bool IsCanhandle(Request *h)
{
return (h->GetRequest() == REQ_HANDLE1);
}
virtual void DoHanle(Request *h)
{
cout << "Handler1 is handle : " << h->GetDescription() << endl;
}
};
class handle2 : public ChainHandle
{
public:
virtual bool IsCanhandle(Request *h)
{
return (h->GetRequest() == REQ_HANDLE2);
}
virtual void DoHanle(Request *h)
{
cout << "Handler2 is handle : " << h->GetDescription() << endl;
}
};
class handle3 : public ChainHandle
{
public:
virtual bool IsCanhandle(Request *h)
{
return (h->GetRequest() == REQ_HANDLE3);
}
virtual void DoHanle(Request *h)
{
cout << "Handler3 is handle : " << h->GetDescription() << endl;
}
};
int main()
{
handle1 h1;
handle2 h2;
handle3 h3;
h1.SetNextHandle(&h2);
h2.SetNextHandle(&h3);
Request req("process task ... ", RequestType::REQ_HANDLE3);
h1.handle(&req);
return 0;
}
設計二更改版本
設計二比設計一區別
一條鏈把三個對象連接起來,每個對象一個類型,符合的才進入,不符合下一個對象處理(每個對象都擁有自己的下一個對象元素)。
模式定義
使多個對象都有機會處理請求,從而避免請求的發送者和接受者之間的耦合關係。將這些對象連成一條鏈,並沿着這條鏈傳遞請求,知道有一個對象處理它爲止。