欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

Dependency Injection 筆記 (3)

系統(tǒng) 1825 0

續(xù) 上集 接著要來(lái)進(jìn)一步了解的是 DI 的實(shí)現(xiàn)技術(shù),也就是注入相依對(duì)象的方式。這里介紹的依賴注入方式,又稱為「窮人的 DI」(poor man’s DI),因?yàn)檫@些用法都與特定 DI 工具無(wú)關(guān),亦即不使用任何現(xiàn)成的 DI 框架(例如 Unity、Autofac)。畢竟,DI 只是一組設(shè)計(jì)原則與模式,不依賴任何工具也能實(shí)現(xiàn)。

(本文摘自電子書:《 .NET?依賴注入 》)

?

設(shè)計(jì)模式梗概

每個(gè)模式都描述了一個(gè)不斷發(fā)生在我們周遭的問(wèn)題,然后描述該問(wèn)題的核心解法,于是你便可以一再使用該解法,而無(wú)須對(duì)同樣的事情做兩次工。
—— Christopher Alexander. A Pattern Language.

除了第 1 章提到的 S.O.L.I.D. 設(shè)計(jì)原則,在運(yùn)用 DI 技術(shù)時(shí),也經(jīng)常需要搭配一些設(shè)計(jì)模式(design patterns),例如 Factory Method(工廠方法)、Decorator(裝飾)、Composite(組合)、Adapter(轉(zhuǎn)換器)等等。基于后續(xù)章節(jié)討論的必要,本節(jié)將介紹幾個(gè)相關(guān)的設(shè)計(jì)模式。如需比較完整深入的介紹,可參考相關(guān)書籍,例如:《面向?qū)ο笤O(shè)計(jì)模式》、《深入淺出設(shè)計(jì)模式》、《重構(gòu)-向范式前進(jìn)》等等。


小引-電器與接口

日常生活中,四處可見電器用品,例如電視、微波爐、計(jì)算機(jī)等等。這些電器通常都有條電線,電線尾端是個(gè)插頭,而當(dāng)我們要使用這些電器時(shí),就把插頭插在墻壁或電源插座上,電器便能夠獲得所需之電力。一般情況下,沒(méi)有人會(huì)舍插座不用,而把電器的電源線固定焊在墻壁的電源插座。假使真這么做,萬(wàn)一有一天電視或計(jì)算機(jī)故障而需要維修,那可就麻煩了。

Dependency Injection 筆記 (3)

不只電源插座,計(jì)算機(jī)的 USB 插槽也一樣——它們都具備寬松耦合的特性。這里的電源插座或 USB 插槽,對(duì)應(yīng)到軟件世界里的概念,便是接口。一個(gè)接口就等于是一份規(guī)格,而各家廠商所生產(chǎn)的各式各樣的電源插座或 USB 插槽,就是遵照其標(biāo)準(zhǔn)規(guī)格(接口)所實(shí)現(xiàn)出來(lái)的產(chǎn)品,或簡(jiǎn)稱實(shí)現(xiàn)品。用軟件的術(shù)語(yǔ)來(lái)說(shuō),這些實(shí)現(xiàn)品就是類型——實(shí)現(xiàn)了特定接口的類型。

接口的威力即在于一旦訂出標(biāo)準(zhǔn)規(guī)格,各家廠商便可依照標(biāo)準(zhǔn)接口來(lái)制作各類產(chǎn)品。對(duì)使用者來(lái)說(shuō),好處則是享有多種選擇,因?yàn)樗麄儾粫?huì)被特定廠商的產(chǎn)品綁住;只要他們高興,隨時(shí)可以更換不同的產(chǎn)品,而且通常是即插即用。在軟件的世界里,接口也有同樣的好處:讓類型與類型之間保持寬松耦合,以便提供隨時(shí)抽換實(shí)現(xiàn)類型的彈性。


Null Object 模式

