很多freshman上來就想搞清楚什么是IOC和DI,其實很多先進的理論和技術都在老的基礎上升華出來的,最終目的是為了解放生產力。
所以先來說說下面兩點基礎知識:
- Direct Dependency(直接依賴)
- Inverted Dependency(反向依賴)
Direct Dependency
應用程序中的依賴關系方向應該是抽象的方向,而不是實現詳細信息的方向。 大部分應用程序都是這樣編寫的:編譯時依賴關系順着運行時執行的方向流動,從而生成一個直接依賴項關系圖。 也就是說,如果類 A 調用類 B 的方法,類 B 調用 C 類的方法,則在編譯時,類 A 將取決於類 B,而 B 類又取決於類 C,如圖1所示。
假設一個A通過朋友B和C找超級富婆的故事,A只有B朋友的關系,B只有C朋友的關系,C朋友才能幫忙找到超級富婆!條件是“身體好”!
對應的代碼塊如下:
public class ClassA { /// <summary> /// Find super rich woman /// </summary> /// <returns>return super rich woman</returns> public string FindRichWoman() { var criteria = "身體好"; return new ClassB().FindRichWoman(citeria); } }
public class ClassB { /// <summary> /// Find super rich woman by citeria. /// </summary> /// <returns>return super rich woman</returns> public string FindRichWoman(string criteria) {return new ClassC().FindRichWoman(criteria); } }
public class ClassC { /// <summary> /// Find super rich woman by criteria. /// </summary> /// <returns>return super rich woman</returns> public string FindRichWoman(string criteria) { if (criteria.Equals("身體好")) return "Super Rich Woman"; return string.Empty; } }
編譯時和運行時的依賴關系和控制關系都是A=》B=》C
- 高層次類對底層次類正向依賴 - A要想找到富婆就必須要找到B,B需要去找C
- 高層次類對低層次類的正向控制 - B什么時候要富婆由A來決定,C什么時候去找富婆由B來決定
Inverted Dependency
應用依賴關系反轉原則后,A 可以調用 B 實現的抽象上的方法,讓 A 可以在運行時調用 B,而 B 又在編譯時依賴於 A 控制的接口(因此,典型的編譯時依賴項發生反轉)。 運行時,程序執行的流程保持不變,但接口引入意味着可以輕松插入這些接口的不同實現。
- 依賴關系反轉原則之抽象接口和工廠模式應用 - 上面那段話可以這么理解,A發現找個富婆還要自己親自去找B,還得管B的吃喝拉撒,所以是否可以找機器人中心(工廠模式)幫忙搭線,自己只要找到由B抽象出來的虛擬機器人就可以了
使用工廠模式后,只需要將抽象接口B給到工廠就能找到想要的方法,A不用去關注對象B是怎么產生的。
public class ClassA { /// <summary> /// Find super rich woman /// </summary> /// <returns>return super rich woman</returns> public string FindRichWoman() { var criteria = "身體好"; return factory.CreateInstance(InterfaceB).FindRichWomanByB(criteria); } }
- 接口引入意味着可以輕松插入這些接口的不同實現 如果A突然不想通過B找富婆,假設D也不需要任何條件就可以現實找到富婆,那A肯定很樂意換成通過D,我只需要把InterfaceB換成InterfaceD丟給工廠。
public class ClassD: InterfaceD { /// <summary> /// Find super rich woman /// </summary> /// <returns>return super rich woman</returns> public string FindRichWoman() { return "Super Rich Woman"; } } }
public class ClassA { /// <summary> /// Find super rich woman /// </summary> /// <returns>return super rich woman</returns> public string FindRichWoman() { return factory.CreateInstance(InterfaceD).FindRichWoman();
}
}
發現很多博主在講解IOC時,就將此處的概念就定義為IOC, 其實此處:
- 高層次的類不再正向依賴於低層次的類,兩者都依賴於抽象接口 - 類A和類B依賴了InterfaceB
- 低層次類依賴於高層次類的需求抽象 類A有找富婆的需求,那么低層次抽象出來的InterfaceB和InterfaceD都有實現找富婆的辦法,所以他們就都有依賴於來自高層次類A抽象出來找富婆的需求
最大的優勢就是解耦了高層次模塊對於低層次模塊的緊密依賴,可以靈活擴展!
到了鍛煉身體的時間了,下一節再來說IOC和DI的概念和對應的場景