日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

模式之消息树

發布時間:2023/12/16 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 模式之消息树 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

消息樹,并不是公認的設計模式之一,是本人根據觀察者模式發展來的,并于軟件實踐中得以廣泛應用,已經是本人的支柱編碼結構。

觀察者模式是觀察者、被觀察者,兩者有從屬關系,被觀察者主動改變,通知觀察者。并且在觀察者更新的時候也有不方便的地方(見模式之觀察者模式)。下面是筆者設計的消息樹:

消息樹分兩部分,消息和消息節點。消息節點可以組成樹狀結構(消息節點有父子關系:一父多子)。消息就在消息樹上跑。由于面向對象編程的編程方式,很自然的會形成很多樹狀結構的東西,而且,為了方便協調需要通信。消息樹建立了一個樹狀通信通道,任意節點都是消息的發起位置,也是消息的處理位置,消息在樹上有兩種流動模式,向上即向根節點流動是單條流動路線,向下即向葉子節點流動是廣播,廣播節點以下都能收到消息。消息發出后沿樹流動直到有節點處理后返回,這種發消息,處理消息可以是消息樹的若干級之間。對于一個節點,它發消息,不用管誰處理,只要明白向父節點發還是廣播給子節點,最終有節點處理就可以了,到底誰處理是透明的。而且,消息是可以定制的,可以根據情況傳任意數據,而且推拉模式都行。消息節點是消息的發送位置同時也是接收位置,每個消息節點決定自己可以處理那些消息,處理不了的不用管,處理消息也分為向上流動的消息和向下流動的消息。

template<class MessageCodeType>

class CMessage

{

public:

??? CMessage(MessageCodeType code):m_code(code){};

??? virtual ~CMessage(){};

public:

??? MessageCodeType GetCode()

??? {

??????? return m_code;

??? }

private:

??? MessageCodeType m_code;

};

template<class MessageType,class MessageCodeType>

class CMessageNode

{

public:

??? typedef MessageType????????? Message;

??? typedef CMessageNode<Message,MessageCodeType> MessageNode;

??? typedef set<MessageNode* >?? NodeSet;

??? typedef set<MessageCodeType> MessageFilterSet;

??? typedef typename NodeSet::iterator subIterator;

public:

??? CMessageNode():m_pParent(NULL){};

??? virtual ~CMessageNode()

??? {

??????? if(NULL != m_pParent)

??????? {

??? ??? ??? m_pParent->RemoveSubNode(this);

??????? }

??????? for(subIterator it = m_setSubNodes.begin();it!=m_setSubNodes.end();it++)

??????? {

??????????? (*it)->m_pParent = NULL;

??????? }

??? };

public:

??? bool SetParNode(MessageNode* pPar)

??? {

??????? if(NULL != m_pParent)

??????? {

??? ??????? m_pParent->RemoveSubNode(this);

??????? }

??????? if(NULL == pPar)

??????? {

??????????? m_pParent = NULL;

??????????? return true;

??????? }

??????? return pPar->AddSubNode(this);

??? }

??? MessageNode* GetParNode()

??? {

??????? return m_pParent;

??? }

??? bool AddSubNode(MessageNode* pNode)

??? {

??????? if(m_setSubNodes.insert(pNode).second)

??????? {

??????????? pNode->m_pParent = this;

??????????? return true;

??????? }

??????? return false;

??? }

??? bool FindSubNode(MessageNode* pNode)

??? {

??????? return m_setSubNodes.find(pNode)!=m_setSubNodes.end();

??? }

??? bool RemoveSubNode(MessageNode* pNode)

??? {

??????? subIterator it = m_setSubNodes.find(pNode);

??????? if(it == SubEnd())

??????????? return false;

??????? (*it)->m_pParent = NULL;

??????? m_setSubNodes.erase(it);

??????? return true;

??? }

??? int GetSubNodeCount()

??? {

??????? return (int)m_setSubNodes.size();

??? }

??? subIterator SubBegin()

??? {

??????? return m_setSubNodes.begin();

??? }

??? subIterator SubEnd()

??? {

??????? return m_setSubNodes.end();

??? }

??? //添加向上經過此點的消息過濾

??? void AddUpMessageFiltrateItem(MessageCodeType code)

??? {

??????? m_setMessageUpFilter.insert(code);

??? }

??? //添加向下經過此點的消息過濾

??? void AddDownMessageFiltrateItem(MessageCodeType code)

??? {

??????? m_setMessageDownFilter.insert(code);

??? }

??? void ClearUpMessageFilter()

??? {

??????? m_setMessageUpFilter.clear();

??? }

??? void ClearDownMessageFilter()

??? {

??????? m_setMessageDownFilter.clear();

??? }

??? void DeleteUpMessageFiltrateItem(MessageCodeType code)

??? {

??????? m_setMessageUpFilter.erase(code);

??? }

??? void DeleteDownMessageFiltrateItem(MessageCodeType code)

??? {

??????? m_setMessageDownFilter.erase(code);

??? }

protected:

??? //如果處理了返回true,否則返回false

??? void SendUpMessage(Message* pM)

??? {

??????? if(NULL != m_pParent)

??????? ??? SendUpMessage(m_pParent,pM);

??? }

???

??? //如果處理了返回true,否則返回false

??? void SendDownMessage(Message* pM)

??? {

??????? for(subIterator it = SubBegin();it!=SubEnd();it++)

??????? {

??????????? SendDownMessage(*it,pM);

??????? }

??? }

public:

??? static void SendUpMessage(MessageNode* pNode,Message* pM)

??? {

??????? pNode->MessageFromDown(pM);

??? }

??? static void SendDownMessage(MessageNode* pNode,Message* pM)

??? {

??????? pNode->MessageFromUp(pM);

??? }

private:

??? //轉接來自于SubNode的消息

??? //如果處理了則返回true

??? //否則返回false

??? void MessageFromDown(Message* pM)

??? {

??????? if(m_setMessageUpFilter.find(pM->GetCode()) != m_setMessageUpFilter.end())

??????????? return;

??????? //如果本節點沒有處理

??????? if(!OnUpMessage(pM))

?????????? SendUpMessage(pM);

??? }

??? //轉接來自于Par的消息

??? void MessageFromUp(Message* pM)

??? {

??????? if(m_setMessageDownFilter.find(pM->GetCode()) != m_setMessageDownFilter.end())

??????????? return;

???????

??????? //如果本節點沒有處理消息

??????? //則送子節點繼續處理并返回處理結果

??????? if(!OnDownMessage(pM))

??????????? SendDownMessage(pM);

??? }

protected:

??? //經過此節點的上行消息

??? //返回true表示此節點已經處理消息,消息不上傳

??? //返回false消息向上傳

??? virtual bool OnUpMessage(Message* pM)

??? {

??????? return false;

??? }

??? //經過此節點的下行消息

??? //返回true:消息不再向下傳遞

??? //false:消息繼續傳遞

??? virtual bool OnDownMessage(Message* pM)

??? {

??????? return false;

??? }

private:

??? MessageNode* m_pParent;

??? NodeSet m_setSubNodes;

???

??? //過濾向下經過此點的消息

??? MessageFilterSet m_setMessageDownFilter;

???

??? //過濾向上經過此點的消息

??? MessageFilterSet m_setMessageUpFilter;

};

