目前,我正在尝试用 Go 实现一款多人回合制卡牌游戏。我有两个包裹:
game
和network
。 game
包实现了游戏逻辑。 Game
对象验证并接受 Action
类型的对象。它返回类型为 Response
的对象。
network
包接受来自 WebSocket 连接的消息并将其转换为 InboundMessage
类型。 InboundMessage
是一个带有方法 Action
的接口,它将 InboundMessage
转换为 Action
发送到游戏。所以 network
包取决于 game
。
但是,我想要与我从游戏中收到的
Response
对象类似的东西。目标是将每个 Response
转换为一个或多个 OutboundMessage
发送给客户端。我不想让 game
依赖于 network
。
game
和network
完全独立的解决方案也可以。
这里只是为了澄清一下我如何将
InboundMessage
转换为 Action
:
type InboundMessage interface {
Action() game.Action
}
type PlayCardMessage struct {
Card game.Card
MessageBase
}
func (m PlayCardMessage) Action() game.Action {
return game.NewPlayCardAction(m.Card, m.Client.player)
}
我想复制这一点,其中
Response
将转换为一个或多个 OutboundMessage
,而无需 game
,具体取决于 network
。
实施这样的事情的最佳方法是什么?我想出的唯一解决方案是打开类型开关
Response
但这并不像多态调用那么优雅。
有几种方法可以做到这一点。一种方法是依赖
network
对 game
的依赖,即在 network
包中,将 Response
转换为 OutboundMessage
。正如您已经观察到的,您可以通过 Response
上的类型开关来完成此操作。
另一种选择是拥有一个
ResponseType
枚举,然后将其公开在 Response
接口(即 Response.ResponseType() 方法)中,然后拥有构造函数映射:
var responseSerializer = map[game.ResponseType]func(Response) OutboundMessage {
...
}
另一种选择是在
Response
中实现序列化方法,并使用 OutboundMessage
作为序列化有效负载周围的简单信封:
outbound:=OutboundMessage {
Payload: response.Serialize(),
}
其中
Payload
是 []byte
。