IOC和DI之刨根問底 -- 第一節


很多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的概念和對應的場景


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM