<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【65期】Spring的IOC是啥?有什么好處?

          共 2597字,需瀏覽 6分鐘

           ·

          2020-10-21 15:59

          程序員的成長(zhǎng)之路
          互聯(lián)網(wǎng)/程序員/技術(shù)/資料共享?
          關(guān)注


          閱讀本文大概需要 4.3 分鐘。

          來自:zhihu.com/question/23277575/answer/169698662

          設(shè)計(jì)模式7大原則

          為什么會(huì)有人說設(shè)計(jì)模式已死呢,因?yàn)閟pring這些框架幫你做好了類和對(duì)象的管理,讓你寫代碼的時(shí)候只專注于你實(shí)現(xiàn)的功能,而不是設(shè)計(jì)。先來看看設(shè)計(jì)模式的7大原則:
          • 開放-封閉原則

          • 單一職責(zé)原則

          • 依賴倒轉(zhuǎn)原則

          • 最小知識(shí)原則

          • 接口隔離原則

          • 合成/聚合復(fù)用原則

          • 里氏代換原則,任何基類可以出現(xiàn)的地方,子類一定可以出現(xiàn)

          依賴倒置

          假設(shè)我們?cè)O(shè)計(jì)一輛汽車:先設(shè)計(jì)輪子,然后根據(jù)輪子大小設(shè)計(jì)底盤,接著根據(jù)底盤設(shè)計(jì)車身,最后根據(jù)車身設(shè)計(jì)好整個(gè)汽車。這里就出現(xiàn)了一個(gè)“依賴”關(guān)系:汽車依賴車身,車身依賴底盤,底盤依賴輪子。
          這樣的設(shè)計(jì)看起來沒問題,但是可維護(hù)性卻很低。
          假設(shè)設(shè)計(jì)完工之后,上司卻突然說根據(jù)市場(chǎng)需求的變動(dòng),要我們把車子的輪子設(shè)計(jì)都改大一碼。這下我們就蛋疼了:因?yàn)槲覀兪歉鶕?jù)輪子的尺寸設(shè)計(jì)的底盤,輪子的尺寸一改,底盤的設(shè)計(jì)就得修改;同樣因?yàn)槲覀兪歉鶕?jù)底盤設(shè)計(jì)的車身,那么車身也得改,同理汽車設(shè)計(jì)也得改——整個(gè)設(shè)計(jì)幾乎都得改!
          我們現(xiàn)在換一種思路。我們先設(shè)計(jì)汽車的大概樣子,然后根據(jù)汽車的樣子來設(shè)計(jì)車身,根據(jù)車身來設(shè)計(jì)底盤,最后根據(jù)底盤來設(shè)計(jì)輪子。這時(shí)候,依賴關(guān)系就倒置過來了:輪子依賴底盤, 底盤依賴車身, 車身依賴汽車。
          這時(shí)候,上司再說要改動(dòng)輪子的設(shè)計(jì),我們就只需要改動(dòng)輪子的設(shè)計(jì),而不需要?jiǎng)拥妆P,車身,汽車的設(shè)計(jì)了。這就是依賴倒置原則——把原本的高層建筑依賴底層建筑“倒置”過來,變成底層建筑依賴高層建筑。高層建筑決定需要什么,底層去實(shí)現(xiàn)這樣的需求,但是高層并不用管底層是怎么實(shí)現(xiàn)的。這樣就不會(huì)出現(xiàn)前面的“牽一發(fā)動(dòng)全身”的情況。

          控制反轉(zhuǎn)(Inversion of Control)

          就是依賴倒置原則的一種代碼設(shè)計(jì)的思路。具體采用的方法就是所謂的依賴注入(Dependency Injection)。其實(shí)這些概念初次接觸都會(huì)感到云里霧里的。說穿了,這幾種概念的關(guān)系大概如下:
          為了理解這幾個(gè)概念,我們還是用上面汽車的例子。只不過這次換成代碼。我們先定義四個(gè)Class,車,車身,底盤,輪胎。然后初始化這輛車,最后跑這輛車。代碼結(jié)構(gòu)如下:
          這樣,就相當(dāng)于上面第一個(gè)例子,上層建筑依賴下層建筑——每一個(gè)類的構(gòu)造函數(shù)都直接調(diào)用了底層代碼的構(gòu)造函數(shù)。假設(shè)我們需要改動(dòng)一下輪胎(Tire)類,把它的尺寸變成動(dòng)態(tài)的,而不是一直都是30。我們需要這樣改:
          由于我們修改了輪胎的定義,為了讓整個(gè)程序正常運(yùn)行,我們需要做以下改動(dòng):
          由此我們可以看到,僅僅是為了修改輪胎的構(gòu)造函數(shù),這種設(shè)計(jì)卻需要修改整個(gè)上層所有類的構(gòu)造函數(shù)!在軟件工程中,這樣的設(shè)計(jì)幾乎是不可維護(hù)的——在實(shí)際工程項(xiàng)目中,有的類可能會(huì)是幾千個(gè)類的底層,如果每次修改這個(gè)類,我們都要修改所有以它作為依賴的類,那軟件的維護(hù)成本就太高了。
          所以我們需要進(jìn)行控制反轉(zhuǎn)(IoC),上層控制下層,而不是下層控制著上層。我們用依賴注入(Dependency Injection)這種方式來實(shí)現(xiàn)控制反轉(zhuǎn)。所謂依賴注入,就是把底層類作為參數(shù)傳入上層類,實(shí)現(xiàn)上層類對(duì)下層類的“控制”。這里我們用構(gòu)造方法傳遞的依賴注入方式重新寫類的定義:
          這里我們?cè)侔演喬コ叽缱兂蓜?dòng)態(tài)的,同樣為了讓整個(gè)系統(tǒng)順利運(yùn)行,我們需要做如下修改:
          看到?jīng)]?這里我只需要修改輪胎類就行了,不用修改其他任何上層類。這顯然是更容易維護(hù)的代碼。不僅如此,在實(shí)際的工程中,這種設(shè)計(jì)模式還有利于不同組的協(xié)同合作和單元測(cè)試:比如開發(fā)這四個(gè)類的分別是四個(gè)不同的組,那么只要定義好了接口,四個(gè)不同的組可以同時(shí)進(jìn)行開發(fā)而不相互受限制;而對(duì)于單元測(cè)試,如果我們要寫Car類的單元測(cè)試,就只需要Mock一下Framework類傳入Car就行了,而不用把Framework, Bottom, Tire全部new一遍再來構(gòu)造Car。
          這里我們是采用的構(gòu)造函數(shù)傳入的方式進(jìn)行的依賴注入。其實(shí)還有另外兩種方法:Setter傳遞和接口傳遞。這里就不多講了,核心思路都是一樣的,都是為了實(shí)現(xiàn)控制反轉(zhuǎn)。

          控制反轉(zhuǎn)容器(IoC Container)

          其實(shí)上面的例子中,對(duì)車類進(jìn)行初始化的那段代碼發(fā)生的地方,就是控制反轉(zhuǎn)容器。
          顯然你也應(yīng)該觀察到了,因?yàn)椴捎昧艘蕾囎⑷耄诔跏蓟倪^程中就不可避免的會(huì)寫大量的new。這里IoC容器就解決了這個(gè)問題。這個(gè)容器可以自動(dòng)對(duì)你的代碼進(jìn)行初始化,你只需要維護(hù)一個(gè)Configuration(可以是xml可以是一段代碼),而不用每次初始化一輛車都要親手去寫那一大段初始化的代碼。
          這是引入IoC Container的第一個(gè)好處。IoC Container的第二個(gè)好處是:我們?cè)趧?chuàng)建實(shí)例的時(shí)候不需要了解其中的細(xì)節(jié)。在上面的例子中,我們自己手動(dòng)創(chuàng)建一個(gè)車instance時(shí)候,是從底層往上層new的:
          這個(gè)過程中,我們需要了解整個(gè)Car/Framework/Bottom/Tire類構(gòu)造函數(shù)是怎么定義的,才能一步一步new/注入。而IoC Container在進(jìn)行這個(gè)工作的時(shí)候是反過來的,它先從最上層開始往下找依賴關(guān)系,到達(dá)最底層之后再往上一步一步new(有點(diǎn)像深度優(yōu)先遍歷):
          IoC Container可以直接隱藏具體的創(chuàng)建實(shí)例的細(xì)節(jié)。
          這是我看到的說控制反轉(zhuǎn)最清楚的文章,大家理解的時(shí)候不要在乎這些框架,而是這個(gè)設(shè)計(jì)本身,所以從設(shè)計(jì)模式的原則講起。

          推薦閱讀:

          【64期】MySQL 服務(wù)占用cpu 100%,如何排查問題? (MySQL面試第七彈)

          【63期】談?wù)凪ySQL 索引,B+樹原理,以及建索引的幾大原則(MySQL面試第六彈)

          【62期】解釋一下MySQL中內(nèi)連接,外連接等的區(qū)別(MySQL面試第五彈)

          5T技術(shù)資源大放送!包括但不限于:C/C++,Linux,Python,Java,PHP,人工智能,單片機(jī),樹莓派,等等。在公眾號(hào)內(nèi)回復(fù)「2048」,即可免費(fèi)獲取!!

          微信掃描二維碼,關(guān)注我的公眾號(hào)

          朕已閱?

          瀏覽 38
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  天堂毛片 | 一道本一区二区三区在线视频 | 欧美a v在线 | 女人成人网站 | 淫色淫香视频 |