大話設計模式之七大原則

設計模式七大原則

設計模式概述

​ 設計模式就是對軟件設計過程中存在的普遍問題,所提出的解決方案。能夠很好的解決一些常見的問題。

​ 設計模式的最終目的就是:高內聚低耦合

  • 代碼重用性:相同功能的代碼,不需要多次編寫
  • 代碼可讀性:編程規範性,便於其他程序員閱讀
  • 代碼可擴展性:當增加新的功能後,對原來功能沒有影響

七大原則

一、單一責任原則

​ 顧名思義,我們設計的類儘量負責一項功能,這樣不容易造成代碼混亂,避免出現一些bug。

反例:

Single類:

public class single{
    public static void main(String[] args){
        People people = new People;
        people.run("老師");
   		people.run("學生");
        people.run("校長");
    }
}

People類:

public class People{
    void run(String type){
        System.out.println(type+"給學生上課");
    }
}

​ 這樣會造成,不管是老師、學生、校長都會調用這個方法,因爲People不止負責了一個功能,所以該設計有問題。

改進

​ 對於上面的例子,我們採用單一職責原則重寫一下,將People拆分成三個類,分別是學生、老師、校長。讓他們負責各自的功能,使其互相不影響。如果想對學生做限制,那麼只需要對學生類進行修改。

優化

​ 或者可以將上面People分爲三個方法,每個方法對應不同的人員,將單一職責落在方法層面而不是類層面

優缺點

優點:

  • 降低類的複雜度,一個類只負責一個職責
  • 提高代碼的可讀性,邏輯清楚明瞭
  • 降低風險,只修改一個類,並不影響其他類的功能

缺點:

  • 代碼增多(可以將單一職責落在方法層面進行優化)

二、接口隔離原則

​ 類不應該依賴不需要的接口,接口儘量小顆粒劃分、如果將多個方法合併爲一個接口,再提供給其他系統使用的時候,就必須實現該接口的所有方法,那些方法是根本不需要的,造成使用者的混淆

三、依賴倒轉原則

  • 高層模塊不應該依賴底層模塊,二者都應該依賴接口或抽象類
  • 其核心就是面向接口編程
  • 依賴倒轉原則主要是基於如下的設計概念:相對於細節的多變性,抽象的東西要更加穩定的多,以抽象爲基礎搭建的框架更加穩定
  • 抽象指接口或抽象類,細節指具體的實現類
反例:
  • 設計圖

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-QaVgzavi-1593420283358)(https://raw.githubusercontent.com/iszhonghu/Picture-bed/master/img/20200629150212.png)]

Potato類

public class Potato{
    public void run(){
        System.out.println("買了土豆");
    }   
}

People類

public class People{
    public void bug(Potato potato){
        potato.run();
    }
}

Test類

public class Test{
    public staticvoid main(String[] args){
        People people = People();
        people.bug(new Potato());
    }
}
改進

​ 上述在反例中,如果不想買土豆,想買其他的蔬菜,就比較麻煩還需要改People方法,這就是代碼中的模塊和模塊之間的耦合性太高。

  • 改進後的設計圖

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-QuXNMN0h-1593420283360)(https://raw.githubusercontent.com/iszhonghu/Picture-bed/master/img/20200629150342.png)]

​ 這樣我們從底層的類抽象出一個接口類,其直接和高層進行交互,而底層的一些類則不參與,這樣能降低耦合度,提高穩定性。

  • Vegetables類
public interface Vegetables{
    public void run();
}
  • Potato類

    public class Potato implements Vegetables{
        public void run(){
            System.out.println("買了土豆");
        }   
    }
    
  • Tomato類

public class Tomato implements Vegetables{
    public void run(){
        System.out.println("買了番茄");
    }
}
  • People類
public class People{
    public void bug(Vegetables vegetable){
        vegetable.run();
    }
}
  • Test類
public class Test{
    public static void main(String[] args){
        People people = new People();
        people.bug(new Potato());
        people.bug(new Tomato());
    }
}
總結

​ 該原則的重點在於”倒轉“,要從底層往上思考,儘量抽象抽象類和接口。此例子很好的解釋了”上層模型不能依賴底層模塊,應該都依賴於抽象“。

四、里氏替換原則

​ 主要是闡述了對繼承extend的一些看法

繼承的優點:

  • 提高代碼的可重用性,子類也有父類的屬性和方法
  • 提高代碼的可擴展性,子類有自己特有的方法

繼承的缺點:

  • 當父類發生改變的時候,要考慮子類的修改

​ 里氏替換原則是繼承的基礎,只有當子類替換父類時,軟件功能仍不受影響,才說明父類真正被複用了。

原則一:

​ 子類必須實現父類的抽象方法,但不得重寫(覆蓋)父類的非抽象的方法

原則二:

​ 子類中可以增加自己特有的方法。

原則三;

​ 當子類覆蓋或實現父類的方法時,方法的前置條件(即方法的形參)要比父類方法的輸入參數更加寬鬆。

五、開閉原則

​ 前面四個原則都是爲了開閉原則做鋪墊,其是最基礎、最重要的設計原則,核心爲對擴展開發,對修改關閉、簡單來說,通過擴展軟件的行爲來實現變化,而不是通過修改來實現。

六、迪米特原則

介紹:
  • 一個對象應該對其他對象保持最少的瞭解。
  • 類與類關係越密切,耦合度越大
  • 一個類對自己依賴的類知道的越少越好。也就是說,對於被依賴的類不管多麼複雜,都儘量將邏輯封裝在類的內部。對外除了提供的public 方法,不對外泄露任何信息
  • 迪米特法則還有個更簡單的定義:只與直接(熟悉)的朋友通信

直接(熟悉)的朋友:每個對象都會與其他對象有耦合關係,只要兩個對象之間有耦合關係, 我們就說這兩個對象之間是朋友關係。耦合的方式很多,依賴,關聯,組合,聚合等。
其中,我們稱出現成員變量,方法參數,方法返回值中的類爲直接的朋友,而出現在局部變量中的類不是直接的朋友。也就是說,陌生的類最好不要以局部變量 的形式出現在類的內部。

七、合成複用原則

  • 儘量使用合成/集合,不要用繼承
  • 如果使用繼承,會使得耦合性加強,儘量作爲方法的輸入參數或類的成員變量,這樣可以避免耦合

最後

  • 如果覺得看完有收穫,希望能給我點個贊,這將會是我更新的最大動力,感謝各位的支持
  • 歡迎各位關注我的公衆號【java冢狐】,專注於java和計算機基礎知識,保證讓你看完有所收穫,不信你打我
    友。也就是說,陌生的類最好不要以局部變量 的形式出現在類的內部。

七、合成複用原則

  • 儘量使用合成/集合,不要用繼承
  • 如果使用繼承,會使得耦合性加強,儘量作爲方法的輸入參數或類的成員變量,這樣可以避免耦合

最後

  • 如果覺得看完有收穫,希望能給我點個贊,這將會是我更新的最大動力,感謝各位的支持
  • 歡迎各位關注我的公衆號【java冢狐】,專注於java和計算機基礎知識,保證讓你看完有所收穫,不信你打我
  • 如果看完有不同的意見或者建議,歡迎多多評論一起交流。感謝各位的支持以及厚愛。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章