1. 程式人生 > >控制反轉IOC的依賴注入方式 【調侃】IOC前世今生 IoC模式 談談對Spring IOC的理解 一個簡單的小程式演示Unity的三種依賴注入方式 小菜學習設計模式(五)—控制反轉(Ioc) IoC模式(依賴、依賴倒置、依賴注入、控制反轉) IoC模式

控制反轉IOC的依賴注入方式 【調侃】IOC前世今生 IoC模式 談談對Spring IOC的理解 一個簡單的小程式演示Unity的三種依賴注入方式 小菜學習設計模式(五)—控制反轉(Ioc) IoC模式(依賴、依賴倒置、依賴注入、控制反轉) IoC模式

轉自:https://www.cnblogs.com/ysyn/p/5563256.html

引言:

   專案中遇到關於IOC的一些內容,因為和正常的邏輯程式碼比較起來,IOC有點反常。因此本文記錄IOC的一些基礎知識,並附有相應的簡單例項,而在實際專案中再複雜的應用也只是在基本應用的基礎上擴充套件而來的。本文目的兩個,一是記錄學習過程,以便將來溫故;二是請大牛對小弟指點一二。

 

概念:

  控制反轉(Inversion of Control,英文縮寫為IoC)是一個重要的面向物件的法則來削減計算機程式的耦合問題,也是輕量級的Spring框架的核心。 控制反轉一般分為兩種型別,依賴注入(Dependency Injection,簡稱DI)和依賴查詢(Dependency Lookup)。依賴注入應用比較廣泛。-百度百科。

 

簡單例項:

下面編寫使用IOC實現的簡單例項,以便大家對IOC有個初始的概念。功能是輸入字串格式的日誌,程式碼如下:

介面ILogger和具體的Logger類:

  View Code

常規的呼叫方式:

ILogger logger = new Logger();
logger.Log("good");

 

使用IOC模式的客戶端調取方式:

新增using Microsoft.Practices.Unity;

IUnityContainer container = new UnityContainer();
container.RegisterType<ILogger, Logger>();
ILogger logger = container.Resolve<ILogger>();
logger.Log("good");

結果如下:

 

介紹常用的概念:依賴、依賴倒置、控制反轉、依賴注入。

日常編碼過程中,新建一個類,進而new物件進而進行相關的業務邏輯,例如下面例項,使用者播放媒體檔案:

  View Code

 

從上文可以看出程式碼的耦合度太高了,如果有新的需求,需要改動的地方太多了,那麼使用依賴倒置原則來降低耦合度。

依賴倒置原則:

高層模組不應該依賴於低層模組,兩者應該依賴於抽象;

抽象不應該依賴於具體,具體應該依賴於抽象;

  View Code

 

控制反轉:

控制反轉(IoC),它為相互依賴的元件提供抽象,將依賴(低層模組)物件的獲得交給第三方(系統)來控制,即依賴物件不在被依賴模組的類中直接通過new來獲取。

控制反轉IoC是Inversion of Control的縮寫,是說物件的控制權進行轉移,轉移到第三方,比如轉移交給了IoC容器,它就是一個建立工廠,你要什麼物件,它就給你什麼物件,有了IoC容器,依賴關係就變了,原先的依賴關係就沒了,它們都依賴IoC容器了,通過IoC容器來建立它們之間的關係。

 

依賴注入:

依賴注入,控制反轉(IoC)一種重要的方式,就是將依賴物件的建立和繫結轉移到被依賴物件類的外部來實現。

依賴注入,就是由IoC容器在執行期間,動態地將某種依賴關係注入到物件之中。

  View Code

呼叫方式:

  View Code

 

注入方式: 

