2014-10-17 61 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

相關問題