色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

淺談控制反轉和依賴注入

454398 ? 來源:博客園 ? 作者:田園里的蟋蟀 ? 2020-10-29 11:38 ? 次閱讀

控制反轉(Inversion of Control)是解決程序耦合問題的一種方案,還有種叫法是依賴注入(Dependency Injection),但我感覺Ioc(控制反轉)是一種思想,DI(依賴注入)是實現這種思想的一種方式,或者說Ioc是一種概念,DI是這種概念的思想,不知道我這樣理解的對不對。可能一開始接觸這些東西有點莫名其妙,園友們寫的一些東西也看得頭疼,至少我當時是這樣,如果你是像我一樣的菜鳥,請跟我一起學習下,不看代碼,我們先看一個生活中的例子-壓水井和自來水廠的故事

小時候在農村喝水都是自家打井或是用電水泵取水,想什么時候喝就什么時候喝,想喝多少就喝多少,很方便,而且不用花錢。但是有個問題是,家里面的房子要裝修或是重建,原來打的井已經不適合新建的房子了,也就是說需要重新打井,這就很麻煩,建多少次房子,需要打多少次的井(當然土豪才這樣)。

我們先看這個小示例,其實如果抽象一點的話,有點類似工廠模式,為什么?我們分析下:上面例子中的水可以看成一個產品,每家的井或是電水泵可以看成一個工廠,自己根據自家的情況來“生產”出來水,只有一家有井或是電水泵還好(其他家去他家取水,但不現實),如果每家都有一個井或是電水泵,就有點工廠泛濫的情況發生了,可能會出現:

水污染:每家都吃不上水,這里面的水出現問題就是產品出現問題,這樣我們就需要在每個工廠里面進行處理,就比如需要在每家的井或電水泵上安裝一個凈水器,顯然代價比較大,也不太現實。

整體搬遷:原來的井或電水泵用不了了,每家的井或電水泵就需要重新搞,可能不太現實,當然只是做個假設,細想一下,這個問題的根源其實就是井或電水泵太多了,也就是工廠泛濫。

上面所說的問題為什么會出現?其實就是依賴關系作祟,每一家都要依賴自家的井或電水泵,也沒辦法,畢竟人要喝水,總不能跑到地下暗河去喝吧,只能通過井或電水泵(工廠)來取水(調用),這個問題在編程中就是依賴倒置原則的反例,何為依賴倒置原則

高層次的模塊不應該依賴于低層次的模塊,他們都應該依賴于抽象。

抽象不應該依賴于具體,具體應該依賴于抽象。

第一點:高層次模塊(使用者)就是每戶人家,低層次模塊(被使用者)就是壓水井或電水泵,可以看出他們都是依賴于具體的對象,而并非依賴于抽象;第二點:水(抽象)依賴壓水井或電水泵(具體),人(具體)依賴壓水井(具體),而并非具體依賴于抽象。可以看出這兩點完全不設和依賴倒置原則,怎么解決問題呢?請看下面。

自來水廠

上面的示例中其實有個三個對象:每戶人家、壓水井或電水泵、水,就是在探討他們三個這之間的依賴關系,明確這一點很重要。

隨著時代的發展,壓水井和電水泵慢慢消失在我們的視野中(當然現在還有很多落后的地方在用,比如像我老家),政府就在每個村莊或是幾個村莊之間建設自來水廠,為什么政府要建設自來水廠?難道他們都是搞編程的?知道工廠泛濫的壞處?哈哈,我覺得應該是多收點錢吧,你覺得呢?開個玩笑。

不管政府目的如何,但好像解決了工廠泛濫的一些問題,我們再來分析下有了自來水廠會有什么不同,我們畫個示意圖看下:

畫的比較丑(莫笑),但是簡單的意思還是可以表達的,圖中的人和水都是抽象的,地下水和水庫依賴于于抽象的水,A村的人和B村的人依賴于抽象的人,人和水怎么關系呢?這個就有自來水廠決定了,它讓你喝地下水,你就不能喝水庫的水。這就基本符合依賴倒置原則:抽象不依賴于具體,具體依賴于抽象

這中間關鍵在于自來水廠,沒了壓水井,有了自來水廠,我們看看上面壓水井的“工廠泛濫”問題能不能解決?

