我最近遇到的问题是我的代码最终需要一个类来存储另一个的实例,而另一个类来存储第一个的实例。 我觉得好像这是一个糟糕的设计,我一直在努力想出一个更好的设计,但我提出的任何一个显然会导致更差的性能。 (要求迭代列表只是为了找到一些东西,否则我不需要。)
例如,我正在研究服务器端系统,我会给你基本的大纲,以便你可以看到我的意思。
说Server类包含World和NetworkHandler的实例。
当客户端连接到服务器时,会通知NetworkHandler,并将该通道存储在Session对象中。 登录后,将创建一个Player实例并将其添加到World。
这是事情变得奇怪的地方。我尝试让Session持有Player的实例,而Player持有Session的实例。这似乎效果最好,但我觉得必须有更好的方法。
至于为什么我需要从两个地方访问它们,NetworkHandler会传递附加到通道的会话,并以这种方式处理数据包。 (这必须能够访问附加到会话的播放器)
但是,有时候,世界需要遍历玩家并访问他们所附加的会话。 (例如断开它们)
感谢您提供任何帮助,如果有任何不明之处,请询问。
答案 0 :(得分:2)
我能想到的一个替代架构是"事件驱动"应该在这种情况下解耦对象。 (当然,它也有其缺点,事件驱动的代码可能非常复杂)。
例如,您可以在队列上放置一个所有会话都可以响应的断开事件,而不是遍历玩家以断开它们。会话可以将事件放在队列中,每个玩家只能收听来自其各个会话的事件。
答案 1 :(得分:1)
如果不了解更多有关您的问题/域的信息,很难提供明确的设计建议,但从您编写的内容来看,您似乎应该将“管道”逻辑(网络和服务器内容)与游戏逻辑分开。
一般的建议是,如果你发现自己陷入了只能想到丑陋和丑陋的解决方案的情况:退后几米并采取更广阔的视野。也许你需要重构多个课程。
也就是说,让两个类相互引用没有根本的错误(尽管通常可以避免)。考虑一下这种情况:
+-----------+ 1 contains * +-----------+
| Box |---------------->| Item |
+-----------+ +-----------+
| | 1 is inside 1 | |
| |<----------------| |
| | | |
+-----------+ +-----------+
如果您不了解UML,请说明:上面的图片将被读作“有框和项目。盒子可以包含任意数量的物品。每件商品都在一个盒子里面。“
您需要这些的示例并不常见,但确实会发生。如果两个类别紧密耦合,这是可以的。如果可能的话,只是不要跨模块边界创建这样的依赖。