Unity如何實現網路通訊(三):觀察者模式以及在網路模組的應用
阿新 • • 發佈:2019-01-08
首先我們來說一下什麼叫觀察者模式。觀察者模式,顧名思義,就是觀察,那麼就會有觀察者和被觀察者,比如在軍隊中,所有的軍人要聽長官的指示,軍人就是觀察者,長官就是被觀察者,長官一聲號令:“向左轉!”,長官所有的監聽者就會執行向左轉的方法,那麼這就是一個觀察者模式的流程,我們只需要通過程式碼來模擬現實生活中的事情,並將之抽象即可。
在我們的程式碼中,如果沒有一個良好的設計模式、框架,就會產生如下現象:A做飯比較忙讓B去買一包鹽,但B說沒有錢,於是C又給B拿錢,B拿到錢後,又說沒有交通工具,於是D拿著B的錢坐著自己的交通工具去買鹽了,這樣,鹽終於買回來了,A才把飯做完了。在這裡我們會發現執行效率很差,因為B聽A的,C、D聽B的,如果讓BCD同時聽A的號令,A說買鹽了,B主動要錢,C提前準備好錢,D準備好交通工具拿錢走人,這樣就起到了非常好的效果。
於是,我們在程式碼中就有了觀察者和被觀察者,而為了處理之間的觀察關係,我們又抽象出了一個管理觀察關係的類,也是實現觀察者模式的核心。
public
List<Action>
handlerList =
new
List<Action>();
public
void Dispatch()
{
foreach
(Action
item
in
handlerList)
{
item();
}
}
以上是簡易版程式碼,當被觀察者做出了指示,就會呼叫派發方法。而所有觀察者都被存在列表中,當派發方法執行,觀察者就會執行各自對應的方法。
那麼如果被觀察者做出不同的指示,就會有不同的觀察者,比如長官指示第一列隊向左轉,第二列隊是絕對不能動的,所以我們需要給被觀察者的指示進行分類,我們原來使用的是List來儲存所有的觀察者,觀察的是同一個指示,那麼如果我們有多個指示,該怎麼做呢。
很明顯,我們就需要引入字典Dictionary<指示型別,所有的監聽者>;
當被觀察者做出指示時,需要宣告指示的型別,然後從字典中取出對應的監聽者,來執行對應的方法。我們會發現,此時我們的需要正好和SOCKET中對於不同協議資料的處理所提出的要求不謀而合。
那麼我們就來看看如何在SOCKET中使用觀察者模式,以下給出了核心程式碼:
using System.Collections;
using System.Collections.Generic;
public delegate void OnActionHander(byte[] buffer);
public class EventDispatcher : SingleTon<EventDispatcher> {
private Dictionary<ushort, List<OnActionHander>> dic = new Dictionary<ushort, List<OnActionHander>>();
/// 新增監聽
public void AddEventListener(ushort protoCode,OnActionHander handler)
{
if (dic.ContainsKey(protoCode))
{
dic[protoCode].Add(handler);
}
else
{
List<OnActionHander> lstHandler = new List<OnActionHander>();
lstHandler.Add(handler);
dic[protoCode] = lstHandler;
}
}
/// 移除事件
public void RemoveEventListener(ushort protoCode,OnActionHander handler)
{
List<OnActionHander> lstHandler=dic[protoCode];
lstHandler.Remove(handler);
if (lstHandler.Count == 0)
{
dic.Remove(protoCode);
}
}
/// 派發協議
public void Dispatch(ushort protoCode,byte[] buffer)
{
if (dic.ContainsKey(protoCode))
{
List<OnActionHander> lstHandler=dic[protoCode];
if (lstHandler != null && lstHandler.Count > 0)
{
for (int i = 0; i < lstHandler.Count; i++)
{
if (lstHandler[i] != null)
{
lstHandler[i](buffer);
}
}
}
}
}
}
這樣就可以實現對網路中傳入資料的監聽。