2012-12-15 149 views
3

我對Java相當陌生。我來自PHP,我曾經使用magic __get和__set方法在php中創建註冊表類。因此,該系統的其他部分可以輕鬆做到:Java註冊表類?

registry.foo = new Foo(); 

我應該提到我正在嘗試創建遊戲引擎。這是我在Java中ATM註冊表:

class Registry { 

    private static Map<String, Object> box = new HashMap<String, Object>(); 

    public static Object get(String key) { 

     if (Registry.box.get(key) != null) { 
      return Registry.box.get(key); 
     }else { 
      return null; 
     } 
    } 

    public static void set(String key, Object o) { 
     Registry.box.put(key, o); 
    } 

} 

然後對系統訪問註冊表的其他部分,我現在需要這件事:

((Object) Registry.get("Object")).doSomething(); 

這實在是一個很大的代碼。在PHP中,這將通過簡單地完成:

Registry.foo.doSomething(); 

任何方法來使這一點更簡單?我想我可以讓公共領域,但隨後regsitry類需要隱式創建這些領域的新對象的可能性,可能需要添加哪些是未知的註冊表類本身,這是..討厭:P

提前致謝!

回答

1

沒有辦法讓這一點更簡單?

不以任何可行的方式。 Java是一種靜態類型的語言,並且必須事先知道對象的結構。相當於PHP的__get__set的想法與該語言是相反的。

對於它的價值,你的「註冊表」看起來像不好的設計呢。 (不可否認的是,從你展示的小代碼中做出了一些非常瘋狂的假設)。你不應該需要一個看起來不相關的對象的全局存儲庫。您應該考慮某種依賴注入。

基於您的評論,而不是構建你的代碼是這樣的:

class World implements GameSystem { 

    public void update() { 
     Registry.get("game").doSomething(); 
    } 

} 

你應該做的:

class World implements GameSystem { 

    Game game; 
    public World(Game game) { // and other dependencies 
     this.game = game; 
    } 

    public void update() { 
     this.game.doSomething(); 
    } 

} 

的想法是,你的節目的內容真的沒有任何業務知道如何找到其他組件。它還使組件之間的依賴性顯式化,並幫助您避免循環依賴。

+0

嗯。依賴注入?好吧,你有什麼建議我應該做什麼? 我擁有的是運行gameloop等遊戲的主要對象。 它有一個GameSystems的公共場HashMap,它在gameloop中運行每個GameSystems.update()方法。其中一個系統是世界系統,當運行world.update()時,它會運行一個「實體」的散列圖,該實體也具有.update()以及.render()。事情是,一些實體和一些遊戲系統需要向主遊戲課程詢問某些事情。或者有些遊戲系統需要與其他遊戲系統進行通信。 –

+0

@PetterThowsen我將編輯答案以包含您提到的類的示例。這就是說,這是一個臭名昭着的模式,你應該在互聯網上發現它討論的噁心。 Java也有一大堆實現它的框架(Spring,Guice,Meld/CDI)。 – millimoose

3

這是一個雙管齊下的問題:

  1. Java是一種靜態類型語言,並在運行時定義對象不提供在語言的靈活性(你可以使用庫在運行時綜合類,但是,看到#2)
  2. 一個全球註冊的對象擊敗了很多安全裝置的類型安全的語言。如果您的整個應用程序圍繞獲取並將對象放入全局Map中,那麼可能會有更安全且耦合度更低的設計。

這又如何解決呢?

  1. 將您的應用程序結構重新設計爲不需要全局地圖。
  2. 使用Java的動態語言子集(如Groovy)。
  3. 使用Scala 2.10(與JVM兼容),其特徵爲Dynamic類型,它完全符合您的需求。
+1

此外,解決方案1和2/3不是互斥的。不管語言如何,全局服務定位器都不應該用來管理組件依賴。 – millimoose

1

這一切的方法首先是太冗長:

public static Object get(String key) { 
    if (Registry.box.get(key) != null) { 
     return Registry.box.get(key); 
    }else { 
     return null; 
    } 
} 

這可能只是:

public static Object get(String key) { 
    return Registry.box.get(key); 
} 

但第二,這絕對是一個糟糕的設計。全局存儲庫 - 聽起來不合理。通過字符串鍵存儲所有類型的對象 - 這太可怕了。