回到電源插座的例子。如果我們將計(jì)算機(jī)的電源線從插座上拔起,它們就只是彼此不再連接而已,計(jì)算機(jī)和插座并不會(huì)因此而著火或爆炸。但是在軟件程序的世界里,若對(duì)象 A 會(huì)調(diào)用對(duì)象 B(對(duì)象 A 依賴對(duì)象 B),而當(dāng)你將對(duì)象 B 移除,亦即對(duì)象 B 不存在時(shí),程序就會(huì)發(fā)生 NullReferenceException 類型的錯(cuò)誤。于是,我們常常會(huì)在程序里面加入檢查對(duì)象參考是否為 null 的邏輯,例如:

      
        if
      
       (anObject != 
      
        null
      
      
        )

    anObject.DoSomething();


      
      
        else
      
      
        

    DoSomethingElse();
      
    

如果在程序中一再重復(fù)寫這些檢查 null 的邏輯,代碼便會(huì)膨脹,而且在解讀程序的主要邏輯時(shí),常常得要跳過(guò)這些檢查邏輯,多少會(huì)形成閱讀代碼的阻礙。針對(duì)此問(wèn)題,我們可以設(shè)計(jì)一個(gè)空的、完全不做任何事的類型,然后在變量有可能是 null 的地方,讓它們指向那個(gè)空的對(duì)象。這種模式叫做 Null Object。

Null Object 的優(yōu)點(diǎn):可減少編寫判斷對(duì)象參考是否為 null 的防錯(cuò)邏輯。但前提是開發(fā)人員得知道有 Null Object 可用,否則還是會(huì)寫出多余的防錯(cuò)代碼。

Null Object 類型通常要實(shí)現(xiàn)某個(gè)接口(或繼承自抽象類型),但實(shí)現(xiàn)代碼完全沒(méi)做任何事,即所有方法都只是個(gè)空殼子,或僅提供無(wú)害的默認(rèn)行為。以程序中常用的 logging(日志)機(jī)制為例,我們可以將寫入日志的操作定義成一個(gè) ILogger 接口,然后依實(shí)際需要實(shí)現(xiàn)不同的 logging 類型,例如用來(lái)將日志訊息輸出至 Console 的 ConsoleLogger。此外,考慮到應(yīng)用程序有時(shí)候可能不需要紀(jì)錄任何訊息,我們可以實(shí)現(xiàn)一個(gè) NullLogger 類型,當(dāng)作 Null Object 使用。結(jié)構(gòu)圖如下。

Dependency Injection 筆記 (3)


底下分別是 ILoger 接口以及 NullLogger 和 ConsoleLogger 類型的代碼:

      
        public
      
      
        interface
      
      
         ILogger

{

    Log(
      
      
        string
      
      
         msg);

}




      
      
        public
      
      
        class
      
      
         NullLogger : ILogger

{

    
      
      
        public
      
      
        void
      
       Log(
      
        string
      
      
         msg)

    {

        
      
      
        //
      
      
         不做任何事
      
      
            }

}




      
      
        public
      
      
        class
      
      
         ConsoleLogger : ILogger

{

    
      
      
        public
      
      
        void
      
       Log(
      
        string
      
      
         msg)

    {

        Console.WriteLine(msg);

    }

}
      
    

?

像底下這個(gè)函式,調(diào)用端只要傳入 ConsoleLogger 對(duì)象,日志訊息就會(huì)輸出至 Console;而當(dāng)調(diào)用端想要停止記錄日志,便可傳入 NullLogger 對(duì)象。如此一來(lái),就不用在每次寫入日志訊息時(shí)都重復(fù)寫一遍檢查 logger 對(duì)象是否為 null 的防錯(cuò)邏輯。

      
        void
      
      
         DoSomething(ILogger logger)

{



    logger.Log(
      
      
        "開始執(zhí)行
      
      
         DoSomething 函式。
      
      
        "
      
      
        );

    ....

}
      
    

?

Note: ?Null Object 本身并不需要「進(jìn)化」成真正有做事的對(duì)象,因?yàn)樗拇嬖诰褪菫榱颂峁┮粋€(gè)完全不做任何事、不具任何意義的對(duì)象。
?

Decorator 模式

