如何寫出優(yōu)秀的代碼?設(shè)計模式六大原則告訴你

人生一切難題,知識給你答案

溫馨提示:閱讀本文需要4-5分鐘(少量代碼)


今天,我們來解決一個問題:

如何寫出優(yōu)秀的代碼?設(shè)計模式六大原則告訴你

人生一切難題,知識給你答案。


==單一原則==

定義:應(yīng)該有且僅有一個原因引起類的變更。

單一原則適用于接口、類以及方法,對于接口,我們在設(shè)計的時候一定要做到單一,但對于實現(xiàn)類就需要多方面考慮。生搬硬套單一原則會引起類的劇增,給維護帶來非常多的麻煩。而且過分細分類的職責(zé)也會人為地增加系統(tǒng)的復(fù)雜性。

最常見的就是Activity類,如果我們在Activity中進行網(wǎng)絡(luò)請求操作,請求完畢又進行業(yè)務(wù)處理,處理之后通知View的刷新,這樣做的話Activity就會變的十分臃腫,Activity的職責(zé)就是顯示視圖并處理與用戶的交互,如何解決呢?抽離網(wǎng)絡(luò)請求操作與業(yè)務(wù)操作,通過接口回調(diào)通知Activity視圖的變更,推薦使用MVP模式。

對于單一原則,建議是接口一定要做的單一職責(zé),類的設(shè)計盡量做到只有一個原因引起變化。

==開閉原則==

定義:一個軟件實體如類、模塊和函數(shù)應(yīng)該對擴展開放,對修改關(guān)閉。

開閉原則的定義已經(jīng)非常明確地告訴我們:軟件實體應(yīng)該對擴展開放,對修改關(guān)閉,其含義是說一個軟件實體應(yīng)該通過擴展來實現(xiàn)變化,而不是通過修改已有的代碼來實現(xiàn)變化。

比如現(xiàn)有一個類ProductFactory用來生產(chǎn)一堆產(chǎn)品:

public class ProductFactory {
    private final static List<Product> productList=new ArrayList<>();

    static {
        Product product=new Product();
        product.setPrice(10);
        product.setName("產(chǎn)品A");
        productList.add(product);
        product=new Product();
        product.setPrice(10);
        product.setName("產(chǎn)品B");
        productList.add(product);
    }
    
    public List<Product> getProduct(){
        return productList;
    }

}

客戶端通過創(chuàng)建ProductFactory并調(diào)用getProduct方法就可以獲取產(chǎn)品列表,看似非常完美,如果這個時候產(chǎn)品說我想獲取產(chǎn)品A,然后過了幾天由于產(chǎn)品效益不是很高,需要做打折處理,這個時候怎么辦?是在ProductFactory類中新增方法還是直接在該方法中修改?由于業(yè)務(wù)的不斷變化,造成該類被頻繁修改。

使用開閉原則來解決,創(chuàng)建一個接口IProduct,內(nèi)部約定一個規(guī)則:

public interface IProduct {
    List<Product> getProduct();
}

正常產(chǎn)品獲?。?/p>

public class ProductFactory implements IProduct {

    private final static List<Product> productList=new ArrayList<>();

    static {
        Product product=new Product();
        product.setPrice(10);
        product.setName("產(chǎn)品A");
        productList.add(product);
        product=new Product();
        product.setPrice(10);
        product.setName("產(chǎn)品B");
        productList.add(product);
    }

    @Override
    public List<Product> getProduct() {
        return productList;
    }
}

客戶端使用:

public class Client {
    public static void main(String[] args){
        IProduct productFactory=new ProductFactory();
        List<Product> productList=productFactory.getProduct();
    }
}

產(chǎn)品經(jīng)理說我只需要產(chǎn)品A的產(chǎn)品,通過擴展來實現(xiàn):

public class ProductAFactory implements IProduct {

    private final static List<Product> productList=new ArrayList<>();

    static {
        Product product=new Product();
        product.setPrice(10);
        product.setName("產(chǎn)品A");
        productList.add(product);
        product=new Product();
        product.setPrice(10);
        product.setName("產(chǎn)品B");
        productList.add(product);
    }

    @Override
    public List<Product> getProduct() {
        List<Product> list=new ArrayList<>();
        for(Product product:productList){
            boolean isProductA=product.getName().equals("產(chǎn)品A");
            if(isProductA){
                list.add(product);
            }
        }
        return list;
    }
}

客戶端那邊只需要把ProductFactory替換成ProductAFactory即可,即使產(chǎn)品說需要將產(chǎn)品進行打折處理,我們只需要創(chuàng)建打折類實現(xiàn)IProduct并實現(xiàn)getProduct方法進行打折處理。

==里氏替換原則==

定義:所有引用基類(父類)的地方必須能透明地使用其子類的對象。

里氏替換原則告訴我們,在軟件中將一個基類替換成其子類對象,程序?qū)⒉粫a(chǎn)生任何錯誤和異常;反之則不行,如果一個軟件實體使用的是一個子類對象的話,那么它不一定能夠使用基類對象。

子類的所有方法必須在父類中聲明,或子類必須實現(xiàn)父類中聲明的方法。根據(jù)里氏替換原則,為了保證系統(tǒng)的擴展性,在程序中通常使用父類來進行定義。

在運用里氏替換原則時,盡量把父類設(shè)計為抽象類或者接口,讓子類繼承父類或?qū)崿F(xiàn)父接口,并實現(xiàn)在父類中聲明的方法。運行時,子類實例替換父類實例,我們可以方便地擴展系統(tǒng)的功能。

==依賴倒置原則==

定義:高層模塊不應(yīng)該依賴低層模塊,兩者都應(yīng)該依賴于抽象。抽象不應(yīng)該依賴于細節(jié),細節(jié)應(yīng)該依賴于抽象。

在Java中,抽象指接口或者抽象類,兩者都不能直接被實例化。

細節(jié)就是實現(xiàn)類,實現(xiàn)接口或繼承抽象類而產(chǎn)生的就是細節(jié)。

高層模塊就是調(diào)用端,低層模塊就是具體實現(xiàn)類。

依賴倒置的具體表現(xiàn)就是,模塊間的依賴通過抽象發(fā)生,實現(xiàn)類之間不發(fā)生直接依賴關(guān)系,其依賴關(guān)系是通過接口或者抽象類產(chǎn)生的。

如果類與類直接依賴細節(jié),那么就會直接耦合,如此一來當(dāng)修改時,就會同時修改依賴者代碼,限制了可擴展性。

==迪米特原則==

定義:一個軟件實體應(yīng)當(dāng)盡可能少地與其他實體發(fā)生相互作用。

迪米特原則又被稱為最少知識原則,通俗地講,設(shè)計系統(tǒng)時盡量減少對象之間的交互,如果兩個對象之間不必彼此直接通信,那么這兩個對象就不應(yīng)當(dāng)發(fā)生任何直接的相互作用。

如果其中的一個對象需要調(diào)用另一個對象的某個方法,可以通過第三方轉(zhuǎn)發(fā)這個調(diào)用。引入一個合理的第三者來降低現(xiàn)有對象之間的耦合度。

==接口隔離原則==

定義:一個類對另一個類的依賴應(yīng)該建立在最小的接口上。

建立單一接口,不要建立龐大臃腫的接口;盡量細化接口,接口中的方法盡量少。也就是說,我們要為各個類建立專用的接口,而不要試圖建立一個很龐大的接口供所有依賴它的類調(diào)用。

接口盡量小,但要有限度。對接口進行細化可以提高程序設(shè)計的靈活性,但是如果過度的細化,則會造成接口數(shù)量過多,使設(shè)計復(fù)雜化。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容