2011-03-13 72 views
1

我有一個類需要初始化,然後才能開始工作。但是,我不想在我的對象內創建它,我希望它被注入 - 所以我需要同時具有init()和run()。OOP設計:避免狀態並保持依賴注入

但是,這會產生一個問題 - 對象現在有狀態,我試圖避免它。有沒有克服這種情況的設計模式?

+0

任何面向對象的設計都必須是有狀態的,除非你的類沒有任何全局變量,並且所有局部變量都被聲明爲「最終」。 – 2011-03-13 14:41:53

+0

@Travis這是一個很好的觀點,但我並不是用你描述的基本方式來表達它 - 我的意思是它更像是一個狀態機 - 如果沒有做A,你就無法做B,而且這種做法很難實現 – Yossale 2011-03-13 16:08:44

回答

4

關於依賴注入: 依賴注入只是將邏輯實現傳遞給類的一個奇妙術語。依賴注入的最基本形式是constructor。您只需傳入您不想在類內的任何實例,作爲構造函數的參數。

public interface Logic 
{ 
    public void do(); 
} 

public class MyClass 
{ 
    private final Logic logic; 

    public MyClass(final Logic logic) 
    { 
     this.logic = logic; 
    } 

    public void doLogic() { this.logic.do(); } 
} 

public class MyLogic implements Logic 
{ 
    public void do() { /* custom logic goes here */ } 
} 

public class Main 
{ 
    public static void main(final String[] args) 
    { 
     final MyClass myClass = new MyClass(new MyLogic()); 
     myClass.doLogic(); 
    } 
} 

建築類: 的一個好方法,以確保類完全構造和初始化是FactoryMethod模式。創建一個static MyClass create();方法並使MyClass構造函數private初始化您的類,並確保它在傳出之前有效。

public class MyClass 
{ 
    /** Factory Method, only way to create a MyClass instance */ 
    public static MyClass create() 
    { 
     final MyClass instance = new MyClass(); 
     // initialize class however you need it 
     return instance; 
    } 

    private MyClass() 
    { 
     // normal constructor, if no logic you still need this 
     // to make sure it can only be created by the Factory Method 
     super(); 
    } 
} 
+0

這是一個很好的解決方案,但它並沒有解決整個問題 - 我想要在類B之外創建類A,然後在構造函數中傳遞給B - 但類A仍然需要在類B中初始化(只有他知道所需的價值)。 – Yossale 2011-03-13 15:56:50

+0

**沒有冒犯,但這是一個非常糟糕的設計。**創建一個不能使用的類,除非另一個類被配置,這有什麼意義?這打破了OOA/OOD的各種最佳實踐規則。一個更好的設計是將類A作爲類B的公共內部類。因此,類B可以控制所有類A實例的實例化和配置。你所描述的是FactoryPattern的另一個用途。如果您需要多個不同的A類實現,則需要有一個通用的接口並且具有B類的所有Implemenations內部類。 – 2011-03-14 04:30:14

0

在這個例子中,它聽起來像你應該提供你的依賴作爲構造函數的參數。這樣可以增加附加關鍵字final的安全性,這樣您就可以確保它永遠不會再被設置。