水污染:比如地下水出現問題,因為自來水廠不依賴地下水,而是依賴于抽象的水,地下水有問題,那我用水庫的水,水庫的水如果有問題,那我們用雨水凈化。。。我們人喝到的不管什么水?反正都是水,不影響我們喝水就行了。

整體搬遷:比如A村的人因為某些原因,要搬到B村,如果是上面壓水井的模式,幫過去就需要重新打井了,但是有了自來水廠,我只需要接個管線,按個水龍頭就行了,就這么簡單。

從上面的分析來看,建設自來水廠確實比壓水井可靠多了,回到我們這篇要講的正題-控制反轉(Ioc),你可能也有些明白了,其實自來水廠就可以看做是Ioc,用什么樣的水?給什么樣的人?都是自來水廠決定,好處就不用多說了,上面已經講明,套用到編程里面是相同的道理,只可意會哦。

說到這里,你不禁有些驚訝,難道政府里面有系統架構師?哈哈笑過。

上面的示例,下面我們再來用代碼復述一下,畢竟理論要結合實踐。

壓水井的問題-依賴

壓水井模式有三個對象:人、壓水井、水,我們就用常規的方式簡單寫下代碼:

 1         /// 
 2         /// 村民
 3         /// 
 4         public class VillagePeople
 5         {
 6             public void DrinkWater()
 7             {
 8                 PressWater pw = new PressWater();
 9                 UndergroundWater uw = pw.returnWater();
10                 if (uw!=null)
11                 {
12                     Console.WriteLine("地下水好甜啊!!!");
13                 }
14             }
15         }
16         /// 
17         /// 壓水井
18         /// 
19         public class PressWater
20         {
21             public UndergroundWater returnWater()
22             {
23                 return new UndergroundWater();
24             }
25         }
26         /// 
27         /// 地下水
28         /// 
29         public class UndergroundWater
30         { 
31         }

上面的代碼就是簡單演示村民通過壓水井喝水的過程,因為村民不能直接取得水,只能通過壓水井取得地下水,很明顯我們可以看出之間的依賴關系:

VillagePeople依賴于PressWater

VillagePeople依賴于UndergroundWater

PressWater依賴于UndergroundWater

我們在做業務處理的時候,簡單的依賴關系可以用上面的方式處理,如果太復雜的話就不行了,牽一發而動全身總歸不是很好。

大家可能說,上面不是講到“工廠泛濫”問題,這邊怎么沒指出?因為PressWater某一方面其實就可以看做一個小工廠,每家的壓水井不一樣,這邊只是說某一種,“工廠泛濫”其實就是依賴作祟,上面的例子說明的是依賴關系,一樣的道理,所以下面就用這個例子來做一些東西。

壓水井的問題解決-依賴倒置

我們在講壓水井的時候提到過依賴倒置原則,這邊就不再說了,因為VillagePeople依賴于PressWater、VillagePeople依賴于UndergroundWater、PressWater依賴于UndergroundWater,我們可以把PressWater(壓水井)和UndergroundWater(地下水)抽象出來,UndergroundWater屬于水的一種,可以抽象為IWater,PressWater因為是獲取水的方式之一,可以抽象為IWaterTool,這邊就要面向接口編程了,根據依賴倒置原則,我們把上面的代碼修改一下:

 1         /// 
 2         /// 村民
 3         /// 
 4         public class VillagePeople
 5         {
 6             public void DrinkWater()
 7             {
 8                 IWaterTool pw = new PressWater();
 9                 IWater uw = pw.returnWater();
10                 if (uw != null)
11                 {
12                     Console.WriteLine("水好甜啊!!!");
13                 }
14             }
15         }
16         /// 
17         /// 壓水井
18         /// 
19         public class PressWater : IWaterTool
20         {
21             public IWater returnWater()
22             {
23                 return new UndergroundWater();
24             }
25         }
26         /// 
27         /// 獲取水方式接口
28         /// 
29         public interface IWaterTool
30         {
31             IWater returnWater();
32         }
33         /// 
34         /// 地下水
35         /// 
36         public class UndergroundWater : IWater
37         { }
38         /// 
39         /// 水接口
40         /// 
41         public interface IWater
42         { }

