日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

IoC好处

發(fā)布時(shí)間:2025/3/21 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 IoC好处 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

IoC(Inversion of Control?,控制反轉(zhuǎn))也稱為依賴注入(Dependency Injection),作為Spring的一個(gè)核心思想,是一種設(shè)計(jì)對(duì)象之間依賴關(guān)系的原則及其相關(guān)技術(shù)。


IoC是什么?
?

高內(nèi)聚低耦合可以說(shuō)是軟件技術(shù)形態(tài)的終極目標(biāo)。用學(xué)術(shù)界的話來(lái)說(shuō),軟件的兩個(gè)本質(zhì)特性就是構(gòu)造性和演化性,高內(nèi)聚低耦合的設(shè)計(jì)能夠讓構(gòu)造和演化都更加高效,比如:

  • 開(kāi)發(fā)更方便組織分工
  • 代碼更容易進(jìn)行復(fù)用
  • 更容易進(jìn)行測(cè)試
  • 軟件演化有更好的靈活性,能快速響應(yīng)需求變化,維護(hù)代價(jià)更小

軟件設(shè)計(jì)各種技術(shù)的出現(xiàn),無(wú)一不是朝著這個(gè)終極目標(biāo)的努力。面向?qū)ο蟆⒒诮M件(學(xué)術(shù)界稱為構(gòu)件)的軟件開(kāi)發(fā)、面向切面編程(AOP)、Java近些年流行的模塊化方法(比如OSGi技術(shù))等等,這些方法和技術(shù)的出現(xiàn),無(wú)外乎都是為了讓軟件更加高內(nèi)聚低耦合。與此同時(shí),各路大神還提出各種軟件設(shè)計(jì)原則和模式,來(lái)規(guī)范我們的軟件形態(tài)。我們今天談的IoC也是其中的一個(gè)大招。

?

IoC(Inversion of Control?,控制反轉(zhuǎn))也稱為依賴注入(Dependency Injection),作為Spring的一個(gè)核心思想,是一種設(shè)計(jì)對(duì)象之間依賴關(guān)系的原則及其相關(guān)技術(shù)。

?

先來(lái)看看字面上怎么來(lái)解釋:當(dāng)一個(gè)對(duì)象創(chuàng)建時(shí),它所依賴的對(duì)象由外部傳遞給它,而非自己去創(chuàng)建所依賴的對(duì)象(比如通過(guò)new操作)。因此,也可以說(shuō)在對(duì)象如何獲取它的依賴對(duì)象這件事情上,控制權(quán)反轉(zhuǎn)了。這便不難理解控制反轉(zhuǎn)和依賴注入這兩個(gè)名字的由來(lái)了。


一個(gè)場(chǎng)景
?

上面的解釋聽(tīng)起來(lái)還是有點(diǎn)晦澀,讓我們來(lái)看看具體的例子吧!

有個(gè)土豪老板,我們經(jīng)常要出差,因此經(jīng)常要訂機(jī)票。定機(jī)票呢,可以通過(guò)去哪兒網(wǎng)訂票,也可以通過(guò)攜程訂票。

我們馬上可以想到可以通過(guò)三個(gè)類來(lái)表達(dá)這個(gè)場(chǎng)景,Boss,QunarBookingService,CtripBookingService。當(dāng)然了,我們還應(yīng)該提供一個(gè)BookingService接口,作為QunarBookingService,CtripBookingService的公共抽象。面向接口編程是面向?qū)ο笤O(shè)計(jì)的基本原則,如果這都不了解,趕緊先回去看GoF的《設(shè)計(jì)模式》第一章!

BookingService.java

package com.tianmaying.iocdemo;public interface BookingService {void bookFlight(); }

QunarBookingService.java

package com.tianmaying.iocdemo;public class QunarBookingService implements BookingService {public void bookFlight() {System.out.println("book fight by Qunar!");} }

CtripBookingService.java

package com.tianmaying.iocdemo;public class CtripBookingService implements BookingService {public void bookFlight() {System.out.println("book fight by Ctrip!");} }

好了,土豪出門談生意,得訂機(jī)票了,Boss就琢磨著怎么訂票呢,Boss比較了一下價(jià)格,這一次決定用去哪兒,對(duì)應(yīng)的Boss的代碼:

Boss.java

package com.tianmaying.iocdemo;public class Boss {private BookingService bookingService;public Boss() {this.bookingService = new QunarBookingService();}public BookingService getBookingService() {return bookingService;}public void setBookingService(BookingService bookingService) {this.bookingService = bookingService;}public void goSomewhere() {bookingService.bookFlight();} }

在Boss的構(gòu)造函數(shù)中,將其bookingService成員變量實(shí)例化為?QunarBookingService,goSomewhere()函數(shù)中就可以調(diào)用bookingService的bookFlight方法了!

為了把這個(gè)場(chǎng)景Run起來(lái),我們還需要一個(gè)main函數(shù):

package com.tianmaying.iocdemo;public class App {public static void main(String[] args) {bossGoSomewhere();}static void bossGoSomewhere() {Boss boss = new Boss();boss.goSomewhere();} }

運(yùn)行之后可以看到控制中可以打印出"book fight by Qunar!"了。


使用IoC的場(chǎng)景
?

在這個(gè)例子中,我們看到Boss需要使用BookingService,于是Boss自己實(shí)例化了一個(gè)QunarBookingService對(duì)象。同志們想想,身為土豪Boss,思考的都是公司戰(zhàn)略的事兒,定個(gè)票還要自己選擇通過(guò)什么方式來(lái)完成,這個(gè)Boss是不是當(dāng)?shù)脤?shí)在太苦逼。

?

所以土豪趕緊給自己找了個(gè)美女秘書(shū)(別想歪!),Boss要出差時(shí),只需要說(shuō)一聲他需要訂票服務(wù),至于是哪個(gè)服務(wù),讓美女秘書(shū)選好后告訴他即可(注入啊!注入!)。(別跟我較真說(shuō)美女秘書(shū)直接把票送上就行!)

?

這樣的話,Boss是不是一身輕松了? 而這個(gè)美女秘書(shū)還是免費(fèi)包郵的,這正是Spring扮演的角色!來(lái)看看使用Spring之后的代碼。

?

我們?cè)趐om.xml文件中加入依賴(項(xiàng)目使用Maven作為構(gòu)建工具):

<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>4.2.0.RELEASE</version> </dependency>

QunarBookingService.java

package com.tianmaying.iocdemo; import org.springframework.stereotype.Component;@Component public class QunarBookingService implements BookingService {public void bookFlight() {System.out.println("book fight by Qunar!");} }

這里我們使用Spring的@Component標(biāo)注將QunarBookingService注冊(cè)進(jìn)Spring的Context,這樣它就可以被注入到需要它的地方!相應(yīng)地,創(chuàng)建QunarBookingService實(shí)例的責(zé)任也交給了Spring。我們說(shuō)了,美女秘書(shū)幫你搞定嘛!

?

新建一個(gè)SmartBoss類,聰明的老板知道把選擇訂機(jī)票服務(wù)這樣的雜事交給秘書(shū)來(lái)做。

SmartBoss.java

package com.tianmaying.iocdemo;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component;@Component public class SmartBoss {private BookingService bookingService;@Autowiredpublic void setBookingService(BookingService bookingService) {this.bookingService = bookingService;}public BookingService getBookingService() {return bookingService;}public void goSomewhere() {bookingService.bookFlight();} }

在上面的代碼中,SmartBoss不再自己創(chuàng)建BookingService的實(shí)例,只是通過(guò)@Autowired標(biāo)注告訴Spring小秘我需要一個(gè)BookingService!

?

調(diào)用代碼因此也要做一些小修改,需要?jiǎng)?chuàng)建Spring的Context:

static void smartBossGoSomewhere() {AbstractApplicationContext context = new AnnotationConfigApplicationContext(App.class);try {SmartBoss boss = context.getBean(SmartBoss.class);boss.goSomewhere();} finally {context.close();} }



IoC的好處
?

回到正題,通過(guò)上面的例子,我們來(lái)看看IoC到底帶來(lái)了哪些好處?

?

Boss沒(méi)有和某個(gè)具體的BookingService類耦合到一起了,這樣Boss的維護(hù)和演化就更加方便。想象一下,如果Boss需要改用CtripBookingService,這時(shí)也不需要修改Boss.java的代碼,更換接口的實(shí)現(xiàn)非常方便,給Boss注入新的實(shí)現(xiàn)即可,輕松愜意。(當(dāng)然,要做到熱插拔還需要進(jìn)一步的工作,要么得玩轉(zhuǎn)類加載器這玩意,或者借助OSGi這樣的神器)。這也是典型的開(kāi)放-封閉原則的例子,即對(duì)現(xiàn)有模塊,功能擴(kuò)展應(yīng)該是開(kāi)放的,而對(duì)其代碼修改應(yīng)該是封閉的,即能夠做到不需要修改已有代碼來(lái)擴(kuò)展新的功能。

?

想象一下,如果Boss自己直接去實(shí)例化QunarBookingService,而QunarBookingService在另外一個(gè)Package中甚至另外一個(gè)Jar包中,你可得import進(jìn)來(lái)才能使用,緊耦合啊!現(xiàn)在好了,Boss只依賴于抽象接口,測(cè)試更方便了吧,Mock一下就輕松搞定!Boss和QunarBookingService彼此不知道對(duì)方,Spring幫兩者粘合在一起。

?

為什么IoC是個(gè)大招,因?yàn)樗鼤?huì)自然而然得促進(jìn)你應(yīng)用一些好的設(shè)計(jì)原則,會(huì)幫助你開(kāi)發(fā)出更加“高內(nèi)聚低耦合”的軟件。


IoC如何實(shí)現(xiàn)
?

