定義
軟件實體應當對擴展開放,對修改關閉
Software entities should be open for extension,but closed for modification
軟件實體包含:
- 模塊
- 類與接口
- 方法
強調的是 用抽象
構建框架,用實現
擴展細節。
開閉原則的含義是:當應用的需求改變時,在不修改軟件實體的源代碼或者二進制代碼的前提下,可以擴展模塊的功能,使其滿足新的需求。
作用
開閉原則,是面向對象設計中最基礎的設計原則。可以提高軟件系統的可複用性
及可維護性
。它指導我們如何建立穩定
靈活
的系統。
- 對軟件測試的影響
軟件遵守開閉原則的話,軟件測試時只需要對擴展的代碼進行測試就可以了,因爲原有的測試代碼仍然能夠正常運行。
- 可以提高代碼的可複用性
粒度越小,被複用的可能性就越大;在面向對象的程序設計中,根據原子和抽象編程可以提高代碼的可複用性。
- 可以提高軟件的可維護性
遵守開閉原則的軟件,其穩定性高和延續性強,從而易於擴展和維護。
實現
可以通過“抽象約束、封裝變化
”來實現開閉原則,即通過接口或者抽象類爲軟件實體定義一個相對穩定的抽象層,而將相同的可變因素封裝在相同的具體實現類中。
因爲抽象靈活性好,適應性廣,只要抽象的合理,可以基本保持軟件架構的穩定。而軟件中易變的細節可以從抽象派生來的實現類來進行擴展,當軟件需要發生變化時,只需要根據需求重新派生一個實現類來擴展就可以了。
【例子】課程信息
課程是名稱、價格等信息的組合。學員根據自己需求挑選對應的課程學習,有時候課程也會做些活動進行優惠等。
這些課程的公共特點就可以爲其定義一個抽象類(ICourse),每個具體的課程都是其子類。學員可以根據需求選擇或購買新課程,而不需要修改原代碼。
/**
* @description: 開閉原則 - 接口 - 課程
**/
public interface ICourse {
String getName();
Double getPrice();
}
/**
* @description: 課程-java
**/
public class JavaCourse implements ICourse {
private String name;
private Double price;
public JavaCourse(String name, Double price) {
this.name = name;
this.price = price;
}
@Override
public String getName() {
return this.name;
}
@Override
public Double getPrice() {
return this.price;
}
}
/**
* @description: java 優惠, 對外擴展
**/
public class JavaDiscountCourse extends JavaCourse {
public JavaDiscountCourse(String name, Double price) {
super(name, price);
}
// 違背了里氏替換原則
@Override
public Double getPrice() {
// 8折優惠
return super.getPrice() * 0.8;
}
// 原價
public Double getOriginPrice() {
return super.getPrice();
}
}
例子類圖: