很多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也可以現實找到富婆,那麼只需要將介面D扔給工廠,條件還是隻要身體好,他就能給你找到富婆!
public class ClassD: InterfaceD { /// <summary> /// Find super rich woman by criteria. /// </summary> /// <returns>return super rich woman</returns> public string FindRichWomanByAnotheWay(string criteria) { if (criteria.Equals("身體好")) return "Super Rich Woman"; return string.Empty; } } }
public class ClassA { /// <summary> /// Find super rich woman /// </summary> /// <returns>return super rich woman</returns> public string FindRichWoman() { var criteria = "身體好"; return factory.CreateInstance(InterfaceD).FindRichWomanByAnotheWay(criteria);
}
}
發現很多博主在講解IOC時,就將此處的概念就定義為IOC, 其實此處:
- 高層次的類不再正向依賴於低層次的類,兩者都依賴於抽象介面 - 類A依賴了InterfaceA和InterfaceD
- 低層次類依賴於高層次類的需求抽象 類A有通過B和通過C來富婆的兩種需求,這種需求抽象出來就是通過誰來富婆,那麼低層次的類B和類D都依賴於這個來自高層次類抽象出來的需求
最大的優勢就是解耦了高層次模組對於低層次模組的緊密依賴,可以靈活擴充套件!
到了鍛鍊身體的時間了,下一節再來說IOC和DI的概念和對應的場景