應用實例:

/*定義消息和節點*/

/*定義一種消息,使用正整形作為消息碼,一棵消息樹上消息碼不能重,一個碼代表一個消息*/

class Message : public CMessage<UINT>{

public:

??? Message(UINT key);

??? virtual ~Message();

};

//

/*定義消息節點,定義了處理消息的類型和消息碼類型*/

class MessageNode : public CMessageNode<Message,UINT>

{

public:

??? MessageNode();

??? virtual ~MessageNode();

};

/*建立消息樹和消息*/

#define MSG_SET_PARA??????? 100

#define MSG_UPDATE_NODE_B?? 101

class Message_Set_Para : public Message

{

public:

Message_Set_Para(int _para):Message(MSG_SET_PARA),para(_para){}

public:

int para;

}

class RootNode : public MessageNode

{

protected:

virtual bool OnUpMessage(Message* pM)

??? {

??????? UINT code = pM->GetCode();

??????? if(MSG_SET_PARA == code)

??????? {

??????????? Message_Set_Para* pPara = dynamic_cast< Message_Set_Para*>(pM);

??????????? /*do somthing*/

??????????? return true;/*true:消息不再傳遞,到此為止,false:消息繼續傳遞*/

??????? }

??????? else if(MSG_UPDATE_NODE_B == code)

??????? {//從節點B發出的更新消息

???????????? /*do somthing*/

???????????? return true;

??????? }

??????? __surper::OnUpMessage(pM);

??? }

??? //經過此節點的下行消息

??? //返回true:消息不再向下傳遞

??? //false:消息繼續傳遞

??? virtual bool OnDownMessage(Message* pM)

??? {

??????? return false;

??? }

}

class Node_A : public MessageNode

{

public:

?void set_para1()

{

Message_Set_Para msg(2);

SendUpMessage(&msg);

}

}

class Node_B : public MessageNode

{

public:

???? void update()

{

???? SendUpMessage(&Message(MSG_UPDATE_NODE_B));

}

}

RootNode root;

Node_A a;

Node_B b;

a.SetParNode(&root);

b.SetParNoe(&root);

b.update();

a.set_para1();

MessageNode::SendUpMessage(&b,Message_Set_Para(5));

如例:消息和消息樹有多重定義方法,有多種變化用法,適用場景極多。

在此例中,不免使用了動態類型轉換等不雅行為,后面內容講到訪問者模式的時候就可以一并處理了。

總結

以上是生活随笔為你收集整理的模式之消息树的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。