1. 程式人生 > >Unity如何實現網路通訊(三):觀察者模式以及在網路模組的應用

Unity如何實現網路通訊(三):觀察者模式以及在網路模組的應用

    首先我們來說一下什麼叫觀察者模式。觀察者模式,顧名思義,就是觀察,那麼就會有觀察者和被觀察者,比如在軍隊中,所有的軍人要聽長官的指示,軍人就是觀察者,長官就是被觀察者,長官一聲號令:“向左轉!”,長官所有的監聽者就會執行向左轉的方法,那麼這就是一個觀察者模式的流程,我們只需要通過程式碼來模擬現實生活中的事情,並將之抽象即可。     在我們的程式碼中,如果沒有一個良好的設計模式、框架,就會產生如下現象: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);                     }                 }             }         }     } } 這樣就可以實現對網路中傳入資料的監聽。