2015-11-13 80 views
0

我嘗試瞭解Wikipedia上描述的惰性初始化模式。有一個構造函數接受FRUIT_TYPE類型的參數。初始化時,正在檢查哈希映射是否已經有給定的水果類型,如果不是,則使用構造函數創建超出給定類型的水果。水果然後被放入地圖。我複製粘貼示例,它工作正常。但是如何在沒有必要的領域的情況下創建水果,以便將其設置爲構造函數中的給定參數,例如, G。Java:接受參數的空構造函數

private FRUIT_TYPE fruitType; 
private Fruit(FRUIT_TYPE type){this.fruitType = type} 

我在想什麼?

+4

這是一個破碎的例子,因爲你不能真正從任意'Fruit'參考拿到(非常規的名字命名)'FRUIT_TYPE'值。參數和字段是不相關的,因爲沒有任何東西使用它們。它確實展示了懶惰的初始化,但是很糟糕。 –

+0

@JonSkeet在哪裏可以找到一個可靠的例子,因爲它沒有在GOF書中描述? –

+1

那麼你可以很容易地在構造函數中添加賦值,也許可以使用'getFruitType()'的實例方法,此時它會好起來的...... –

回答

0

要回答你的問題,那個例子中的個別Fruit實例不知道它自己的類型。在設計的例子中,它不需要知道,因爲類型既不被檢查也不被使用。

我強烈建議不要遵循該示例。它有多個問題,而不是其中最重要的是缺少類型字段:

  • 即使是高併發版本不是線程安全的(見http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
  • 這是非常做作又難用。這些方針的東西可能更符合典型應用案例:

    class Fruit { 
        private static final AtomicReference<Fruit> banana = new AtomicReference<>(); 
        private FruitType type; 
        private Fruit(FruitType type) {this.type = type; someExpensiveCall(); } 
    
        static Fruit getBanana() { 
        Fruit b = banana.get(); 
        if (b == null) { 
         banana.compareAndSet(null, new Banana()); 
         b = banana.get(); 
        } 
        return b; 
        } 
    } 
    
+0

我的意圖是指出,即使在高併發版本中,示例代碼也不正確,而不是重新激活舊的辯論。 –