1. 程式人生 > >設計模式之軟體開發原則(1)開閉原則和依賴倒置原則

設計模式之軟體開發原則(1)開閉原則和依賴倒置原則

開閉原則

定義

所謂開閉原則就是一個軟體實體如類、模組和函式應該對擴充套件開放、對修改關閉。 強呼叫抽象構建框架,實現實現拓展細節。

有優點是提高軟體的複用性和易維護展性。是面向物件的最基本原則。

依賴倒置原則

定義

高層模組不應該依賴底層模組,二者都應該依賴其抽象。 抽象不應該依賴細節:細節應該依賴抽象。 針對介面程式設計,不要針對實現程式設計。

優點

降低耦合提高穩定性,提高程式碼的可讀性和易維護性。減少程式碼在修改時可能造成的風險。

下面我們用程式碼來說明啥是依賴倒置原則

假設我們想實現一個人在學習的需求,我們可以這樣寫

/**
 * @author 楊紅星
 * @version
1.0.0 * @date 2018/11/30 */
public class Redstar { public void studyJava() { System.out.println("redstar 在學習java"); } public void studyFE() { System.out.println("redstar 在學習前端"); } } 複製程式碼

然後有個測試類

/**
 * @author 楊紅星
 * @version 1.0.0
 * @date 2018/11/30
 */
public class RedstarTest
{ public static void main(String[] args) { Redstar redstar = new Redstar(); redstar.studyFE(); redstar.studyJava(); } } 複製程式碼

這時假設我們還想要學習Python那麼我們則需要去修改Redstar這個類。這樣寫法是面向實現程式設計,因為整個Redstar類就是一個實現類。這個redstar類是要經常被修改的。也就拓展性比較差。我們這個RedstarTest類就是應用層(高層模組)的類是依賴於這個Redstar實現類(底層模組)的。因為我們沒有抽象。根據依賴倒置原則高層次的模組不應該去依賴低層次的模組。每次Redstar拓展都要來RedstarTest進行補充。

我們下面開始碼具有依賴倒置的程式碼,首先建立一個介面。這個介面有個學習方法。

/**
 * @author 楊紅星
 * @version 1.0.0
 * @date 2018/11/30
 */
 
public interface ICourse {
    void studyCourse();
}

複製程式碼

下面寫幾個實現類,實現這個介面


public class JavaCourse implements ICourse {

    @Override
    public void studyCourse() {
        System.out.println("redstar在學習Java課程");
    }
}

複製程式碼
public class FECourse implements ICourse {
    @Override
    public void studyCourse() {
        System.out.println("redstar在學習FE課程");
    }

}
複製程式碼

此時我們將Redstar類修改為如下,這裡注意這個方法的型別是用介面型別,不是具體類型別,在呼叫這個方法時,介面型別會根據實體類的型別向下轉型執行具體方法。

/**
 * @author 楊紅星
 * @version 1.0.0
 * @date 2018/11/30
 */
public class Redstar {
    public void studyJava(ICourse iCourse) {
        iCourse.studyCourse();
    }
}

複製程式碼

Test類修改為

/**
 * @author 楊紅星
 * @version 1.0.0
 * @date 2018/11/30
 */
public class RedstarTest {
    public static void main(String[] args) {
        Redstar redstar = new Redstar();
        redstar.studyJava(new JavaCourse());
        redstar.studyJava(new FECourse());
    }
}
複製程式碼

輸出結果為

redstar在學習Java課程
redstar在學習FE課程
複製程式碼

這時如果我們還有其他大的課程想要學習我們可以通過新增ICourse的實現類的方式來新增。 Redstar這個類是不會去動他的。對於想要學習什麼課程我們有RedstarTest類這高層類來自己選擇。 順便提一下我們在RedstarTest類中使用介面方法的方式對ICourse介面的依賴進行注入。我們也可以使用構造器的方式對依賴進行注入。

/**
 * @author 楊紅星
 * @version 1.0.0
 * @date 2018/11/30
 */
public class Redstar {
    private ICourse iCourse;
    public Redstar(ICourse iCourse) {
        this.iCourse = iCourse;
    }

    public void studyJava() {
        iCourse.studyCourse();
    }
}

複製程式碼

此時我們Redstar中就應該這麼寫

/**
 * @author 楊紅星
 * @version 1.0.0
 * @date 2018/11/30
 */
public class RedstarTest {
    public static void main(String[] args) {
        JavaCourse javaCourse = new JavaCourse();
        FECourse feCourse = new FECourse();
        Redstar redstar = new Redstar(javaCourse);
        redstar.studyJava();
        redstar = new Redstar(feCourse);
        redstar.studyJava();
    }
}

複製程式碼

有構造器的方式同樣我們也可以用set 的方式,此時我們的Redstar就要這麼寫了

/**
 * @author 楊紅星
 * @version 1.0.0
 * @date 2018/11/30
 */
public class Redstar {
    private ICourse iCourse;

    public void setiCourse(ICourse iCourse) {
        this.iCourse = iCourse;
    }

    public void studyJava() {
        iCourse.studyCourse();
    }
}

複製程式碼

對應的RedstarTest就要這麼寫了

/**
 * @author 楊紅星
 * @version 1.0.0
 * @date 2018/11/30
 */
public class RedstarTest {
    public static void main(String[] args) {
        JavaCourse javaCourse = new JavaCourse();
        FECourse feCourse = new FECourse();
        Redstar redstar = new Redstar();
        redstar.setiCourse(feCourse);
        redstar.studyJava();
        redstar.setiCourse(javaCourse);
        redstar.studyJava();
    }
}
複製程式碼

好到這裡我們的依賴倒置原則就講完了,總結一下總體原則就是面向介面程式設計,或者說面向抽象程式設計。上面例子中的介面我們也可以使用抽象類來代替。同學們可以使用抽象類模擬一下上面的過程。