設計模式之軟體開發原則(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();
}
}
複製程式碼
好到這裡我們的依賴倒置原則就講完了,總結一下總體原則就是面向介面程式設計,或者說面向抽象程式設計。上面例子中的介面我們也可以使用抽象類來代替。同學們可以使用抽象類模擬一下上面的過程。