依賴注入的方式有很多:

  • 構造器注入(Constructor Injection):Ioc容器會智慧地選擇選擇和呼叫適合的建構函式以建立依賴的物件。如果被選擇的建構函式具有相應的引數,Ioc容器在呼叫建構函式之前解析註冊的依賴關係並自行獲得相應引數物件;
  • 屬性注入(Property Injection):如果需要使用到被依賴物件的某個屬性,在被依賴物件被建立之後,Ioc容器會自動初始化該屬性;
  • 方法注入(Method Injection):如果被依賴物件需要呼叫某個方法進行相應的初始化,在該物件建立之後,Ioc容器會自動呼叫該方法

編寫例項說明依賴注入的方式:

介面IA,IB,IC,ID和具體類A,B,C,D。

  View Code

客戶端呼叫方式:

複製程式碼
IUnityContainer container = new UnityContainer();
            container.RegisterType<IA, A>();
            container.RegisterType<IB, B>();
            container.RegisterType<IC, C>();
            container.RegisterType<ID, D>();
           
            A a = container.Resolve<IA>() as A;
            if (null != a)
            {
                Console.WriteLine("a.B == null ? {0}", a.B == null ? "Yes" : "No");
                Console.WriteLine("a.C == null ? {0}", a.C == null ? "Yes" : "No");
                Console.WriteLine("a.D == null ? {0}", a.D == null ? "Yes" : "No");
            }
複製程式碼

執行結果:

 

自我理解:

 依賴注入,從深層次上還是不能理解其本質。此處介紹其用法,大致可分為三步:

1、定義一個container,

IUnityContainer container = new UnityContainer();

2、介面和實現類的註冊,

container.RegisterType<ILogger, Logger>();

3、生成物件

ILogger logger = container.Resolve<ILogger>();

 

 

網上摘抄:

一、

大多數面向物件程式語言,在呼叫一個類的時候,先要例項化這個類,生成一個物件。
如果你在寫一個類,過程中要呼叫到很多其它類,甚至這裡的其它類,也要“依賴”於更多其它的類,那麼可以想象,你要進行多少次例項化。

這就是“依賴”的意思。

依賴注入,全稱是“依賴注入到容器”, 容器(IOC容器)是一個設計模式,它也是個物件,你把某個類(不管有多少依賴關係)放入這個容器中,可以“解析”出這個類的例項。

所以依賴注入就是把有依賴關係的類放入容器(IOC容器)中,然後解析出這個類的例項

二、

假如有一個 船(C)類 ,一個 槳(J) 類,

class C{
    J j = new J() ;
}

如果船要幹什麼事,肯定需要漿的參與。所以是十分 “依賴”漿;
出了需求需要重構:這時候我們需要控制漿的長度為10在構造方法中。我們需要這麼寫;

class C{
    J j = new J(10) ;
}

一個特性需要修改漿構造方法,又需要修改船其中的new J()方法。這時候就設計者就思考,為什麼我們加入一個特性需要更改兩個類中程式碼(這也就是耦合度高)!
所以我們要解耦要依賴注入;

常用解耦方式:
構造方法注入
如下:我重構程式碼的時候在也不用看哪裡的漿還是短的了!因為船構造方法依賴了漿。任你漿怎麼設計,我用的時候傳一個漿進來即可。(下層依賴上層,用的時候傳入,而不是針對下層去修改)

複製程式碼
class C{
    J j ;
    public c(J j)
    {
        this.j = j;
    };
}
複製程式碼

工廠模式注入

工廠模式 Human 人 去注入; 工廠類如下

複製程式碼
Class Human {
    J j =new J();
    J getJ()
    {
        return j ;
    }
}
複製程式碼

此時如下:不管你怎麼改漿,改成100米與船都無關,他只要依賴Human,
一千個船修改漿需求我只修改Human類中方法便可。(核心業務邏輯需要依賴的類例項化交給第三方類來實現注入。)

Class C {
    J j ;
    Human h = new Human;
    j=Human.getJ();
}

框架注入(本質還是工廠設計模式的具體實現)
本質也是第三方依賴注入,但是這個第三方可以脫離類。將物件依賴對映資訊儲存在容器一般為.xml 或者特定的物件中,並實現動態的注入。