從上面的代碼可以看出,UndergroundWater依賴接口IWater,PressWater依賴IWaterTool和IWater,VillagePeople依賴IWaterTool和IWater,這樣就符合依賴倒置原則了,都是依賴于抽象,從而降低耦合度,這樣當一個方式變化了不會影響到其他,地下水污染了,我可以通過別的獲取工具獲取水,而不至于沒水喝。

但是上面說的忽略了個問題,接口總是會被實現的,也就是總會執行:IWaterTool pw =newPressWater();這樣耦合度就產生了,也就是VillagePeople依賴于PressWater,我們可以通過工廠參數來產生不同的獲取工具對象,這種方式表面上雖然解決了問題,但是實質上代碼耦合度并沒有改變,怎么辦呢?請接著往下看。

自來水廠-Ioc

通過Ioc模式可以徹底解決上面我們提到耦合的問題,它把耦合從代碼中移出去,放到統一的XML文件中,通過一個容器在需要的時候把這個依賴關系形成,即把需要的接口實現注入到需要它的類中。就像自來水廠一樣,水的來源、水的去處都是它來決定,人們只要通過它來喝水就行了,而不需要考慮的太多。

早在微軟提供的一個示例框架PetShop中就有Ioc的體現,只不過那時候不太懂,PetShop是通過反射創建對象,上面的代碼我們修改一下:

 1         /// 
 2         /// 村民
 3         /// 
 4         public class VillagePeople
 5         {
 6             public void DrinkWater()
 7             {
 8                 IWaterTool pw = (IWaterTool)Assembly.Load(ConfigurationManager.AppSettings["AssemName"]).CreateInstance(ConfigurationManager.AppSettings["WaterToolName"]);
 9                 IWater uw = pw.returnWater();
10                 if (uw != null)
11                 {
12                     Console.WriteLine("水好甜啊!!!");
13                 }
14             }
15         }

上面代碼中我們只需要在配置文件中添加獲取水工具的名稱WaterToolName就行了,因為一種工具對應獲取特定的一種水,所以水的種類不需要配置。地下水污染了,我們只需要在配置文件中修改一下WaterToolName就可以了。

Ioc模式,系統中通過引入實現了Ioc模式的Ioc容器,即可由Ioc容器來管理對象的生命周期、依賴關系等,從而使得應用程序的配置和依賴性規范與實際的應用程序代碼分開。其中一個特點就是通過文本的配置文件進行應用程序組件間相互關系的配置,而不用重新修改并編譯具體的代碼。

看到這里,是不是感覺Ioc模式有點“熱插拔”的意思?有點像USB一樣呢?

自來水廠運行-DI

如果把自來水廠看做Ioc,那我覺得依賴注入(DI)就是這個自來水廠的運行模式,當然其實是一個意思,依賴注入是什么?全稱Dependency Injection,我們從字面上理解下:需要的接口實現注入到需要它的類中,這就是依賴注入的意思。自來水廠獲取水源的時候,控制這個獲取水源的開關可以看做是依賴注入的一種體現,話不多說,懂得就好。

依賴注入的方式有很多,就像控制獲取水源的開關有很多一樣。

構造器注入(Constructor Injection):Ioc容器會智能地選擇選擇和調用適合的構造函數以創建依賴的對象。如果被選擇的構造函數具有相應的參數,Ioc容器在調用構造函數之前解析注冊的依賴關系并自行獲得相應參數對象;

屬性注入(Property Injection):如果需要使用到被依賴對象的某個屬性,在被依賴對象被創建之后,Ioc容器會自動初始化該屬性;

方法注入(Method Injection):如果被依賴對象需要調用某個方法進行相應的初始化,在該對象創建之后,Ioc容器會自動調用該方法。

有時間可以好好研究下依賴注入的各種方式,這邊我們就使用微軟提供的Unity實現依賴注入,方式是構造器注入,首先使用Nuget工具將Unity添加到項目中,安裝Unity需要.net framework4.5支持。

添加完之后,發下項目中多了Microsoft.Practices.Unity和Microsoft.Practices.Configuation兩個dll,代碼如下:

 1         /// 
 2         /// 人接口
 3         /// 
 4         public interface IPeople
 5         {
 6             void DrinkWater();
 7         }
 8         /// 
 9         /// 村民