一般情況下,如果在使用計(jì)算機(jī)時(shí)突然停電了,尚未儲(chǔ)存的數(shù)據(jù)就會(huì)消失不見。為了解決此問(wèn)題,我們可以在墻壁的電源插座與計(jì)算機(jī)電源線之間加入一個(gè)不斷電系統(tǒng)(UPS)。此時(shí),UPS 的電源線會(huì)接在墻壁的電源插座上,而計(jì)算機(jī)的電源則改接在 UPS 上。此三者在串接的時(shí)候,都是通過(guò)單一的標(biāo)準(zhǔn)接口:插座。類似這種通過(guò)同一接口來(lái)串接多個(gè)不同對(duì)象的作法,叫做Decorator Pattern(裝飾模式)。此模式可以讓我們?yōu)閷?duì)象層層迭加新的功能上去,而無(wú)須修改現(xiàn)有的類型。下圖為 Decorator 模式 的結(jié)構(gòu)圖。
?
Dependency Injection 筆記 (3)
?

延續(xù)前面的 logging 范例,假設(shè)想要在每次輸出 log 訊息時(shí)額外加上當(dāng)時(shí)的日期時(shí)間,而且前提是不可修改現(xiàn)有的 ILogger 和 ConsoleLogger 類型,該怎么做?

我們可以使用 Decorator 模式。作法為:設(shè)計(jì)一個(gè)新的類型,此類型不僅要實(shí)現(xiàn) ILogger 接口,而且還需要使用現(xiàn)有的 ConsoleLogger 對(duì)象來(lái)輸出 log 訊息。簡(jiǎn)單起見,我就把這個(gè)類型命名為 DecoratedLogger。代碼如下:

?
          
            public
          
          
            class
          
          
             DecoratedLogger : ILogger

{

    
          
          
            private
          
          
             ILogger logger;

 

    
          
          
            public
          
          
             DecoratedLogger(ILogger aLogger)

    {

        logger 
          
          =
          
             aLogger;

    }

 

    
          
          
            public
          
          
            void
          
           Log(
          
            string
          
          
             msg)

    {

        logger.Log(DateTime.Now.ToString() 
          
          + 
          
            "
          
          
             - 
          
          
            "
          
           +
          
             msg);

    }

}
          
        

?

下圖描繪了這個(gè)簡(jiǎn)略版本的 Decorator 模式范例的類型結(jié)構(gòu):
?
Dependency Injection 筆記 (3)
?
于是,在客戶端程序中使用這個(gè)新的 DecoratedLogger 來(lái)輸出 log 訊息時(shí),可以這么寫:
?
          
            void
          
          
             DoSomething()

    {

        ILogger logger 
          
          = 
          
            new
          
           DecoratedLogger(
          
            new
          
          
             ConsoleLogger());

        logger.Log(
          
          
            "
          
          
            Hello, 裝飾模式!
          
          
            "
          
          
            );

    }
          
        

?

你可以看到,在這次的修改當(dāng)中,現(xiàn)有的 ILogger 和 ConsoleLogger 完全沒(méi)有動(dòng)到。我們只增加了一個(gè)新類型(DecoratedLogger),就為應(yīng)用程序加上了新功能。這也就符合了第 1 章提過(guò)的 OCP(開放/封閉原則)。
?
(摘自:《 .NET?依賴注入 》)
?

Dependency Injection 筆記 (3)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 亚洲人在线视频 | 国产69精品久久久久999小说 | 91福利小视频 | 天天摸天天爽天天澡视频 | 亚洲综合色一区二区三区另类 | 国产精品丝袜视频 | 日韩久久精品电影 | 日本粉嫩一区二区三区视频 | 久久精品呦女 | 九九热视频在线观看 | 国产欧美成人 | 日韩精品一区二 | 天天操夜夜摸 | 成人精品一区二区三区校园激情 | 中文久久 | 亚洲欧洲精品成人久久曰影片 | 一区二区三区高清在线观看 | 米奇7777狠狠狠狠视频 | 国产精品天堂 | 欧美在线视频一区二区 | 国产精品久久久久久久一区探花 | 欧美在线国产 | 亚洲综合视频网 | 欧美日韩国产欧美 | 欧美亚洲欧美区 | 久久精品国产一区二区三区不卡 | 国产精品美女久久久久aⅴ国产馆 | 日本一级特黄a大片在线 | 成人午夜视频在线观看 | 亚洲成a人v在线观看 | 国产高清在线视频 | 亚洲欧美精品中字久久99 | 久久九 | 日日拍夜夜嗷嗷叫视频 | www一区 | 丝袜久久 | 欧美a一级大片 | 色婷婷社区 | 成人高清视频免费观看 | 亚洲国产在 | 国产精品久久久久久久久免费相片 |