IoC/DI

From:http://jinnianshilongnian.iteye.com/blog/1471944

我對IoC/DI的理解

博客分類:
IoC DI 

 


IoChtml

 

IoC   Inversion of Control ,控制反轉,  控制權從應用程序轉移到框架(如 IoC 容器),是框架共有特性
 

 

一、爲何須要IoC容器
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.二、可配置通用工廠: 工廠主動控制,應用程序被動接受,控制權從應用程序轉移到工廠
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配置文件)
缺點:不通用
 
步驟:
一、讀取配置文件根據配置文件經過反射
建立AImpl
二、發現A須要一個類型爲B的屬性b
三、到工廠中找名爲b的對象,發現沒有,讀取
配置文件經過反射建立BImpl
四、將b對象裝配到a對象的b屬性上
【組件的配置與使用分離開(解耦、更改實現無需修改源代碼、易於更好實現) 】
 
1.三、 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 容器
 
二、IoC 容器特色
1 無需主動new對象;而是描述對象應該如何被建立便可
          IoC 容器幫你建立,即被動實例化;
【2】不須要主動裝配對象之間的依賴關係,而是描述須要哪一個服務(組件),
         IoC 容器會幫你裝配(即負責將它們關聯在一塊兒),被動接受裝配;
【3】主動變被動,好萊塢法則:別打電話給咱們,咱們會打給你;
【4】迪米特法則(最少知識原則):不知道依賴的具體實現,只知道須要提供某類服務的對象(面向抽象編程),鬆散耦合,一個對象應當對其餘對象有儘量少的瞭解,不和陌生人(實現)說話
【5】IoC是一種讓服務消費者不直接依賴於服務提供者的組件設計方式,是一種減小類與類之間依賴的設計原則。
 
三、理解 IoC 容器問題關鍵:控制的哪些方面被反轉了?
一、誰控制誰?爲何叫反轉? ------  IoC 容器控制,而之前是應用程序控制,因此叫反轉 
二、控制什麼?               ------  控制應用程序所須要的資源(對象、文件 ……
三、爲何控制?             ------  解耦組件之間的關係 
四、控制的哪些方面被反轉了? ------  程序的控制權發生了反轉:從應用程序轉移到了 IoC 容器。 
 
思考:
    1: IoC/DI等同於工廠嗎?
    2: IoC/DI跟之前的方式有什麼不同?
領會: 主從換位的思想

 
 
四、實現了 IoC 思想的 容器 就是輕量級容器嗎
若是僅僅由於使用了控制反轉就認爲這些輕量級容器不同凡響,就好象在說個人轎車不同凡響由於它有四個輪子? 
 
容器:提供組件運行環境,管理組件聲明週期(無論組件如何建立的以及組件之間關係如何裝配的);
 
IoC容器不只僅具備容器的功能,並且還具備一些其餘特性---如依賴裝配
             
控制反轉概念太普遍,讓人迷惑,後來 Martin  Fowler 提出依賴注入概念
Martin  Fowler  Inversion of Control Containers and the Dependency Injection pattern  
http://martinfowler.com/articles/injection.html
 
 
DI
 
二、什麼是DI
 
DI :依賴注入( Dependency Injection   :用一個單獨的對象(裝配器)來 裝配對象之間的依賴關係  


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

關於IoC/DI與DIP之間的關係 詳見 http://www.iteye.com/topic/1122310?page=5#2335746spring

 

IoC/DI與迪米特法則 詳見http://www.iteye.com/topic/1122310?page=5#2335748編程

本站公眾號
   歡迎關注本站公眾號,獲取更多信息