亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Dependency Injection 筆記 (3)

系統(tǒng) 1720 0

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

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

?

設計模式梗概

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

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


小引-電器與接口

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

Dependency Injection 筆記 (3)

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

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


Null Object 模式

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

      
        if
      
       (anObject != 
      
        null
      
      
        )

    anObject.DoSomething();


      
      
        else
      
      
        

    DoSomethingElse();
      
    

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

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

Null Object 類型通常要實現(xiàn)某個接口(或繼承自抽象類型),但實現(xiàn)代碼完全沒做任何事,即所有方法都只是個空殼子,或僅提供無害的默認行為。以程序中常用的 logging(日志)機制為例,我們可以將寫入日志的操作定義成一個 ILogger 接口,然后依實際需要實現(xiàn)不同的 logging 類型,例如用來將日志訊息輸出至 Console 的 ConsoleLogger。此外,考慮到應用程序有時候可能不需要紀錄任何訊息,我們可以實現(xiàn)一個 NullLogger 類型,當作 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);

    }

}
      
    

?

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

      
        void
      
      
         DoSomething(ILogger logger)

{



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

    ....

}
      
    

?

Note: ?Null Object 本身并不需要「進化」成真正有做事的對象,因為它的存在就是為了提供一個完全不做任何事、不具任何意義的對象。
?

Decorator 模式

一般情況下,如果在使用計算機時突然停電了,尚未儲存的數(shù)據(jù)就會消失不見。為了解決此問題,我們可以在墻壁的電源插座與計算機電源線之間加入一個不斷電系統(tǒng)(UPS)。此時,UPS 的電源線會接在墻壁的電源插座上,而計算機的電源則改接在 UPS 上。此三者在串接的時候,都是通過單一的標準接口:插座。類似這種通過同一接口來串接多個不同對象的作法,叫做Decorator Pattern(裝飾模式)。此模式可以讓我們?yōu)閷ο髮訉拥有碌墓δ苌先?,而無須修改現(xiàn)有的類型。下圖為 Decorator 模式 的結(jié)構(gòu)圖。
?
Dependency Injection 筆記 (3)
?

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

我們可以使用 Decorator 模式。作法為:設計一個新的類型,此類型不僅要實現(xiàn) ILogger 接口,而且還需要使用現(xiàn)有的 ConsoleLogger 對象來輸出 log 訊息。簡單起見,我就把這個類型命名為 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);

    }

}
          
        

?

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

    {

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

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

    }
          
        

?

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

Dependency Injection 筆記 (3)


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

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

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

【本文對您有幫助就好】

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

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 亚洲成色综合一区二区三区四区 | 久热中文字幕在线精品首页 | 香蕉视频在线免费播放 | 久久中文字幕视频 | 亚洲精品国产v片在线观看 亚洲精品国产啊女成拍色拍 | 久久er国产精品免费观看1 | 香蕉视频一区二区三区 | 久久在精品线影院精品国产 | 久久综合偷偷噜噜噜色 | 午夜色网站 | 最新仑乱免费视频 | 色综合欧美 | 亚洲伊人久久综合一区二区 | 亚洲视频一二区 | 久久亚洲不卡一区二区 | 亚洲精品一区二区三区婷婷月 | 爱爱的免费视频 | 欧美高清在线精品一区 | 欧美123区| 亚洲欧美综合乱码精品成人网 | 在线观看亚洲精品国产 | 久久免费视频7 | a级成人毛片久久 | 国产在线拍| 日本深夜影院 | 亚洲精品二三区伊人久久 | 久热精品免费视频 | 日本一级黄色毛片 | 狠狠色噜噜狠狠狠狠97不卡 | 亚洲欧美一级久久精品 | 久久精品久久精品久久 | 欧美aa一级片 | 天天干视频在线 | 91精品免费观看 | 中文字幕欧美日韩 | 成人久久 | 久久鸭综合久久国产 | 波多野给衣一区二区三区 | 国内自拍 在线播放 网红 | 久久久久国产一级毛片高清板 | 日日操网站 |