1. 程式人生 > >IOC和DI本質理解

IOC和DI本質理解

IoC

IoC: Inversion of Control,控制反轉, 控制權從應用程式轉移到框架(如IoC容器),是框架共有特性 1、為什麼需要IoC容器 1.1、應用程式主動控制物件的例項化及依賴裝配  Java程式碼  收藏程式碼
  1. A a = new AImpl();  
  2. B b = new BImpl();  
  3. a.setB(b);  
本質:建立物件,主動例項化,直接獲取依賴,主動裝配  缺點:更換實現需要重新編譯原始碼            很難更換實現、難於測試            耦合例項生產者和例項消費者  Java程式碼  收藏程式碼
  1. A a = AFactory.createA();  
  2. B b = BFactory.createB();  
  3. a.setB(b);  
本質:建立物件,被動例項化,間接獲取依賴,主動裝配  (簡單工廠)  缺點:更換實現需要重新編譯原始碼            很難更換實現、難於測試 Java程式碼  收藏程式碼
  1. A a = Factory.create(“a”);  
  2. B b = Factory.create(“b”);  
  3. a.setB(b);   
  <!—配置.properties--> Xml程式碼  收藏程式碼
  1. a=AImpl  
  2. b=BImpl  
  本質:建立物件,被動例項化,間接獲取依賴, 主動裝配         (工廠+反射+properties配置檔案、            Service Locator、登錄檔)  缺點:冗餘的依賴裝配邏輯 我想直接:     //返回裝配好的a Java程式碼  收藏程式碼
  1. A a = Factory.create(“a”);   
1.2、可配置通用工廠:工廠主動控制,應用程式被動接受,控制權從應用程式轉移到工廠 Java程式碼  收藏程式碼
  1. //返回裝配好的a   
  2. A a = Factory.create(“a”);  
   <!—配置檔案--> Java程式碼  收藏程式碼
  1. <bean id=“a” class=“AImpl”>  
  2.     <property name=“b” ref=“b”/>  
  3. </bean>  
  4. <bean id=“b” class=“BImpl”/>  
 本質:建立物件和裝配物件,            被動例項化,被動接受依賴,被動裝配         (工廠+反射+xml配置檔案) 缺點:不通用 步驟: 1、讀取配置檔案根據配置檔案通過反射 建立AImpl 2、發現A需要一個型別為B的屬性b 3、到工廠中找名為b的物件,發現沒有,讀取 配置檔案通過反射建立BImpl 4、將b物件裝配到a物件的b屬性上 【元件的配置與使用分離開(解耦、更改實現無需修改原始碼、易於更好實現) 】 1.3、 IoC(控制反轉)容器:容器主動控制
