java程序設計原則知多少

程序設計七大原則

1、開閉原則

​ 針對咱們設計的功能模塊對擴展開放,對修改關閉:利用面向接口(抽象)編程(多態的特性),實現對功能需求擴展的同時,不容許更改原來的代碼。提升對象的可複用性、可維護性、靈活性。html

​ 抽象的說,用抽象思惟構建咱們想要建立的實體對象,用具體實現去擴展實體對象的細節實現。java

​ 具體的說,業務需求的功能能夠去擴展,可是已經實現的功能不該該去修改。程序員

  • 需求:以簡單工廠模式和工廠方法模式理解開閉原則spring

  • 分析:編程

    1. 工廠模式是獲取一個實例對象的建造者模式,咱們不關心對象如何產生,只關心結果。app

    2. 簡單工廠模式是面對比較簡單的業務場景,用於獲取一個對象實例。咱們須要傳入相關業務參數,讓簡單工廠對象去作相應的判斷,而後返回給咱們對應的實例對象。這個工廠對象作了不少事情,他違背了單一職責原則,當咱們的業務須要擴展的時候,這個工廠對象必須去修改,新增業務判斷,新增返回對應的實例對象。這就違背了開閉原則ide

      public class FruitsFactory {
      
          /**
           * @description: 
           * @param fruitsName
           * @return com.lmc.gp13280.pattern.factory.fruits.IFruits
           * @date 2019/5/23 15:44
           * @author lmc
           */
          public IFruits product(String fruitsName){
      
              if(null != fruitsName && fruitsName != ""){
                  System.out.println("客戶需求的水果是"+fruitsName);
                  if("蘋果".equals(fruitsName)){
                      System.out.println("水果工廠生產了蘋果");
                      return new Apple();
                  }
                  if("橙子".equals(fruitsName)){
                      System.out.println("水果工廠生產了橙子");
                      return new Orange();
                  }
                  if("香蕉".equals(fruitsName)){
                      System.out.println("水果工廠生產了香蕉");
                      return new Banana();
                  }
                  return null;
              }else{
                  return null;
              }
          }
      }

      上面是一個水果工廠,我若是想要草莓,就必須的修改代碼去實現草莓的生產了。工具

    3. 工廠方法模式是抽象一個工廠接口,讓具體的工廠子類實例對象實現工廠接口。咱們想要一個具體的實例對象,只須要找相應的子類工廠實現類就能夠了,若是須要業務擴展,咱們不須要修改原來的工廠子類,只須要新增新的工廠子類就好了。這就實現了業務擴展,可是不會修改原來的程序邏輯。遵循了開閉原則單一職責原則測試

      public interface IFruitsFactory {
          /**
           * 工廠的生產方法
           * @return IFruits
           */
          IFruits product();
      
      }
      public class AppleFactory implements IFruitsFactory {
          @Override
          public IFruits product() {
      
              System.out.println("蘋果工廠只生產蘋果");
              return new Apple();
          }
      }
      public class BananaFactory implements IFruitsFactory {
          @Override
          public IFruits product() {
              System.out.println("香蕉工廠只生產香蕉");
              return new Banana();
          }
      }
      public class OrangeFactory implements IFruitsFactory {
          @Override
          public IFruits product() {
              System.out.println("橙子工廠只生產橙子");
              return new Orange();
          }
      }

      上面的示例代碼中,咱們要新增具體的水果工廠去擴展業務,只須要新增對應的工廠子類去實現水果工廠的接口就好了。ui

    4. 實現業務擴展,不改變原來的程序就是遵循開閉原則。

2、依賴倒置原則

​ spring的依賴注入相信你們都不陌生,其實依賴倒置原則是程序對象依賴其餘對象的時候,應該依賴其抽象,不要依賴實現,應該依賴頂層對象,不要依賴具體的底層對象。由於程序的具體實現都是實現類去實現的,可是咱們要去依賴實現類的頂層接口對象,這就是倒置,也就是依賴倒置。

依賴倒置原則的核心是運行時多態,程序在編譯時不會去實例化子類對象,在程序運行的時候虛擬機纔會去選擇實例化具體的子類對象。

​ 在程序設計中,通常接口定義好了,就不會去輕易改變。由於,在一個成熟的系統中,改變接口,就至關於把設計推翻重構了,你願意作這樣的事情?可是實現類,我們能夠進行輕微改動,或者說不改,新增一個新的實現類去代替。若是依賴其實現類,只要實現類改動,那麼程序員的災難是否是來了呢?若是依賴其頂層接口,咱們其餘依賴此接口的代碼都不須要去作任何改動,由於接口沒變啊,只須要改動需求具體的實現業務邏輯,或者新增業務子類實現接口。是否是能夠提早下班了

​ 經過依賴倒置,能夠減小類與類之間的耦合性,提升系統的穩定性,提升代碼的
可讀性和可維護性,並可以下降修改程序所形成的風險。

/**
 * 水果店 
 * @author: maocheng.liao
 * @create: 2020-02-23 15:20
 */
public class FruitShop {

    private IFruitsFactory fruitsFactory;

    public IFruitsFactory getFruitsFactory() {
        return fruitsFactory;
    }

    public void setFruitsFactory(IFruitsFactory fruitsFactory) {
        this.fruitsFactory = fruitsFactory;
    }
    /**
     * @description:
     * @param :從水果生產基地去進貨水果
     * @return com.lmc.gp13280.pattern.factory.fruits.IFruits
     * @date 2020/2/23 15:34
     * @author maocheng.liao
     */
    public IFruits getFruits(){
        IFruits fruits = fruitsFactory.product();
        return fruits;
    }
}
/**
 * 水果店依賴倒置測試
 *
 * @author: maocheng.liao
 * @create: 2020-02-23 15:25
 */
