設計模式之開閉原則示例
阿新 • • 發佈:2021-07-31
以一個關於課程的例子展示開閉原則:
/** * 定義課程介面 */ public interface ICourse { String getName(); // 獲取課程名稱 Double getPrice(); // 獲取課程價格 Integer getType(); // 獲取課程型別 } /** * 英語課程介面實現 */ public class EnglishCourse implements ICourse { private String name; private Double price; private Integer type; public EnglishCourse(String name, Double price, Integer type) { this.name = name; this.price = price; this.type = type; } @Override public String getName() { return null; } @Override public Double getPrice() { return null; } @Override public Integer getType() { return null; } } // 測試 public class Main { public static void main(String[] args) { ICourse course = new EnglishCourse("小學英語", 199D, "Mr.Zhang"); System.out.println( "課程名字:"+course.getName() + " " + "課程價格:"+course.getPrice() + " " + "課程作者:"+course.getAuthor() ); } }
專案上線,課程正常銷售,但是我們產品需要做些活動來促進銷售,比如:打折。那麼問題來了:打折這一動作就是一個變化,而我們要做的就是擁抱變化,現在開始考慮如何解決這個問題,可以考慮下面三種方案:
1、修改介面
在之前的課程介面中新增一個方法 getSalePrice() 專門用來獲取打折後的價格;
如果這樣修改就會產生兩個問題,所以此方案否定
- ICourse 介面不應該被經常修改,否則介面作為契約的作用就失去了
- 並不是所有的課程都需要打折,加入還有語文課,數學課等都實現了這一介面,但是隻有英語課打折,與實際業務不符
public interface ICourse { // 獲取課程名稱 String getName(); // 獲取課程價格 Double getPrice(); // 獲取課程型別 String getAuthor(); // 新增:打折介面 Double getSalePrice(); }
2、修改實現類
在介面實現裡直接修改 getPrice()方法,此方法會導致獲取原價出問題;或新增獲取打折的介面 getSalePrice(),這樣就會導致獲取價格的方法存在兩個,所以這個方案也否定。
3、通過擴充套件實現變化
直接新增一個子類 SaleEnglishCourse ,重寫 getPrice()方法,這個方案對原始碼沒有影響,符合開閉原則,所以是可執行的方案,程式碼如下,程式碼如下:
public class SaleEnglishCourse extends EnglishCourse { public SaleEnglishCourse(String name, Double price, String author) { super(name, price, author); } @Override public Double getPrice() { return super.getPrice() * 0.85; } }
綜上所述,如果採用第三種,即開閉原則,以後再來個語文課程,數學課程等等的價格變動都可以採用此方案,維護性極高而且也很靈活。