2014-10-17 136 views
1

最近我遇到了问题,因为我的代码最终需要一个类来存储另一个类的实例,而另一个类需要存储第一个类的实例。 我感觉好像这是糟糕的设计,而且我一直试图想出更好的设计,但是我提出的任何设计显然都会导致较差的性能。 (需要迭代的列表只是为了找到某些东西,否则我不需要)有没有更好的方法让两个类互相访问?

例如,我正在研究一个服务器端系统,我会给你基本概要以便您可以看到我的意思是。

表示Server类包含World和NetworkHandler的实例。

当客户端连接到服务器时,会通知NetworkHandler并将通道存储在Session对象中。 登录后,会创建一个Player实例并添加到World中。

这里的东西变得奇怪。我尝试让Session持有Player的实例,Player则持有Session的实例。这似乎效果最好,但我觉得应该有更好的方法。

至于为什么我需要他们从两个地方访问,NetworkHandler会传递附加到通道的会话,并以这种方式处理数据包。 (这必须能够访问连接到会话的玩家)

但是,有时,世界需要遍历玩家并访问他们所连接的会话。 (如断开它们)

谢谢你的任何帮助,如果有什么不清楚的地方问。

回答

1

如果不知道更多关于问题/领域的信息,很难给出明确的设计建议,但从您所写的内容看来,您应该将“管道”逻辑(网络和服务器内容)与游戏逻辑分开。

一般的建议是,如果你发现自己陷入了一种只能想到丑陋和丑陋的解决方案的情况:退一步几米,展开一下。也许你需要重构一个以上的类。

也就是说,让两个类互相引用(虽然经常可以避免)并没有什么根本性的错误。例如,考虑这种情况:

+-----------+ 1 contains * +-----------+ 
| Box |---------------->| Item | 
+-----------+     +-----------+ 
|   | 1 is inside 1 |   | 
|   |<----------------|   | 
|   |     |   | 
+-----------+     +-----------+ 

解释,如果你不知道UML:以上图片将被解读为“有项目。一个盒子可以包含任意数量的项目。每个项目都在一个方框内。“

您需要的例子并不常见,但它们确实发生。如果这两个班级紧密结合,这没关系。如果所有可能的话,不要在模块边界上创建这种依赖关系。

+1

感谢您的回复。我认为,如果我不使用像Netty这样的异步网络库,它会不那么令人困惑。 为了给你一个我处理网络的方式背景,我构建了一个基于解码器的系统。每个会话都有一个解码器的实例,并且针对不同的状态有不同的解码器。 (登录,播放等)。 我不知道我该如何拆分它,所以现在我会离开这两个类,并希望我可以考虑更好的设计,因为我重构了系统的其他部分。 – grundyboy34 2014-10-17 02:02:56

+0

我想我只是想出了如何将其设计成更好的系统。如上所述,每个会话可以更改为不同的解码器。当解码器进入处理世界逻辑的WorldDecoder时,我需要Couple Player和Session时遇到的问题。所以我所能做的就是保持一切,但同样给世界自己的NetworkHandler,并且会话内的会话将被迫使用WorldDecoder。这也将提供托管多个世界的能力,并在需要时使用服务器作为主要集线器。 – grundyboy34 2014-10-17 02:21:31

2

我能想到的一种替代体系结构是“事件驱动”,它应该解耦这种情况下的对象。 (当然,它也有其不足之处,事件驱动代码可能非常复杂)。例如,您可以在所有会话可以响应的队列中放置一个断开连接事件,而不是迭代玩家来断开连接。会话可以将事件放在队列中,每个玩家只能听取其个别会话中的事件。

+0

谢谢你的回复。我研究过甚至是驱动编码,我不确定这是否适合这个项目。 – grundyboy34 2014-10-17 02:32:35

相关问题