Java程式碼  收藏程式碼
  1. //返回裝配好的a   
  2. A a = ApplicationContext.getBean(“a”);  
 <!—配置檔案--> Java程式碼  收藏程式碼
  1. <bean id=“a” class=“AImpl”>  
  2.     <property name=“b” ref=“b”/>  
  3. </bean>  
  4. <bean id=“b” class=“BImpl”/>  
  本質:建立物件和裝配物件、管理物件生命週期           被動例項化,被動接受依賴,被動裝配         (工廠+反射+xml配置檔案) 通用 

  IoC容器:實現了IoC思想的容器就是IoC容器 2、IoC容器特點 【1】無需主動new物件;而是描述物件應該如何被建立即可          IoC容器幫你建立,即被動例項化; 【2】不需要主動裝配物件之間的依賴關係,而是描述需要哪個服務(元件),         IoC容器會幫你裝配(即負責將它們關聯在一起),被動接受裝配; 【3】主動變被動,好萊塢法則:別打電話給我們,我們會打給你; 【4】迪米特法則(最少知識原則):不知道依賴的具體實現,只知道需要提供某類服務的物件(面向抽象程式設計),鬆散耦合,一個物件應當對其他物件有儘可能少的瞭解,不和陌生人(實現)說話 【5】IoC是一種讓服務消費者不直接依賴於服務提供者的元件設計方式,是一種減少類與類之間依賴的設計原則。 3、理解IoC容器問題關鍵:控制的哪些方面被反轉了? 1、誰控制誰?為什麼叫反轉? ------ IoC容器控制,而以前是應用程式控制,所以叫反轉  2、控制什麼?               ------ 控制應用程式所需要的資源(物件、檔案…… 3、為什麼控制?             ------ 解耦元件之間的關係  4、控制的哪些方面被反轉了? ------ 程式的控制權發生了反轉:從應用程式轉移到了IoC容器。  思考:     1: IoC/DI等同於工廠嗎?     2: IoC/DI跟以前的方式有什麼不一樣? 領會:主從換位的思想
  4、實現了IoC思想的容器就是輕量級容器嗎? 如果僅僅因為使用了控制反轉就認為這些輕量級容器與眾不同,就好象在說我的轎車與眾不同因為它有四個輪子?  容器:提供元件執行環境,管理元件宣告週期(不管元件如何建立的以及元件之間關係如何裝配的); IoC容器不僅僅具有容器的功能,而且還具有一些其他特性---如依賴裝配 控制反轉概念太廣泛,讓人迷惑,後來Martin Fowler 提出依賴注入概念 Martin Fowler  Inversion of Control Containers and the Dependency Injection pattern   http://martinfowler.com/articles/injection.html DI 2、什麼是DI DI:依賴注入(Dependency Injection) :用一個單獨的物件(裝配器)來裝配物件之間的依賴關係 。

2、理解DI問題關鍵 誰依賴於誰?           -------   應用程式依賴於IoC容器 為什麼需要依賴?        -------   應用程式依賴於IoC容器裝配類之間的關係 依賴什麼東西?          -------   依賴了IoC容器的裝配功能 誰注入於誰?            -------   IoC容器注入應用程式 注入什麼東西?          -------   注入應用程式需要的資源(類之間的關係) 更能描述容器其特點的名字——“依賴注入”(Dependency Injection) IoC容器應該具有依賴注入功能,因此也可以叫DI容器  3、DI優點     【1】幫你看清元件之間的依賴關係,只需要觀察依賴注入的機制(setter/構造器),就可以掌握整個依賴(類與類之間的關係)。     【2】元件之間的依賴關係由容器在執行期決定,形象的來說,即由容器動態的將某種依賴關係注入到元件之中。     【3】依賴注入的目標並非為軟體系統帶來更多的功能,而是為了提升元件重用的概率,併為系統搭建一個靈活、可擴充套件的平臺。通過依賴注入機制,我們只需要通過簡單的配置,而無需任何程式碼就可指定目標需要的資源,完成自身的業務邏輯,而不用關心具體的資源來自何處、由誰實現。 使用DI限制:元件和裝配器(IoC容器)之間不會有依賴關係,因此元件無法從裝配器那裡獲得更多服務,只能獲得配置資訊中所提供的那些。  4、實現方式    1、構造器注入    2、setter注入    3、介面注入:在介面中定義需要注入的資訊,並通過介面完成注入        @Autowired        public void prepare(MovieCatalog movieCatalog,            CustomerPreferenceDao customerPreferenceDao) {            this.movieCatalog = movieCatalog;            this.customerPreferenceDao = customerPreferenceDao;        } 使用IoC/DI容器開發需要改變的思路 1、應用程式不主動建立物件,但要描述建立它們的方式。 2、在應用程式程式碼中不直接進行服務的裝配,但要配置檔案中描述哪一個元件需要哪一項服務。容器負責將這些裝配在一起。 其原理是基於OO設計原則的The Hollywood Principle:Don‘t call us, we’ll call you(別找我,我會來找你的)。也就是說,所有的元件都是被動的(Passive),所有的元件初始化和裝配都由容器負責。元件處在一個容器當中,由容器負責管理。 IoC容器功能:例項化、初始化元件、裝配元件依賴關係、負責元件生命週期管理。 本質:       IoC:控制權的轉移,由應用程式轉移到框架;       IoC/DI容器:由應用程式主動例項化物件變被動等待物件(被動例項化);       DI:  由專門的裝配器裝配元件之間的關係;       IoC/DI容器:由應用程式主動裝配物件的依賴變應用程式被動接受依賴