public class FruitShopTest {
    public static void main(String[] args) {

        IFruitsFactory fruitsFactory= new AppleFactory();
        FruitShop fruitShop=new FruitShop();
        fruitShop.setFruitsFactory(fruitsFactory);
        IFruits apple = fruitShop.getFruits();
        apple.getName();

        fruitsFactory = new BananaFactory();
        fruitShop.setFruitsFactory(fruitsFactory);
        IFruits banana = fruitShop.getFruits();
        banana.getName();

        fruitsFactory = new OrangeFactory();
        fruitShop.setFruitsFactory(fruitsFactory);
        IFruits orange = fruitShop.getFruits();
        orange.getName();
    }
}

上面的代碼就是最簡單的依賴倒置的實現,咱們依賴的是水果工廠接口和水果接口,水果店是在水果生產基地去進貨水果,至於進貨什麼水果,取決於水果生產基地生產什麼水果和水果店想進什麼水果。而不是依賴具體的水果工廠實現類和具體的水果實現類。

  • 注意:上述部分簡單代碼並未呈現,詳細代碼見博客地址:https://www.cnblogs.com/programmerkaixin/p/10918844.html

3、單一職責原則

​ 我以爲單一職責是迪米特法則的一種體現。

​ 單一職責原則:見名知意,專人作專事,不要多管閒事。對於類、接口、方法只負責一項本身的職責。對於本身的職責程序修改以後,不會影響到其的職責程序。高內聚,低耦合的程序必須遵循單一職責,分工明確,可讀性、可維護性高。

​ 最簡單的示例:我們人的手腳代替不了眼睛,眼睛也代替不了手腳。

​ 臃腫這個詞是否是能很好的體現出單一職責原則呢?代碼寫的這麼臃腫,還能不能好好玩耍啦。

4、接口隔離原則

​ 我以爲接口隔離原則單一職責原則的一種體現,也是迪米特法則的一種體現。

​ 面向對象編程,萬物皆對象。

​ 接口隔離原則:定義多個細化而明確分工的專門接口,不要去定義一個單一臃腫的接口。對於臃腫的接口,咱們很差具體實現,這樣確定會違背單一職責原則

​ 最簡單的示例:對於家用小汽車對象來講,往大的說,他屬於交通工具類、他屬於車類、它屬於汽車類。往小的說,它屬於家用小汽車類、私家車類。

5、迪米特法則

​ 迪米特法則又叫最少知道原則,也有單一職責和接口隔離原則的味道

​ 迪米特法則:低耦合,如何作到極致呢,那就是隻依賴本身真正有關係的對象。在我職責以外的對象所有拒之門外。

​ 我以爲這個沒啥好說的,作到了單一職責,迪米特法則很好實現吧。

6、里氏替換原則

​ 官方定義:任何基類(父類)能夠出現的地方,子類必定能夠出現。 里氏替換原則是繼承複用的基石,只有當衍生類能夠替換掉基類,軟件單位的功能不受到影響時,基類才能真正被複用,而衍生類也可以在基類的基礎上增長新的行爲。當一個子類的實例應該可以替換任何其超類的實例時,它們之間才具備is-A關係。

​ 本人理解: 里氏替換原則是爲了約束繼承氾濫,就是說,在面向對象程序設計中,必須具備is-A的關係才能去使用繼承,而不能去爲了實現某一業務需求,爲了方便使用繼承而繼承。

​ 前置條件:每一個方法調用以前,該方法應該校驗傳入參數的正確性,只有正確才能執行該方法,不然認爲調用方違反契約,不予執行。這稱爲前置條件(Pre-condition)。

​ 後置條件:一旦經過前置條件的校驗,方法必須執行,而且必須確保執行結果符合契約,這稱之爲後置條件(Post-condition)。也就是返回值符合。

​ 里氏替換原則約束條件:當存在繼承關係時,子類中方法的前置條件必須與超類中被覆蓋的方法的前置條件相同或者更寬鬆;而子類中方法的後置條件必須與超類中被覆蓋的方法的後置條件相同或者更爲嚴格

​ 不要爲了繼承而繼承,而是真的有繼承關係的時候才能去繼承。

7、合成複用原則

​ 這裏結合依賴倒置原則使用合成複用原則效果更佳

​ 組合(has-a):類比電腦組裝,內存、硬盤、cpu、顯卡 ······ 它們之間組成了電腦,可是他們之間沒有什麼關係。這就是組合關係,生命週期一致。

​ 聚合(contanis-a):類比員工聚合成部門。員工和部門是相互獨立的,一兩個員工離職不影響部門對象。部門解散也不影響員工對象。

​ 合成複用原則:程序複用儘可能使用組合關係、聚合關係。儘可能少使用繼承關係去實現業務需求。

​ 繼承會把全部的實現所有暴露給子類。破壞了類的封裝性,父類的改變,會影響子類。高耦合。

​ 組合、聚合能夠很好的遵循依賴倒置原則,開閉原則。成員對象的細節實現(組合、聚合對象)對於一個新的對象是隱藏的。

​ 合成複用原則配合依賴倒置原則,很好的遵循開閉原則。達到程序高可用、高可維、高可讀。

​ spring爲何這麼牛?spring爲何依賴注入?spring爲何是輕量級的?

相關文章
相關標籤/搜索