一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

淺談 SOLID 原則的具體使用

 KongKong世界 2018-09-26

SOLID 是面向?qū)ο笤O(shè)計5大重要原則的首字母縮寫,當(dāng)我們設(shè)計類和模塊時,遵守 SOLID 原則可以讓軟件更加健壯和穩(wěn)定。那么,什么是 SOLID 原則呢?本篇文章我將談?wù)?SOLID 原則在軟件開發(fā)中的具體使用。

單一職責(zé)原則(SRP)

單一職責(zé)原則(SRP)表明一個類有且只有一個職責(zé)。一個類就像容器一樣,它能添加任意數(shù)量的屬性、方法等。然而,如果你試圖讓一個類實現(xiàn)太多,很快這個類就會變得笨重。任意小的改變都將導(dǎo)致這個單一類的變化。當(dāng)你改了這個類,你將需要重新測試一遍。如果你遵守 SRP,你的類將變得簡潔和靈活。每一個類將負(fù)責(zé)單一的問題、任務(wù)或者它關(guān)注的點,這種方式你只需要改變相應(yīng)的類,只有這個類需要再次測試。SRP 核心是把整個問題分為小部分,并且每個小部分都將通過一個單獨的類負(fù)責(zé)。

假設(shè)你在構(gòu)建一個應(yīng)用程序,其中有個模塊是根據(jù)條件搜索顧客并以Excel形式導(dǎo)出。隨著業(yè)務(wù)的發(fā)展,搜索條件會不斷增加,導(dǎo)出數(shù)據(jù)的分類也會不斷增加。如果此時將搜索與數(shù)據(jù)導(dǎo)出功能放在同一個類中,勢必會變的笨重起來,即使是微小的改動,也可能影響其他功能。所以根據(jù)單一職責(zé)原則,一個類只有一個職責(zé),故創(chuàng)建兩個單獨的類,分別處理搜索以及導(dǎo)出數(shù)據(jù)。


開放封閉原則(OCP)

開放封閉原則(OCP)指出,一個類應(yīng)該對擴(kuò)展開放,對修改關(guān)閉。這意味一旦你創(chuàng)建了一個類并且應(yīng)用程序的其他部分開始使用它,你不應(yīng)該修改它。為什么呢?因為如果你改變它,很可能你的改變會引發(fā)系統(tǒng)的崩潰。如果你需要一些額外功能,你應(yīng)該擴(kuò)展這個類而不是修改它。使用這種方式,現(xiàn)有系統(tǒng)不會看到任何新變化的影響。同時,你只需要測試新創(chuàng)建的類。

假設(shè)你現(xiàn)在正在開發(fā)一個 Web 應(yīng)用程序,包括一個在線納稅計算器。用戶可以訪問Web 頁面,指定他們的收入和費用的細(xì)節(jié),并使用一些數(shù)學(xué)公式來計算應(yīng)納稅額??紤]到這一點,你創(chuàng)建了如下類:

public class TaxCalculator
{
    public decimal Calculate(decimal income, decimal deduction, string country)
    {
        decimal taxAmount = 0;
        decimal taxableIncome = income - deduction;
        switch (country)
        {
            case "India":
                //Todo calculation
                break;
            case "USA":
                //Todo calculation 
                break;
            case "UK":
                //Todocalculation
                break;
        }
        return taxAmount;
    }
}

這個方法非常簡單,通過指定收入和支出,可以動態(tài)切換不同的國家計算不同的納稅額。但這里隱含了一個問題,它只考慮了3個國家。當(dāng)這個 Web 應(yīng)用變得越來越流行時,越來越多的國家將被加進(jìn)來,你不得不去修改 Calculate 方法。這違反了開放封閉原則,有可能你的修改會導(dǎo)致系統(tǒng)其他模塊的崩潰。

讓我們對這個功能進(jìn)行重構(gòu),以符合對擴(kuò)展是開放,對修改是封閉的。



根據(jù)類圖,可以看到通過繼承實現(xiàn)橫向的擴(kuò)展,并且不會引發(fā)對其他不相關(guān)類的修改。這時 TaxCalculator 類中的 Calculate 方法會異常簡單:

public decimal Calculate(CountryTaxCalculator obj)
{
    decimal taxAmount = 0;
    taxAmount = obj.CalculateTaxAmount();
    return taxAmount;
}

里氏替換原則(LSP)

里氏替換原則指出,派生的子類應(yīng)該是可替換基類的,也就是說任何基類可以出現(xiàn)的地方,子類一定可以出現(xiàn)。值得注意的是,當(dāng)你通過繼承實現(xiàn)多態(tài)行為時,如果派生類沒有遵守LSP,可能會讓系統(tǒng)引發(fā)異常。所以請謹(jǐn)慎使用繼承,只有確定是“is-a”的關(guān)系時才使用繼承。

假設(shè)你在開發(fā)一個大的門戶網(wǎng)站,并提供很多定制的功能給終端用戶,根據(jù)用戶的級別,系統(tǒng)提供了不同級別的設(shè)定??紤]到這個需求,設(shè)計如下類圖:


可以看到,ISettings 接口有 GlobalSettings、SectionSettings 以及 UserSettings 三個不同的實現(xiàn)。GlobalSettings 設(shè)置會影響整個應(yīng)用程序,例如標(biāo)題、主題等。SectionSettings 適用于門戶的各個部分,如新聞、天氣、體育等設(shè)置。UserSettings 為特定登錄用戶設(shè)置,如電子郵件和通知偏好。

這樣的設(shè)計沒問題,但如果有另一個需求,系統(tǒng)需要支持游客訪問,唯一區(qū)別是游客不支持系統(tǒng)的設(shè)定,為了滿足這個需求,你可能會如下設(shè)計:

public class GuestSettings : ISettings
{
    public void GetSettings()
    {
        //get settings from database
        //include guest name、ip address...
    }

    public void SetSettings()
    {
        //guests are not allowed set settings
        throw new NotImplementedException();
    }
}

這樣沒問題嗎?準(zhǔn)確來說,系統(tǒng)存在隱患。當(dāng)單獨使用 GuestSettings 時,因為我們了解游客不能設(shè)置,所以我們潛意識并不會主動調(diào)用 SetSettings 方法。但是由于多態(tài),ISettings 接口的實現(xiàn)可以被替換為 GuestSettings 對象,當(dāng)調(diào)用SetSettings 方法時,可能會引發(fā)系統(tǒng)異常。

重構(gòu)這個功能,拆分為兩個不同的接口:IReadableSettings 和 IWritableSettings。子類根據(jù)需求實現(xiàn)所需的接口。


接口隔離原則(ISP)

接口隔離原則(ISP)表明類不應(yīng)該被迫依賴他們不使用的方法,也就是說一個接口應(yīng)該擁有盡可能少的行為,它是精簡的,也是單一的。

假設(shè)你正在開發(fā)一個電子商務(wù)的網(wǎng)站,需要有一個購物車和關(guān)聯(lián)訂單處理機(jī)制。你設(shè)計一個接口 IOrderProcessor,它用包含一個驗證信用卡是否有效的方法(ValidateCardInfo)以及收件人地址是否有效的方法(ValidateShippingAddress)。與此同時,創(chuàng)建一個OnlineOrderProcessor 的類表示在線支付。

這非常好,你的網(wǎng)站也能正常工作。現(xiàn)在讓我們來考慮另一種情形,假設(shè)在線信用卡支付不再有效,公司決定接受貨到付款支付。

乍一看,這個解決方案聽起來很簡單,你可以創(chuàng)建一個CashOnDeliveryProcessor 并實現(xiàn) IOrderProcessor 接口。貨到付款的購買方式不會涉及任何信貸卡驗證,所以,CashOnDeliveryOrderProcessor 類內(nèi)部的 ValidateCardInfo 方法拋出 NotImplementedException。


這樣的設(shè)計在未來可能會出現(xiàn)的潛在問題。假設(shè)由于某種原因在線信用用卡付款需要額外的驗證步驟。自然,IOrderProcessor 將被修改,它將包括那些額外的方法,于此同時 OnlineOrderProcessor 將實現(xiàn)這些額外的方法。然而,CashOnDeliveryOrderProcessor 盡管不需要任何的附加功能,但你必須實現(xiàn)這些附加的功能。顯然,這違反了接口隔離原則。

你需要將這個功能重構(gòu):


新的設(shè)計分成兩個接口。IOrderProcessor 接口只包含兩個方法:ValidateShippingAddress 和 ProcessOrder,而 ValidateCardInfo 抽象到到一個單獨的接口:IOnlineOrderProcessor?,F(xiàn)在,在線信用卡支付的任何改變只局限于IOnlineOrderProcessor 和它的子類實現(xiàn),而 CashOnDeliveryOrderProcessor 是不會被影響。因此,新設(shè)計符合接口隔離原則。

依賴倒置原則(DIP)

依賴倒置原則(DIP)表明高層模塊不應(yīng)該依賴低層模塊,相反,他們應(yīng)該依賴抽象類或者接口。這意味著你不應(yīng)該在高層模塊中使用具體的低層模塊。因為這樣的話,高層模塊變得緊耦合低層模塊。如果明天,你改變了低層模塊,那么高層模塊也會被修改。根據(jù)DIP原則,高層模塊應(yīng)該依賴抽象(以抽象類或者接口的形式),低層模塊也是如此。通過面向接口(抽象類)編程,緊耦合被移除。

那么什么是高層模塊,什么是低層模塊呢?通常情況下,我們會在一個類(高層模塊)的內(nèi)部實例化它依賴的對象(低層模塊),這樣勢必造成兩者的緊耦合,任何依賴對象的改變都將引起類的改變。

依賴倒置原則表明高層模塊、低層模塊都依賴于抽象,舉個例子,你現(xiàn)在正在開發(fā)一個通知系統(tǒng),當(dāng)用戶改變密碼時,郵件通知用戶。

public class UserManager
{

    public void ChangePassword(string username,string oldpwd,string newpwd)
    {
        EmailNotifier notifier = new EmailNotifier();

        //add some logic and change password 
        //Notify the user
        notifier.Notify("Password was changed on "+DateTime.Now);
    }
}

這樣的實現(xiàn)在功能上沒有問題,但試想一下,新的需求希望通過SNS形式通知用戶,那么我們只能手動將EmaiNorifier 替換為 SNSNotifier。在這兒,UserManager 就是高層模塊,而EmailNotifier 就是低層模塊,他們彼此耦合。我們希望解耦,依賴于抽象 INotifier,也就是面向接口的編程。


小結(jié)

轉(zhuǎn)載來自:https://www.cnblogs.com/OceanEyes/p/overview-of-solid-principles.html
本篇博客為大家介紹了面向?qū)ο笤O(shè)計的 SOLID 原則,并以具體的案例輔助講解。你可以看到,繼承和多態(tài)在SOLID 原則中扮演了非常重要的角色。我們的應(yīng)用程序不能過度設(shè)計,當(dāng)然也不能隨意設(shè)計。了解基本的 SOLID 原則能讓你的應(yīng)用程序變得健壯。你可以在Github 上查看具體的示例代碼:https://github.com/MEyes/SOLID.Principles   

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    日韩精品视频一二三区| 性感少妇无套内射在线视频| 成人免费高清在线一区二区| 国产自拍欧美日韩在线观看| 少妇视频一区二区三区| 欧美日韩国产黑人一区| 欧美黄色黑人一区二区| 国产内射在线激情一区| 麻豆最新出品国产精品| 国产精品九九九一区二区| 狠狠干狠狠操亚洲综合| 国内外免费在线激情视频| 亚洲欧美日产综合在线网| 久久精品国产一区久久久| 亚洲国产精品久久综合网| 风韵人妻丰满熟妇老熟女av| 乱女午夜精品一区二区三区| 日韩精品日韩激情日韩综合| 亚洲夫妻性生活免费视频| 91在线爽的少妇嗷嗷叫| 国产成人高清精品尤物| 男人的天堂的视频东京热| 黄片在线免费看日韩欧美| 超碰在线播放国产精品| 精品伊人久久大香线蕉综合| 国产亚洲精品岁国产微拍精品| 一区二区三区四区亚洲另类| 欧美大胆美女a级视频| 久热青青草视频在线观看| 欧美亚洲国产日韩一区二区| 久久99国产精品果冻传媒| 高潮日韩福利在线观看| 午夜福利92在线观看| 欧美日韩国产的另类视频| 99久久精品午夜一区二| 欧美亚洲美女资源国产| 欧美日韩精品一区二区三区不卡| 欧美国产日韩变态另类在线看| 美国女大兵激情豪放视频播放| 亚洲国产香蕉视频在线观看| 久久这里只精品免费福利|