2016-04-21 62 views
0

我正在寫一個遊戲服務器。採取多態性方法?

我有一個類叫NetMessage。該類用作通過網絡發送的字節數組之間的中間值。

當服務器接收到字節數組時,它將其更改回NetMessage並列出這些列表,並將其交給經理。

NetMessage是一個抽象類,因此所有的消息都來自它,但是當數據到達GameManager時,它可能必須對所獲得的數據做大不相同的事情。

例如,NetMoveMessage需要與NetConnectMessage的處理方式不同。

此外,消息本身除了序列化自身之外沒有任何方法,本身也不能改變狀態。只有經理可以,所以他們基本上只是數據類。

現在決定如何處理數據,我只是簡單地檢查它是什麼類型的消息。例如

  NetMessage message = IncomingMessages.First.Value; 
      IncomingMessages.RemoveFirst(); 

      if(message is NetConnectMessage) 
      { 
       //cool things here 
      } 
      else if(message is NetMoveMessage) 
      { 
       //Isn't this exciting? 
      } 

這是不好的做法?有一個更好的方法嗎?對我來說,考慮到消息沒有做任何事情似乎很好,所以讀取數據的唯一方法是確定需要閱讀的數據,並相應地處理它。如果有一些明顯的更好的方法,我很想念,但隨時啓發我。

回答

1

你可以使用,這將是更快的大量元素,但只慢一些,由於它的開銷

Dictionary<Type, Action<NetMessage>> messageHandlers = new Dictionary<Type, Action<NetMessage>>(); 

void RegisterHandler(Type type, Action<NetMessage> handler) 
{ 
    messageHandlers.Add(type, handler); 
} 

void MessageReceived(NetMessage message) 
{ 
    messageHandlers[message.GetType()].Invoke(message); 
} 

然後,您可以註冊使用

RegisterHandler(typeof(NetMessageSubClass), delegate(NetMessage message) 
{ 
    //NetMessageSubclass related stuff 
}); 

有事件解釋也可能是一個使用泛型的更方便的解決方案,但目前我想不起來。


編輯這裏的通用方法

void RegisterHandler<T>(Action<T> handler) where T : NetMessage 
{ 
    messageHandlers.Add(
     typeof(T), 
     (NetMessage message) => handler.Invoke((T)message) 
    ); 
} 
1

是的,當然有更好的方法來做到這一點。這是一個多態使用的完美例子。

在抽象基類中聲明的虛擬方法(NetMessage):

//sidenote, the method 
public virtual void DoCoolStuff(){} 

而在你的派生類(NetConnectMessageNetMoveMessage覆蓋的方法做任何它需要該類在做特定。

public override void DoCoolStuff(){ 
    //make it do cool stuff :D 
} 

並且代替許多如果的和別人的,你現在可以叫它像這樣:

NetMessage message = IncomingMessages.First.Value; 
IncomingMessages.RemoveFirst(); 
message.DoCoolStuff(); 

這正是多態性是如何工作的:它會在運行時確定什麼類型的信息郵件的實際是,並相應地調用適當的方法。

+0

的東西是消息不會做任何事情。所有的消息都包含數據,說明某件事想做什麼。例如,移動消息實際上不能移動任何東西,因爲它沒有像玩家那樣的信息來做類似的事情。服務器實際上是模擬這些事情,然後根據這些事件寫出新消息發送出去。 –

+0

啊,好吧。然後我不明白需要有消息類。 那麼,無論你決定使用什麼方法,它會回到if/else的某處(或者編寫一個具有相同名稱的方法,重載它們以接收每種類型消息的不同參數)。 – Vucko