2012-09-19 33 views
9

我是一個網絡開發者(遊戲開發者爲愛好),並且我看到我自己多次使用以下範例。 (無論是在開發服務器架構還是開發視頻遊戲方面)。它看起來非常難看,但我不知道解決方法。我將在遊戲開發中舉一個例子,因爲這是我最近注意到的。這是我一直在努力的RPG遊戲。每次戰鬥開始時,CombatEngine都會創建兩方戰鬥人員。每次戰鬥建立一個與給定的戰鬥,這是負責支配玩家移動的這沒有收到明確的命令相關的ArtificialIntelligence對象:古怪的參考在課堂建設中傳遞

public class Combatant { 

    ArtificialIntelligence ai = null; 

    public Combatant() 
    { 
     // Set other fields here. 

     this.ai = new ArtificialIntelligence(this); 
    } 

} 

這裏就是我不喜歡:內場(ArtificialIntelligence)在施工期間需要一名戰鬥員,因爲它需要一些Combatant字段來指示適當的行動。所以,爲了方便起見,我保留對作爲參數傳入ArtificialIntelligence對象的戰鬥員的引用,但該對象包含對ai對象本身的引用!它創造了這個奇怪的遞歸,但我不知道如何解決它。 AI對象需要很多特定於戰鬥員的字段,這就是爲什麼我傳入整個對象的原因,但我不喜歡該對象如何包含對上層戰鬥員中包含的ai字段的引用字段,它包含在上面的ai類中。這是不好的做法,還是我只是在想它?

+6

您是否遇到了stackoverflow錯誤?我對此表示懷疑,如果沒有,那麼這裏就不會有遞歸,只是引用傳遞。我認爲你在這裏沒有問題。 –

+1

Woops,我是一個貿易數學家,所以我的一些術語缺乏。你是對的,這只是參考傳遞。這仍然被認爲是一個非問題?在這種形式下嵌套參考不是不好的做法嗎?並回答你的問題,我沒有得到任何錯誤。我只是覺得它看起來很糟糕,並且想要得到意見。 – Sal

回答

9

雖然沒有「設計」這裏的問題 - 它只是你傳遞一個參考 - 一個重要的考慮因素是,你應該所有領域之前的初始化路過this其他類。否則,其他班級將可能訪問this處於可能不一致的狀態。這有時被稱爲讓this從構造函數中「逃脫」。

別這樣......

public class BadCombatant { 

    ArtificialIntelligence ai = null; 
    String someField; 

    public BadCombatant() { 
     this.ai = new ArtificialIntelligence(this); 
     // Don't do this - ArtificialIntelligence constructor saw someField as null 
     someField = "something"; 
    } 
+1

+1某些IDE會警告構造函數中的「泄漏這個」。 –

+1

好了,「ArtificialIntelligence」的構造函數*(及其調用的任何方法)都會將'someField'看作'null'。 –

+1

我不認爲這是一個好主意,以保持這種循環依賴。看到我的答案!當這個依賴可以被移動到兩個類中的一個或者一個全新的類時,兩個類不需要部分相互依賴。 – CKing

4

我肯定會避免循環依賴。對救援來說是單一責任原則。通過讓人工智能對戰鬥員進行操作,您可以消除參照戰鬥中的人工智能的需求。相反,將取決於ArtificialIntelligence的Combatant中的所有代碼移至ArtificialIntelligence。 CombatEngine將執行以下操作:

  1. 創建與Artificialntelligence無關的獨立戰鬥員實例。

  2. 創建人工智能的相應實例並將其傳遞給之前創建的戰鬥人員。

或者,您可以創建一個名爲CombatController的新類,該類傳遞Combatant和ArtificialIntelligence。該CombatEngine將做到以下幾點:

  1. 創建作戰,沒有依賴任何其他類

  2. 上的任何其他類,創建無依賴性的Artificialntelligence

  3. 創建CombatController並把它傳遞Combatant和ArtificialIntelligence對象使用。 CombatController應該公開用於控制Combatant的方法以及處理AI行爲。

無論您使用哪種上述方法,您都可以消除打擾您的循環依賴關係。

很抱歉,我無法提供代碼示例,因爲我從手機輸入此答案並且格式化是一種痛苦。

+0

+1當然有更多選擇;你可以例如從Combatant中將人工智能需要的區域提取到新類,比如CombatantState。 CombatantState是Combatant中的一個領域,ArtificialIntelligence可以接受CombatantState。最好的解決方案取決於你的代碼的需要。 – sleske

+0

我完全同意。只有當你掌握整個圖景而不僅僅是問題的一部分時,才能清楚使用哪種方法。無論哪種方式,循環依賴都可以輕鬆避免! – CKing