我有一個類需要初始化,然後才能開始工作。但是,我不想在我的對象內創建它,我希望它被注入 - 所以我需要同時具有init()和run()。OOP設計:避免狀態並保持依賴注入
但是,這會產生一個問題 - 對象現在有狀態,我試圖避免它。有沒有克服這種情況的設計模式?
我有一個類需要初始化,然後才能開始工作。但是,我不想在我的對象內創建它,我希望它被注入 - 所以我需要同時具有init()和run()。OOP設計:避免狀態並保持依賴注入
但是,這會產生一個問題 - 對象現在有狀態,我試圖避免它。有沒有克服這種情況的設計模式?
關於依賴注入: 依賴注入只是將邏輯實現傳遞給類的一個奇妙術語。依賴注入的最基本形式是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();
}
}
這是一個很好的解決方案,但它並沒有解決整個問題 - 我想要在類B之外創建類A,然後在構造函數中傳遞給B - 但類A仍然需要在類B中初始化(只有他知道所需的價值)。 – Yossale 2011-03-13 15:56:50
**沒有冒犯,但這是一個非常糟糕的設計。**創建一個不能使用的類,除非另一個類被配置,這有什麼意義?這打破了OOA/OOD的各種最佳實踐規則。一個更好的設計是將類A作爲類B的公共內部類。因此,類B可以控制所有類A實例的實例化和配置。你所描述的是FactoryPattern的另一個用途。如果您需要多個不同的A類實現,則需要有一個通用的接口並且具有B類的所有Implemenations內部類。 – 2011-03-14 04:30:14
在這個例子中,它聽起來像你應該提供你的依賴作爲構造函數的參數。這樣可以增加附加關鍵字final
的安全性,這樣您就可以確保它永遠不會再被設置。
任何面向對象的設計都必須是有狀態的,除非你的類沒有任何全局變量,並且所有局部變量都被聲明爲「最終」。 – 2011-03-13 14:41:53
@Travis這是一個很好的觀點,但我並不是用你描述的基本方式來表達它 - 我的意思是它更像是一個狀態機 - 如果沒有做A,你就無法做B,而且這種做法很難實現 – Yossale 2011-03-13 16:08:44