我正在写一个游戏服务器。
我有一个名为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?
}
这是不好的做法吗?有一个更好的方法吗?考虑到消息没有做任何事情,对我来说似乎很好,因此读取数据的唯一方法是确定需要读取的数据是什么并相应地处理它。如果有一些明显更好的方法,我会失踪,但请随时启发我。
答案 0 :(得分:1)
是的,肯定有更好的方法可以做到这一点。这是多态性使用的完美示例。
在基础抽象类(NetMessage
)中声明虚方法:
//sidenote, the method
public virtual void DoCoolStuff(){}
在您的派生类(NetConnectMessage
和NetMoveMessage
)覆盖方法中,特别是为该类做必要的事情。
public override void DoCoolStuff(){
//make it do cool stuff :D
}
而不是许多if和else,你现在可以这样称呼它:
NetMessage message = IncomingMessages.First.Value;
IncomingMessages.RemoveFirst();
message.DoCoolStuff();
这正是多态性的工作原理:它将在运行时确定您的消息实际上是什么类型的消息,并相应地调用相应的方法。
答案 1 :(得分: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)
);
}