編碼依據的準則——七大設計原則(上)

這是我參與新手入門的第3篇文章編程

簡述

咱們總想寫出正確的代碼,而設計原則就是咱們寫出正確代碼可依據的準則。由於,原則是通過長期經驗總結所得出的合理化的現象。設計模式

咱們經常使用的七大設計原則(也稱爲設計模式的七大原則或面向對象的七大設計原則):markdown

  1. 單一職責原則 (Single Responsibility Principle, SRP)
  2. 接口分隔原則 (Interface Segregation Principle, ISP)
  3. 依賴倒轉原則 (Dependence Inversion Principle, DIP)
  4. 組合/聚合複用原則 (Composite/Aggregate Reuse Principle, CARP)
  5. 開放-關閉原則 (Open-Closed Principle, OCP)
  6. 里氏替換原則 (Liskov Substitution Principle, LSP)
  7. 迪米特法則(Law Of Demeter, LoD)

通常地,能夠把這七個原則分紅了如下兩個部分:ide

設計方法:單一職責原則、接口分隔原則、依賴倒置原則、組合/聚合複用原則編碼

設計目標:開閉原則、里氏代換原則、迪米特原則spa

這篇文章先聊聊「設計方法」相關的原則。設計

單一職責原則 (Single Responsibility Principle, SRP)

顧名思義,單一職責原則就是一個類/接口/方法有且僅有一個職責。code

更官方的說法是,單一職責原則規定一個類應該有且僅有一個引發它變化的緣由,不然類應該被拆分(There should never be more than one reason for a class to change)。 能夠這樣理解,若是類職責不「單一」,每一個職責的變化都有各自的緣由。orm

單一職責原則的核心就是控制類的粒度大小、將對象解耦、提升其內聚性對象

遵循單一職責原則有如下優勢:

  1. 下降類的複雜度。一個類只負責一項職責,其邏輯確定要比負責多項職責簡單得多。
  2. 提升類的可讀性。當類遵循單一職責時,你天然很容易知道此類是幹什麼的。
  3. 增長可複用性。若是一個方法是多個職責的,你只想使用其中的一個職責,這個方法就是不可複用的。好比,修改用戶信息。用戶信息有用戶名,信息,密碼,家庭地址等等。若是你把全部的信息修改放到一個方法中,那麼修改密碼功能就不能複用這個方法了。
  4. 下降變動引發的風險。當一個類有多個職責時,你改變其中一個職責,就有可能影響其餘職責。

接口分隔原則 (Interface Segregation Principle, ISP)

概念理解:接口的設計應該遵循最小接口原則,即不能強迫用戶去依賴那些他們不使用的接口。

好比,接口A,定義了三個方法:

public interface A {
    
    void method1();
    
    void method2();
    
    void method3();
}
複製代碼

而類B,只依賴A的兩個方法:

public class B implements A{
    @Override
    public void method1() {
        System.out.println("do method 1");
    }

    @Override
    public void method2() {
        System.out.println("do method 2");
    }

    @Override
    public void method3() {
        // do nothing
    }
}
複製代碼

這樣,A接口就是沒有遵循最小接口原則。按接口分隔原則,就應該將接口拆分紅使B類不會依賴那些他們不使用的接口。

// 將接口A拆成A1和A2
public interface A1 {
    
    void method1();
    
    void method2();
}

public interface A2 {
    
    void method3();
}

// B只須要依賴A1
public class B implements A1{
    @Override
    public void method1() {
        System.out.println("do method 1");
    }

    @Override
    public void method2() {
        System.out.println("do method 2");
    }
}

複製代碼

依賴倒轉原則 (Dependence Inversion Principle, DIP)

依賴倒置原則定義

A. 上層模塊不該該依賴底層模塊,它們都應該依賴於抽象(High level modules should not depend upon low level modules. Both should depend upon abstractions)

B. 抽象不該該依賴於細節,細節應該依賴於抽象(Abstractions should not depend upon details. Details should depend upon abstractions)

什麼是底層模塊?咱們能夠把不可分隔的邏輯(最基礎的方法)當成底層模塊,而組裝或使用他們的邏輯就是上層模塊。「上層模塊和底層模塊都應該依賴於抽象」,能夠用代碼這樣理解:

示例1(不遵循依賴倒置原則):

// 底層模塊
public class LowLevel{
    public void methodLow(){
        System.out.println("底層方法");
    }
}

// 上層模塊,直接依賴底層模塊
public class HighLevel {
    public void methodHigh(LowLevel lowLevel) {
        System.out.println("上層模塊");
        lowLevel.methodLow();
    }
}
複製代碼

示例2(遵循依賴倒置原則)

// 抽象接口
public interface AbstractLevel {
    void method();
}

// 底層模塊依賴抽象
public class LowLevel implements AbstractLevel{
    @Override
    public void method(){
        System.out.println("底層方法");
    }
}

// 上層模塊依賴抽象
public class HighLevel {
    public void methodHigh(AbstractLevel abstractLevel) {
        System.out.println("上層模塊");
        abstractLevel.method();
    }
}
複製代碼

依賴倒轉(倒置)的中心思想就是針對接口編程,不要針對實現編程

組合/聚合複用原則 (Composite/Aggregate Reuse Principle, CARP)

組合/聚合複用原則定義:

組合/聚合複用原則就是在一個新的對象裏面使用一些已有的對象,使之成爲新對象的一部分; 新的對象經過向這些對象的委派達到複用已有功能的目的。

簡單來講就是多用組合,少用繼承。

在面向對象設計中,有兩種基本的辦法能夠實現複用:第一種是經過組合/聚合,第二種就是經過繼承。而兩種方式以「Has-A」(組合)和「Is-A」(繼承)區分。

直接繼承基類,會破壞封裝,由於繼承將基類的實現細節暴露給子類;若是基類的實現發生了改變,則子類的實現也不得不改變。

小結

本篇文章主要介紹了「單一職責原則」、「接口分隔原則」、「依賴倒置原則」、「組合/聚合複用原則」,這些原則能夠理解爲咱們編碼所遵循的方法。而下一篇文章,咱們會介紹「開閉原則」、「里氏代換原則」、「迪米特原則」,這三個原則是咱們編碼所要實現的目標。

相關文章
相關標籤/搜索