推薦兩篇相當精彩實用的博文:

【調侃】IOC前世今生

IoC模式

談談對Spring IOC的理解

 

引用:

一個簡單的小程式演示Unity的三種依賴注入方式

小菜學習設計模式(五)—控制反轉(Ioc)

IoC模式(依賴、依賴倒置、依賴注入、控制反轉)

IoC模式

引言:

   專案中遇到關於IOC的一些內容,因為和正常的邏輯程式碼比較起來,IOC有點反常。因此本文記錄IOC的一些基礎知識,並附有相應的簡單例項,而在實際專案中再複雜的應用也只是在基本應用的基礎上擴充套件而來的。本文目的兩個,一是記錄學習過程,以便將來溫故;二是請大牛對小弟指點一二。

 

概念:

  控制反轉(Inversion of Control,英文縮寫為IoC)是一個重要的面向物件的法則來削減計算機程式的耦合問題,也是輕量級的Spring框架的核心。 控制反轉一般分為兩種型別,依賴注入(Dependency Injection,簡稱DI)和依賴查詢(Dependency Lookup)。依賴注入應用比較廣泛。-百度百科。

 

簡單例項:

下面編寫使用IOC實現的簡單例項,以便大家對IOC有個初始的概念。功能是輸入字串格式的日誌,程式碼如下:

介面ILogger和具體的Logger類:

  View Code

常規的呼叫方式:

ILogger logger = new Logger();
logger.Log("good");

 

使用IOC模式的客戶端調取方式:

新增using Microsoft.Practices.Unity;

IUnityContainer container = new UnityContainer();
container.RegisterType<ILogger, Logger>();
ILogger logger = container.Resolve<ILogger>();
logger.Log("good");

結果如下:

 

介紹常用的概念:依賴、依賴倒置、控制反轉、依賴注入。

日常編碼過程中,新建一個類,進而new物件進而進行相關的業務邏輯,例如下面例項,使用者播放媒體檔案:

  View Code

 

從上文可以看出程式碼的耦合度太高了,如果有新的需求,需要改動的地方太多了,那麼使用依賴倒置原則來降低耦合度。

依賴倒置原則:

高層模組不應該依賴於低層模組,兩者應該依賴於抽象;

抽象不應該依賴於具體,具體應該依賴於抽象;

  View Code

 

控制反轉:

控制反轉(IoC),它為相互依賴的元件提供抽象,將依賴(低層模組)物件的獲得交給第三方(系統)來控制,即依賴物件不在被依賴模組的類中直接通過new來獲取。

控制反轉IoC是Inversion of Control的縮寫,是說物件的控制權進行轉移,轉移到第三方,比如轉移交給了IoC容器,它就是一個建立工廠,你要什麼物件,它就給你什麼物件,有了IoC容器,依賴關係就變了,原先的依賴關係就沒了,它們都依賴IoC容器了,通過IoC容器來建立它們之間的關係。

 

依賴注入:

依賴注入,控制反轉(IoC)一種重要的方式,就是將依賴物件的建立和繫結轉移到被依賴物件類的外部來實現。

依賴注入,就是由IoC容器在執行期間,動態地將某種依賴關係注入到物件之中。

  View Code

呼叫方式:

  View Code

 

注入方式: 

依賴注入的方式有很多:

  • 構造器注入(Constructor Injection):Ioc容器會智慧地選擇選擇和呼叫適合的建構函式以建立依賴的物件。如果被選擇的建構函式具有相應的引數,Ioc容器在呼叫建構函式之前解析註冊的依賴關係並自行獲得相應引數物件;
  • 屬性注入(Property Injection):如果需要使用到被依賴物件的某個屬性,在被依賴物件被建立之後,Ioc容器會自動初始化該屬性;
  • 方法注入(Method Injection):如果被依賴物件需要呼叫某個方法進行相應的初始化,在該物件建立之後,Ioc容器會自動呼叫該方法