最后我們簡(jiǎn)單說(shuō)說(shuō)IoC是如何實(shí)現(xiàn)的。想象一下如果我們自己來(lái)實(shí)現(xiàn)這個(gè)依賴注入的功能,我們?cè)趺磥?lái)做? 無(wú)外乎:

  • 讀取標(biāo)注或者配置文件,看看Boss依賴的是哪個(gè)BookingService,拿到類名
  • 使用反射的API,基于類名實(shí)例化對(duì)應(yīng)的對(duì)象實(shí)例
  • 將對(duì)象實(shí)例,通過(guò)構(gòu)造函數(shù)或者setter,傳遞給Boss
  • 我們發(fā)現(xiàn)其實(shí)自己來(lái)實(shí)現(xiàn)也不是很難,Spring實(shí)際也就是這么做的。這么看的話其實(shí)IoC就是一個(gè)工廠模式的升級(jí)版!當(dāng)然要做一個(gè)成熟的IoC框架,還是非常多細(xì)致的工作要做,Spring不僅提供了一個(gè)已經(jīng)成為業(yè)界標(biāo)準(zhǔn)的Java IoC框架,還提供了更多強(qiáng)大的功能,所以大家就別去造輪子啦!希望了解IoC更多實(shí)現(xiàn)細(xì)節(jié)不妨通過(guò)學(xué)習(xí)Spring的源碼來(lái)加深理解!

    ?

    例子中的源碼戳 Spring的IoC原理

    ?

    針對(duì)評(píng)論的更新(2016-09-08):



    Xeric的評(píng)論:DI不等于IoC,混為一談會(huì)干擾理解。IoC是方法論,DI是實(shí)現(xiàn)形式。Inversion of Control Containers and the Dependency Injection pattern
    ?

    難得在知乎上有一個(gè)注重概念的,不錯(cuò)!那就來(lái)說(shuō)說(shuō)。



    什么是方法論,最接近的英文是Methodology,簡(jiǎn)言之是概念體系+符號(hào)表示+過(guò)程指導(dǎo),IoC是不是呢?顯然不是。關(guān)于IoC,其實(shí)你該引的文章是這篇InversionOfControl,是一種框架的現(xiàn)象(phenomenon),在你引用的文章里稱之為框架的特征(characteristic)。

    Flowler大叔最早對(duì)IoC感到困惑(那時(shí)Rod Johnson已經(jīng)一戰(zhàn)成名),為什么呢?如果對(duì)框架(軟件工程中的framework)有研究的人,都知道有個(gè)微內(nèi)核的概念,更通俗一點(diǎn)地理解是GoF設(shè)計(jì)模式中也提到過(guò)的,你不要調(diào)用我,我來(lái)調(diào)用你,反轉(zhuǎn)嘛!這都多少年前的概念了,所以你一個(gè)容器說(shuō)自己支持IoC,TM的不是類似說(shuō)我的汽車有輪子碼? 這是一個(gè)再通用不過(guò)的框架特征罷了,任何一種開(kāi)發(fā)平臺(tái)(iOS,Windows,Android),任何一個(gè)開(kāi)發(fā)框架,不都控制反轉(zhuǎn)嘛。

    注意你引的文章:

    As a result I think we need a more specific name for this pattern. Inversion of Control is too generic a term, and thus people find it confusing. As a result with a lot of discussion with various IoC advocates we settled on the name Dependency Injection.

    關(guān)鍵來(lái)了:所以在當(dāng)時(shí)Spring和PicoContainer等輕量級(jí)容器的這個(gè)Context下,IoC這個(gè)概念真正表達(dá)的含義其實(shí)應(yīng)該用一個(gè)更特化的概念來(lái)表達(dá),這就是依賴注入了,這不叫“混為一談”。但是IoC大家還是這么著被大家用下來(lái)了,表達(dá)了一個(gè)相比它原來(lái)更加狹義的概念(軟件工程史上很多概念都是這樣,即使學(xué)術(shù)界也必然會(huì)被所謂“事實(shí)上的工業(yè)標(biāo)準(zhǔn)”所影響),因?yàn)槟钦枪I(yè)界框架橫飛迅猛發(fā)展的年代啊,參考Web 建站技術(shù)中,HTML、HTML5、XHTML、CSS、SQL、JavaScript、PHP、ASP.NET、Web Services 是什么? - David 的回答。

    至于什么“方法論”-“實(shí)現(xiàn)”這個(gè)層次,一些中文文章(比如百度百科)有見(jiàn)類似說(shuō)法,大抵因?yàn)镕lower說(shuō)的:

    I'll point out now that that's not the only way of removing the dependency from the application class to the plugin implementation.

    注意啊注意,是有其他方式(比你你可能會(huì)說(shuō)依賴查找),這個(gè)時(shí)候IoC的概念指的是removing the dependency from the application class to the plugin implementation,這又回到泛化的概念了。不是這些流行Container語(yǔ)境下的IoC。但是人云亦云,大家就都這么說(shuō)了。

    所以題主問(wèn)的是Spring的IoC,文中也是介紹Spring,沒(méi)有任何不妥,說(shuō)個(gè)Spring IoC的好處犯不著說(shuō)方法論,就這個(gè)問(wèn)題而言反而可能讓題主困惑。

    歡迎探討。

    總結(jié)

    以上是生活随笔為你收集整理的IoC好处的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。