10         /// 
11         public class VillagePeople : IPeople
12         {
13             IWaterTool _pw;
14             public VillagePeople(IWaterTool pw)
15             {
16                 _pw = pw;
17             }
18             public void DrinkWater()
19             {
20                 IWater uw = _pw.returnWater();
21                 if (uw != null)
22                 {
23                     Console.WriteLine("水好甜啊!!!");
24                 }
25             }
26         }

調用代碼:

1         static void Main(string[] args)
2         {
3             UnityContainer container = new UnityContainer();
4             container.RegisterType();
5             TestFour.IPeople people = container.Resolve();
6             people.DrinkWater();
7         }

首先我們創建一個Unity容器,接下來我們需要在容器中注冊一種類型,它是一個類型的映射,接口類型是IWaterTool,返回類型為PressWater,這個過程中就是要告訴容易我要注冊的類型。

比如自來水廠要用地下水作為水源,這時候操作員輸入命令,就是RegisterType,參數為IWaterTool、PressWater,下面就是調用Resolve生成對象,這個過程表示要把水輸送到哪戶人家,命令是Resolve,參數為VillagePeople,接下來就是直接打開水龍頭喝水了,很方便吧。

關于依賴注入其實有很多的東西,上面的示例只是拋磚引玉,有時間的話好好研究下,比如依賴注入的其他方式等等。
編輯:hfy

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • IOC
    IOC
    +關注

    關注

    0

    文章

    28

    瀏覽量

    10146
  • Unity
    +關注

    關注

    1

    文章

    127

    瀏覽量

    21875
