Java設計模式(1:軟件架構設計七大原則及開閉原則詳解)


前言

在日常工作中,我們使用Java語言進行業務開發的時候,或多或少的都會涉及到設計模式,而運用好設計模式對於我而言,又是一個比較大的難題。為了解決、克服這個難題,筆主特別開了這個博客來記錄自己學習的筆記和自己的理解,也歡迎對此有興趣的朋友一起來和筆主探討,共同學習。

一、軟件架構設計模式的七大原則

1、開閉原則

對擴展開放,對修改關閉。在程序需要擴展的時候,不能去修改原有的代碼實現一個熱插拔的效果。簡而言之,就是用抽象構建架構,用實現擴展細節。

2、單一職責原則

不要存在多於一個導致類變更的原因。簡單來說,就是一個Class/Interface/Method只負責一項職責

3、依賴倒置原則

這個原則是開閉原則的基礎,是指設計結構代碼時,高層模塊不應該依賴於底層模塊,二者應該依賴於抽象。抽象不應該依賴於細節,細節應該依賴於抽象。即:針對接口編程,依賴於抽象而不依賴於具體

4、接口隔離原則

使用多個接口,而不使用單一的接口,客戶端不應該依賴它不需要的接口。盡量的細化接口的職責,降低類的耦合度

5、迪米特法則

又被成為最少知道原則,指的是一個對象應該對其他對象保持最少的了解。一個實體類應當盡量少地和其他實體之間發生相互作用,使得系統模塊相互獨立。形象來說就是:只和朋友交流,不和陌生人說話。

6、里氏替換原則

如果說實現開閉原則的關鍵步驟就是抽象化,那么基類(父類)和子類的繼承關系就是抽象化的具體實現,所以里氏替換原則就是對實現抽象化的具體步驟的規范。即:子類可以擴展基類(父類)的功能,但不能改變父類原有的功能。

7、合成復用原則

盡量使用對象組合/聚合,而不是使用繼承達到軟件復用的目的。可以使系統更加的靈活,降低類與類之間的耦合度,一個類的變化對於其他類來說影響相對較少。

繼承我們稱之為白箱復用,相當於把實現的細節暴露給子類,組合/聚合 也成為黑箱復用,對類之外的對象是無法獲取到實現細節的。

二、開閉原則詳解

對擴展開放,對修改關閉。在程序需要擴展的時候,不能去修改原有的代碼實現一個熱插拔的效果。簡而言之,就是用抽象構建架構,用實現擴展細節。

光看理論是不行的,這樣的話我們只能是有一個模糊的認識,對具體的細節不太能看得清,我們先來舉一個例子看一看它是怎么使用的:

例:假如我們居住的附近有一個小超市開業了,里面有各種的商品。老板想找你幫忙做一個超市商品的管理系統,那么針對超市眾多商品的情況,我們首先應該會想到創建一個類來顯示商品的基本信息:價格、名稱等, 針對此,我們先來創建一個接口:

/**
 * 商品基本信息 接口
 */
public interface Goods {
    /**
     * 商品的價格
     */
    void getPrice();

    /**
     * 商品的名稱
     */
    void getName();
}

我們發現超市里有薯片販賣,我們再來寫一個薯片的類來實現這個接口,同時標明薯片的名稱和價格:

/**
 * 樂事薯片
 */
public class Crisps implements Goods{
    @Override
    public void getPrice() {
        System.out.println("商品的價格:9.9 RMB");
    }

    @Override
    public void getName() {
        System.out.println("商品的名稱:樂事薯片");
    }
}

老板說以后還會有面包出售,那我們再來創建一個類來表明面包的基本信息:

/**
 * 面包
 */
public class Bread implements Goods{
    @Override
    public void getPrice() {
        System.out.println("商品的價格:5.5 RMB");
    }

    @Override
    public void getName() {
        System.out.println("商品的名稱:面包");
    }
}

等把這一切做好后,老板說因為新店剛剛開業,沒有什么人氣,就想前期通過薯片打折的方式來吸引人氣(薯片打六折),這個時候我們想到的是:

1、修改Crisps類中的getPrice()方法,但這會有一定的風險,可能會影響其他地方的調用結果。那么這個方法就可以pass掉。

2、在Goods接口中再加一個方法獲取打折后的價格,但最后發現Bread類也需要去實現這個方法,但是面包並沒有打折,這就對接口其他的實現類造成了影響,顯然不可取。

3、在Crisps類中再加入一個方法來獲得打折后的薯片價格,但這樣可能會改變Crisps類的結構,可能會造成不必要的麻煩,而且開閉原則的基礎就是:擴展程序的時候不能去修改原有的代碼。那么這個方法也被pass。

4、在增加一個類去繼承Crisps類,在子類中增加一個方法獲取打折后的價格,這樣通過子類我們可以獲取到商品的名稱,打折前的價格,打折后的價格,也不會改變Crisps類原有的結構,符合我們的規范,那我們再來編寫一個類。

/**
 * 薯片的子類
 */
public class CrispsDisCountPrice extends Crisps {

    /**
     * 打折后的價格
     */
    public void getDisCountPrice(){
        System.out.println("打折后的價格:"+ 9.9*0.6 +" RMB");
    }
}

我們來看一下類的結構圖:

Crisps類和Bread類是接口Goods的實現類,而CrispsDisCountPrice類繼承了Crisps類。

寫個測試類測試一下:

public class Test {
    public static void main(String[] args) {
        Bread bread = new Bread();
        CrispsDisCountPrice crisps = new CrispsDisCountPrice();
        bread.getName();
        bread.getPrice();
        crisps.getName();
        crisps.getPrice();
        crisps.getDisCountPrice();
    }
}

結果:

最后

學習設計模式不能只理解於理論,要根據例子理解才能更加的清晰、透徹。接下來的幾篇博客,我會將設計模式剩下的六個原則都一一說明,並舉一例子。講完七大原則后,會重點解析我們常說的23種設計模式。這是我學習記錄的一個過程,謝謝!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM