依賴倒置原則和依賴注入模式

來源:互聯網
上載者:User

昨天讀完了程傑的《大話設計模式》。。收穫頗豐。深刻感到了設計模式的偉大。。對面向介面的編程也理解了不少。剛好看到codeproject上一篇將依賴倒置的。講到了依賴注入的方式。仔細讀了一下。翻譯一遍加深認識。

高耦合的代碼隨著項目複雜性的不斷增加,最終會變成一碗碗的意大利麵條啦。。二者通常是軟體設計上的問題,如果一個類對另一個類的實現瞭解太多。當該類改變的時候會引起更多的改變。這違反了依賴倒置原則

而松耦合的代碼設計優良。隨著時間流逝,代碼複雜兩增大,松耦合的好處會變得更加清晰,依賴注入模式是實現松耦合的一個好的辦法,本文介紹在沒有依賴注入容器的情況下實現依賴注入

GoF說了,依賴倒置的原則:

高層模組不應依賴於低層模組,他們都應該依賴於抽象
抽象不依賴細節,細節依賴抽象

剛開始寫依賴倒置比較難,隨著經驗增長會有所改善,通過使高層模組依賴於抽象,依賴倒置成功解耦,依賴注入模式是該原則的一個實現。

通常我們寫出如下的代碼:

public class Email{    public void SendEmail()    {        // code    }}public class Notification{    private Email _email;    public Notification()    {        _email = new Email();    }    public void PromotionalNotification()    {        _email.SendEmail();    }}

 

Notification類依賴Email類,這違反了DIP,而且當我們要傳送簡訊/儲存到資料庫的時候,我們還要改變Notification類。
我們使用抽象類別/介面解耦

public interface IMessageService{    void SendMessage();}public class Email : IMessageService{    public void SendMessage()    {        // code    }}public class Notification{    private IMessageService _iMessageService;    public Notification()    {        _iMessageService = new Email();    }    public void PromotionalNotification()    {        _iMessageService.SendMessage();    }}

 

IMessageService 是一個介面,而Notification 類只要調用介面的方法/屬性就可以了
同時,我們把Email對象的構造移到Notification 類外面去。

依賴注入模式可以實現。通常有三種方式
1. 構造器注入
2. 屬性注入
3. 方法注入

構造器注入
最普遍的方式,當一個類需要另一個類的依賴的時候,我們通過建構函式來提供,現在我們這樣寫

public class Notification{    private IMessageService _iMessageService;    public Notification(IMessageService _messageService)    {        this._iMessageService = _messageService;    }    public void PromotionalNotification()    {        _iMessageService.SendMessage();    }}

 

有幾個好處:1.建構函式實現很簡單,Notification類需要知道的很少。想要建立Notification執行個體的時候看建構函式就可以知道需要什麼資訊了。因此實現了松耦合。

屬性注入

屬性注入/setter注入比較不常見,當依賴可有可無的時候很有用。我們暴露一個可寫的屬性,允許客戶提供不同的依賴實現,比如這樣。

public class Notification{    public IMessageService MessageService    {        get;        set;    }    public void PromotionalNotification()    {        if (MessageService == null)        {            // some error message        }        else        {            MessageService.SendMessage();        }    }}

 

沒有了建構函式。而用屬性來替換,在PromotionalNotifications 方法裡我們需要檢查MessageService的值或者提供相應的服務。

方法注入
當依賴可以對於每個方法調用都不同的時候,我們可以通過一個方法參數來實現,比如我們的這個類還可以傳送簡訊。我們就要使用方法注入

public class Email : IMessageService{    public void SendMessage()    {        // code for the mail send    }}public class SMS : IMessageService{    public void SendMessage()    {        // code for the sms send    }}public class Notification{    public void PromotionalNotification(IMessageService _messageService)    {        _messageService.SendMessage();    }}

 

IMessageService 介面在兩個類中都實現了。我們可以提供不同的類對象作為參數,這樣可以有不同的調用效果。我們可以使用這三種方法實現松耦合。取決於具體的情景

結論
不難吧。通過構造器注入我們就可以降低耦合度了。因此,程式員一般會使用構造器注入。當然也可以混合著使用嘛。。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.