編寫例項說明依賴注入的方式:

介面IA,IB,IC,ID和具體類A,B,C,D。

  View Code

客戶端呼叫方式:

複製程式碼
IUnityContainer container = new UnityContainer();
            container.RegisterType<IA, A>();
            container.RegisterType<IB, B>();
            container.RegisterType<IC, C>();
            container.RegisterType<ID, D>();
           
            A a = container.Resolve<IA>() as A;
            if (null != a)
            {
                Console.WriteLine("a.B == null ? {0}", a.B == null ? "Yes" : "No");
                Console.WriteLine("a.C == null ? {0}", a.C == null ? "Yes" : "No");
                Console.WriteLine("a.D == null ? {0}", a.D == null ? "Yes" : "No");
            }
複製程式碼

執行結果:

 

自我理解:

 依賴注入,從深層次上還是不能理解其本質。此處介紹其用法,大致可分為三步:

1、定義一個container,

IUnityContainer container = new UnityContainer();

2、介面和實現類的註冊,

container.RegisterType<ILogger, Logger>();

3、生成物件

ILogger logger = container.Resolve<ILogger>();

 

 

網上摘抄:

一、

大多數面向物件程式語言,在呼叫一個類的時候,先要例項化這個類,生成一個物件。
如果你在寫一個類,過程中要呼叫到很多其它類,甚至這裡的其它類,也要“依賴”於更多其它的類,那麼可以想象,你要進行多少次例項化。

這就是“依賴”的意思。

依賴注入,全稱是“依賴注入到容器”, 容器(IOC容器)是一個設計模式,它也是個物件,你把某個類(不管有多少依賴關係)放入這個容器中,可以“解析”出這個類的例項。

所以依賴注入就是把有依賴關係的類放入容器(IOC容器)中,然後解析出這個類的例項

二、

假如有一個 船(C)類 ,一個 槳(J) 類,

class C{
    J j = new J() ;
}

如果船要幹什麼事,肯定需要漿的參與。所以是十分 “依賴”漿;
出了需求需要重構:這時候我們需要控制漿的長度為10在構造方法中。我們需要這麼寫;

class C{
    J j = new J(10) ;
}

一個特性需要修改漿構造方法,又需要修改船其中的new J()方法。這時候就設計者就思考,為什麼我們加入一個特性需要更改兩個類中程式碼(這也就是耦合度高)!
所以我們要解耦要依賴注入;

常用解耦方式:
構造方法注入
如下:我重構程式碼的時候在也不用看哪裡的漿還是短的了!因為船構造方法依賴了漿。任你漿怎麼設計,我用的時候傳一個漿進來即可。(下層依賴上層,用的時候傳入,而不是針對下層去修改)

複製程式碼
class C{
    J j ;
    public c(J j)
    {
        this.j = j;
    };
}
複製程式碼

工廠模式注入

工廠模式 Human 人 去注入; 工廠類如下

複製程式碼
Class Human {
    J j =new J();
    J getJ()
    {
        return j ;
    }
}
複製程式碼

此時如下:不管你怎麼改漿,改成100米與船都無關,他只要依賴Human,
一千個船修改漿需求我只修改Human類中方法便可。(核心業務邏輯需要依賴的類例項化交給第三方類來實現注入。)

Class C {
    J j ;
    Human h = new Human;
    j=Human.getJ();
}

框架注入(本質還是工廠設計模式的具體實現)
本質也是第三方依賴注入,但是這個第三方可以脫離類。將物件依賴對映資訊儲存在容器一般為.xml 或者特定的物件中,並實現動態的注入。

推薦兩篇相當精彩實用的博文:

【調侃】IOC前世今生

IoC模式

談談對Spring IOC的理解

 

引用:

一個簡單的小程式演示Unity的三種依賴注入方式

小菜學習設計模式(五)—控制反轉(Ioc)

IoC模式(依賴、依賴倒置、依賴注入、控制反轉)

IoC模式