收藏 人收藏

    評論

    相關推薦

    PLC控制電機正反轉的物聯網解決方案

    機床工作臺的前進與后退、機床主軸的正轉與反轉、升降機的上升與下降等。為了滿足這些要求,PLC控制電動機必須能夠實現正反轉。 為實現對這類自動化設備的遠程監控,數之能提供高效可靠的物聯網解決方案。通過將數之能數據中臺接入控
    的頭像 發表于 11-19 15:53 ?275次閱讀
    PLC<b class='flag-5'>控制</b>電機正<b class='flag-5'>反轉</b>的物聯網解決方案

    什么是電機正反轉?電機正反轉主要應用在哪些方面?

    能力。 電機正反轉的基本原理 電機正反轉的實現主要依賴于電機的控制方式。在交流電機中,通過改變電源的相序或使用變頻器改變電源的頻率和相位,可以實現電機的正
    的頭像 發表于 10-24 13:56 ?2603次閱讀

    drv8412是怎么控制電機正反轉的?

    請問drv8412是怎么控制電機的正反轉,謝謝
    發表于 09-20 07:13

    無刷電機正反轉由什么控制

    無刷電機(Brushless DC Motor, BLDC)是一種沒有電刷的電機,它通過電子換向器來控制電流的流向,從而實現電機的轉動。無刷電機的正反轉控制是其應用中的一個重要方面,涉及到電機的驅動
    的頭像 發表于 09-03 14:14 ?912次閱讀

    如何將行程開關接入正反轉控制電路

    行程開關是一種常見的限位開關,用于控制機械設備的行程。在正反轉控制電路中,行程開關可以用于實現自動控制,當設備到達預定位置時,自動切換到反向運動。以下是將行程開關接入正
    的頭像 發表于 08-26 16:35 ?838次閱讀

    ESP32控制舵機的正反轉原理是什么

    舵機是一種將電信號轉換為機械運動的設備,廣泛應用于機器人、無人機、汽車等領域。ESP32是一款功能強大的微控制器,具有豐富的外設接口和高性能的處理能力,可以方便地控制舵機實現正反轉等動作。本文將介紹
    的頭像 發表于 08-20 09:13 ?1288次閱讀

    變頻器控制電機的正反轉控制方式有哪些?

    變頻器是一種廣泛應用于工業領域的電力調整設備,它可以通過改變電源的頻率來實現電機的速度控制。在許多生產過程中,電機的正反轉控制是非常重要的,變頻器能夠通過不同的控制方式來實現這一功能。
    的頭像 發表于 08-14 17:04 ?1895次閱讀

    簡單介紹plc如何控制電機正反轉

    PLC(可編程邏輯控制器)控制電機正反轉的過程可以通過以下步驟清晰地表示和歸納: 一、了解電機正反轉工作原理 電機正反轉是指電機能夠實現順時
    的頭像 發表于 07-29 10:37 ?1109次閱讀

    兩相正反轉開關怎么接線方法

    兩相正反轉開關是一種常見的電氣設備,主要用于實現電動機的正反轉控制。在實際應用中,正確接線是保證設備正常運行的關鍵。本文將介紹兩相正反轉開關的接線方法,包括原理、步驟和注意事項。 一、
    的頭像 發表于 07-19 10:48 ?4389次閱讀

    v20變頻器控制電機反轉怎么調

    以下是一些關于V20變頻器控制電機反轉的基本步驟和注意事項。 確認電機和變頻器的型號和規格是否匹配。 確保電機和變頻器的接線正確,包括電源線、控制線和電機線。 檢查變頻器的設置,確保其工作在正確
    的頭像 發表于 06-18 09:46 ?2593次閱讀

    PLC控制電動機正反轉電路的工作原理

    在工業自動化控制中,電動機作為動力源,其正反轉控制是常見的控制需求。傳統的電動機正反轉控制主要
    的頭像 發表于 06-17 09:37 ?2297次閱讀

    PLC如何判斷編碼器正反轉

    在工業自動化控制系統中,編碼器作為重要的位置反饋元件,其輸出的信號能夠準確地反映被控對象的旋轉位置或角度。對于PLC(可編程邏輯控制器)來說,判斷編碼器的正反轉是實現精確控制的基礎。本
    的頭像 發表于 06-17 09:31 ?2502次閱讀

    步進電機的正反轉實現方法

    步進電機,作為一種將電脈沖信號轉換為角位移或線位移的精密控制電機,其正反轉的實現對于許多應用至關重要。本文將深入探討步進電機正反轉的實現方法,從基本的控制原理到具體的實現步驟,再到實際
    的頭像 發表于 06-14 09:58 ?3051次閱讀

    直流電機正反轉控制方式

    直流電機,作為一種將直流電能轉化為機械能的電動機,廣泛應用于各種工業和民用領域。在實際應用中,經常需要實現直流電機的正反轉,以滿足不同的工作需求。本文將詳細介紹直流電機正反轉的實現方法,包括基本原理、控制方式和具體應用案例,以期
    的頭像 發表于 06-04 17:20 ?5339次閱讀

    什么是離子注入?離子注入的應用介紹

    離子注入是將高能離子注入半導體襯底的晶格中來改變襯底材料的電學性能的摻雜工藝。通過注入能量、角度和劑量即可控制摻雜濃度和深度,相較于傳統的擴散工藝更為精確。
    的頭像 發表于 02-21 10:23 ?5357次閱讀
    什么是離子<b class='flag-5'>注入</b>?離子<b class='flag-5'>注入</b>的應用介紹
    主站蜘蛛池模板: 淫品色影院 | 少妇高潮久久久久7777 | 69式国产真人免费视频 | 久草热在线 | 无限资源在线看影院免费观看 | 久草在线福利视频在线播放 | 王雨纯羞羞 | 欧美写真视频一区 | 草久久久久| 国产亚洲精品欧洲在线视频 | 果冻传媒妈妈要儿子 | 色欲天天婬色婬香影院 | 外国xxxx| 中国女人逼| 大胸美女洗澡扒奶衣挤奶 | 亚洲一区国产 | 亚洲欧美一级久久精品 | 国产Av男人的天堂精品良久 | 免费撕开胸罩吮胸视频 | 国产亚洲精品在浅麻豆 | 亚洲午夜精品A片久久WWW解说 | 北条麻妃のレズナンパ | 一边摸一边桶一边脱免费 | 精品国产5g影院天天爽 | 九九热视频免费 | 午夜福利体验试看120秒 | 2019天天射干网站 | 回复术士人生重启在线观看 | 97色伦图片97色伦图影院久久 | 伊人久久国产 | 美女内射少妇三区五区 | 人妻精品久久无码专区 | 乳巨揉みま痴汉电车中文字幕动漫 | 中文字幕无码他人妻味 | 成人在线观看免费视频 | 亚洲一区二区三区91 | 99久久婷婷国产麻豆精品电影 | 亚洲成人日韩 | 国产一区二区高清 | 伊人久久影院大香线蕉 | 黃色带三级a级 |