第一節 依賴倒置設計原則DIP的誕生

從前有一個這樣的業務

代碼編號01 需求:在MSSQLServer數據庫中添加訂單信息

step 1 構建MSSQLServer環境,有添加功能

public class MSSQLServer
{
    public void Insert(){...}
}

setp 2 構建訂單服務,向MSSQLServer環境添加數據

public class OrderService
{
    private MSSQLServer _mssqlServer;

    public Order(MSSQLServer mssqlServer)
    {
        _mssqlServer = mssqlServer;
    }

    public void Add()
    {
        _mssqlServer.Insert();
    }
}

setp 3 整體貫通,實現需求

static void Main()
{
    var mssqlServer= new MSSQLServer();
    var orderService = new OrderService(mssqlServer);
    orderService.Insert();
}

一個呆萌的員工是這樣擴展

代碼編號02 需求變更:改用MySql存儲訂單信息

step 1 構建MySql環境,有添加功能

public class MySql
{
    public void Insert(){...}
}

setp 2 改造訂單服務,向MySql環境添加數據

public class OrderService
{
    private MSSQLServer _mssqlServer;
    private MySql _mySql;

    public Order(MSSQLServer mssqlServer)
    {
        _mssqlServer = mssqlServer;
    }

    public Order(MySql mySql)
    {
        _mySql = mySql;
    }

    public void Add()
    {
        _mssqlServer.Insert();
    }

    public void AddByMySql()
    {
        _mySql .Insert();
    }
}

setp 3 整體貫通,實現需求

static void Main()
{
    var mySql= new MySql();
    var orderService = new OrderService(mySql);
    orderService.InsertByMySql();
}

一個潛力的員工是這樣擴展

代碼編號03 需求變更:改用MySql存儲訂單信息

setp 1 構建數據庫訪問接口

public interface IDataAccess
{
    void Insert();
}

setp 2 實現MySql環境

public class MySqlDataAccess : IDataAccess
{
    public void Insert(){...}
}

setp 3 改造MSSQLServer環境

public class MSSQLServerDataAccess : IDataAccess
{
    public void Insert(){...}
}

setp 4 改造訂單服務,向IDataAccess環境添加數據

public class OrderService
{
    private IDataAccess _dataAccess;

    public Order(IDataAccess dataAccess)
    {
        _dataAccess = dataAccess;
    }

    public void Add()
    {
        _dataAccess .Insert();
    }
}

setp 5 整體貫通,實現需求

static void Main()
{
    var mySql= new MySqlDataAccess();
    var orderService = new OrderService(mySql);
    orderService.Insert();
}

Leader是這樣評價的

首先,02和03兩段代碼都能實現新的需求。

其次,03的代碼比02的代碼,更加的乾淨整潔。尤其是在OrderService中。

第三,02的每一次擴展,涉及到每個部分,包括新的實現方式、OrderService和貫通的部分。但03的每一次擴展,OrderService部分不需要改變。新增或是修改,改變了現有的其他模塊,就有可能出現Bug,如果能儘可能的不改變一些模塊,系統會變的更柔韌。

第四,如果需求要求使用DB2或Oracle來存儲訂單信息。03代碼的實現,毫無疑問的更加容易實現,系統做到了好的擴展性。

第五,如果需求要求使用DB2或Oracle來存儲訂單信息。03代碼的實現,毫無疑問更加簡單,也意味着系統更加高效。

依賴倒置設計原則DIP的誕生

總結:03的實現方式帶來了種種好處。因爲OrderService使用的是存儲的接口,不需要關心是使用哪種存儲的實現方式。OrderService通過IDataAccess接口來耦合具體的實現,不需要耦合MSSQLServer還是MySql,由一種強耦合變成了弱耦合,耦合度降低。

如果把最終使用接口的模塊OrderService定義爲高層模塊,把提供服務實現手段的定義爲底層模塊,總結出:

高層模塊需要其他低層模塊什麼功能,把需求抽象爲一個低層模塊的接口
各種低層模塊的實現按着這個接口去實現

前輩大牛將這句話精煉爲

高層模塊不應該依賴低層模塊,兩者應該依賴於抽象
抽象不應該依賴於實現,實現應該依賴於抽象

這就是依賴倒置設計原則DIP的誕生

生活中的應用

插頭標準規定三插頭的每個插頭的寬度、高度、每兩個插頭間的距離等標準。插座的設計只要能滿足三插頭的標準,其他電器的三插頭按照標準去實現,這樣不管是電視、冰箱還是筆記本的插頭,都可以使用這個插座。

反之插頭也不需要關心用的插座是公牛還是紅牛的。

ATM機的銀行卡插槽只要設計滿足於銀聯卡,就不需要關心取款人用的是工行卡還是農行卡。

USB的接口標準統一後,筆記本上的USB插口可以使用鼠標、鍵盤、U盤、硬盤。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章