1. 程式人生 > 實用技巧 >設計模式6大原則之【開閉原則】

設計模式6大原則之【開閉原則】

定義

一個軟體實體,如類和函式應該對擴充套件開放,對修改關閉。是軟體設計中最基礎的設計原則,它指導我們如何簡歷穩定靈活的系統,例如我們版本更新,不修改程式碼可以增加新功能。實現開閉原則的核心思想是面向抽象程式設計而不是面向具體的實現

優點

提高軟體系統的可複用性和可維護性

程式碼案例

有如下程式碼,我們有一個介面(ICourer)定義了獲取id、名稱、價格的方法,有實現類(Course)繼承自這個介面,有一個測試方法類(Test),可以打印出資訊

ICourse介面:
public interface ICourse {
    Integer getId();    //獲取課程id
    String getName();    //獲取課程名稱
    Double getPrice();    //獲取課程價格
}
Course類:
public class Course  implements ICourse{
    private Integer id;
    private String name;
    private Double price;

    public Course(Integer id, String name, Double price) {
        this.id = id;
        this.name = name;
        this.price = price;
    }

    public Integer getId() {
        return this.id;
    }

    public String getName() {
        return this.name;
    }

    public Double getPrice() {
        return this.price;
    }
}
Test類:
public class Test {
    public static void main(String[] args) {
        ICourse course = new Course(1,"java入門",299d);
        System.out.println("課程id:"+course.getId()+",課程名稱:"+course.getName()+",課程價格:"+course.getPrice());
    }
}

此時我們執行Test,控制檯會有如下輸出,沒有任何問題

課程id:1,課程名稱:java入門,課程價格:299.0

新需求

我們現在要對課程進行打折活動,全場9折,或者滿200打9折滿300打8折等

  • 我們可以在介面中定義一個方法如 getDiscountPrice,然後實現類實現此方法。這樣做不但修改了介面,而且還修改了實現類,假如實現類有很多個,那我們將修改很多個類,違反了開閉原則
  • 僅在實現類中增加 getDiscountPrice 方法。這樣做就跟上面的效果一樣了

最佳方案

新建一個課程打折類(DiscountCourse),繼承自課程類(Count),並在裡面定義具體的打折方法

這種方案的優點是,我們無需修改底層的類(Course),通過新增類去新增功能,僅在上端呼叫的地方(Test類)做出修改,就可以實現需求。符合對修改關閉,對擴充套件開放的原則。
DiscountCourse:
public class DiscountCourse extends Course{
    public DiscountCourse(Integer id, String name, Double price) {
        super(id, name, price);
    }
    public Double getDiscountPrice(){
        //這裡寫打折的邏輯
        return super.getPrice() * 0.8;
    }
} 
修改Test類:
public class Test {
    public static void main(String[] args) {
        ICourse iCourse = new DiscountCourse(1,"java入門",299d);
        DiscountCourse course = (DiscountCourse)iCourse;   //這
        System.out.println("課程id:"+course.getId()+",課程名稱:"+course.getName()+",課程原價:"+course.getPrice()+",打折後價格:"+course.getDiscountPrice());
    }
}

此時執行Test,會有如下輸出

課程id:1,課程名稱:java入門,課程原價:299.0,打折後價格:239.20000000000002