我和依賴注入的概念真的很困惑。
我對軟件領域非常陌生,對以下情況有疑問。假設我需要一個Json
解析器類用於我的java代碼,所以我在使用classpath
參數執行java程序時添加了Json
jar。我的程序依賴於Json
jar,所以這意味着我正在做一個依賴注入這裏?
的另一示例將是使用import
語句也解決用戶類的問題是取決於其它類(如在java的Date
),因此,所有這些都是依賴注入的概念?
我在做什麼概念。
在此先感謝。
我和依賴注入的概念真的很困惑。
我對軟件領域非常陌生,對以下情況有疑問。假設我需要一個Json
解析器類用於我的java代碼,所以我在使用classpath
參數執行java程序時添加了Json
jar。我的程序依賴於Json
jar,所以這意味着我正在做一個依賴注入這裏?
的另一示例將是使用import
語句也解決用戶類的問題是取決於其它類(如在java的Date
),因此,所有這些都是依賴注入的概念?
我在做什麼概念。
在此先感謝。
這與您如何將組件鏈接在一起有很大關係。例如在上面,我希望你將解析器注入需要它的類中。例如
相反的:
public class MyParserUsingClass {
...
public MyParserUsingClass() {
this.parser = new Parser();
}
}
你會怎麼做:
public class MyParserUsingClass {
...
public MyParserUsingClass(Parser injectedParser) {
this.parser = injectedParser;
}
}
爲什麼這樣做?使用解析器的類並不關心解析器來自哪裏,而應該真正使用接口而不是具體實例。通過注入解析器,您可以根據具體情況提供不同的實例,模擬它進行測試等。否則,該類只會在內部創建它,並且您無法控制它。這是可配置的組件,跨網絡通話組件,重量級組件等
+1爲'爲什麼這樣?'的解釋。謝謝! – sriram
依賴注入更多的是減少一個類必須創建它自己所依賴的事件的實例。
依賴注入旨在通過某種外部機制將這些依賴關係「提供」給消費類。常用的方法包括通過構造函數傳遞依賴關係,或者將它們設置爲類的公共「可設置」屬性。
例如,通過構造函數依賴注入可能是這個樣子:
public class Parser
{
private IJsonParser parser;
public Parser(IJsonParser parser) {
this.parser = parser;
}
}
它不需要解析器類做這樣的事情:
public class Parser
{
private IJsonParser parser;
public Parser() {
this.parser = new JsonParser();
}
}
這從如下單一職責原則 - Parser類不需要負責創建JsonParser,也不需要關心它使用的是什麼特定的JsonParser - 它的關注僅僅是它需要執行IJsonParser接口指定的工作ace,並將其留給一些更高的控制代碼來確定最適合做這項工作的適當的具體類型。
在你的具體的例子特別關鍵,依賴注入會是什麼樣子:
public class MyParser {
private final JsonParser parser;
public MyParser(JsonParser parser) {
this.parser = parser;
}
public Result parse(JsonInput input) {
Result = parser.parse(input);
}
}
假設JsonParser
是一個接口,可以現在提供的接口來MyParser
任何實現不依賴於你選擇要使用的具體實施。
假設你有一個類澤斯的工作稱爲MyCustomParser
。 現在要允許注入分析器在類來獲取對你將注資(json的可以改變,你想用另一種方式來解析等)的解析器的類型不同的行爲。 所以你應該創建一個Interface
- IParser
用一個方法調用(通過實例)ParseIt
現在你可以有不同的實現方法,這取決於你想要如何解析。 所有你需要做的就是這個接口傳遞給將使用它MyCustomParser
類(你可以做到這一點把它當作參數構造函數)。 在這種情況下,您正在注入解析器MyCustomParser
類
嚴格意義上,依賴注入與導入類或將jar文件添加到類路徑無關。它旨在支持編程接口原理,它是控制反轉的一種形式。
它帶來的主要好處是你的代碼不依賴於顯式依賴項的實現,但它使用的抽象來代替。你依賴於一個接口,並且該接口的一個實現類的某個實例將在運行時被注入到你的類中(作爲構造器參數,一些設置器,或者 - 在我看來 - 實例字段中是不好的選擇)。因此,您可以例如更改持久層而不觸及服務組件中的代碼,因爲您的服務類只關心一些DAO/Repository接口,並且您將在後臺爲它們提供不同的實現。
這不是依賴注入的。 Google IoC(控制反轉)以獲得更好的感覺。 – Marthin
不,這些都不是依賴注入;這些只是依賴關係。查看「控制反轉」以閱讀主題。 – dasblinkenlight
@assylias:我不這麼認爲。我和其他人混淆了DI概念。而我並沒有問它實際是什麼。 – sriram