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

~祖克伯發表於2021-10-28

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

相關文章