設(shè)計(jì)模式之禪(五) -- 開閉原則

定義

開閉原則的定義就是一個(gè)軟件實(shí)體如類、模塊和函數(shù)應(yīng)該對擴(kuò)展開放,對修改關(guān)閉

含義

  • 在設(shè)計(jì)時(shí)盡量適應(yīng)變化,已提高項(xiàng)目的穩(wěn)定性和靈活性
  • 盡量通過擴(kuò)展軟件實(shí)體行為實(shí)現(xiàn)變化,而不是通過修改已有的代碼實(shí)現(xiàn)

實(shí)例

public interface IBook {

    String getName();

    int getPrice();

    String getAuthor();
}

public class NovelBook implements IBook {
    private String name;

    private int price;

    private String author;

    public NovelBook(String name, int price, String author) {
        this.name = name;
        this.price = price;
        this.author = author;
    }

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

    @Override
    public int getPrice() {
        return this.price;
    }

    @Override
    public String getAuthor() {
        return this.author;
    }
}

public class BookStore {
    private final static ArrayList<IBook> bookList = new ArrayList<>();

    static {
        bookList.add(new NovelBook("天龍八部", 3200, "金庸"));
        bookList.add(new NovelBook("巴黎圣母院", 5600, "雨果"));
        bookList.add(new NovelBook("悲慘世界", 3500, "雨果"));
    }

    public static void main(String[] args) {
        NumberFormat format = NumberFormat.getCurrencyInstance();
        format.setMaximumFractionDigits(2);
        System.out.println("書店賣出去的書籍記錄如下");
        for (IBook book : bookList) {
            System.out.println("書籍名稱:" + book.getName() + "\t書籍作者:" +
                    book.getAuthor() + "\t書籍價(jià)格:" + book.getPrice() / 100 + "元");
        }
    }
}

我們以書店銷售書為例,書籍目前有三個(gè)方法,現(xiàn)在書籍需要增加一個(gè)折扣方法,專門進(jìn)行打折處理,如果直接在NovelBook的getPrice方法上修改,就會影響到老邏輯,另外如果折扣價(jià)是對一部分人開放,這種方式就不行。我們換另一種方式去做,如下所示:


public class OffNovelBook extends NovelBook {
    
    public OffNovelBook(String name, int price, String author) {
        super(name, price, author);
    }
    
    @Override
    public int getPrice() {
        int selfPrice = super.getPrice();
        int offPrice = 0;
        if (selfPrice > 4000) {
            offPrice = selfPrice * 90 / 100;
        } else {
            offPrice = selfPrice * 80 / 100;
        }
        return offPrice;
    }
}

public class BookStore {
    private final static ArrayList<IBook> bookList = new ArrayList<>();

    static {
        bookList.add(new OffNovelBook("天龍八部", 3200, "金庸"));
        bookList.add(new OffNovelBook("巴黎圣母院", 5600, "雨果"));
        bookList.add(new OffNovelBook("悲慘世界", 3500, "雨果"));
    }

    public static void main(String[] args) {
        NumberFormat format = NumberFormat.getCurrencyInstance();
        format.setMaximumFractionDigits(2);
        System.out.println("書店賣出去的書籍記錄如下");
        for (IBook book : bookList) {
            System.out.println("書籍名稱:" + book.getName() + "\t書籍作者:" +
                    book.getAuthor() + "\t書籍價(jià)格:" + book.getPrice() / 100 + "元");
        }
    }
}

我們通過增加一個(gè)子類完成了擴(kuò)展,就就是對擴(kuò)展開放,對修改關(guān)閉的一種體現(xiàn)。

使用必要性

  • 開閉原則對測試的影響
  • 開閉原則可以提高復(fù)用性
  • 開閉原則可以提高可維護(hù)性
  • 面向?qū)ο箝_發(fā)的要求

總結(jié)與思考

設(shè)計(jì)模式有六大原則(單一職責(zé),里氏替換原則,依賴倒置,接口隔離,迪米特法則,開閉原則),我們在編程過程中怎么去判斷所寫代碼是否符合六大原則呢?我想有一個(gè)簡單的準(zhǔn)則就是寫的過程當(dāng)中用開閉原則去思考就好了,開閉原則可以更多的理解為是思想,而另五大原則是實(shí)踐這種思想的方法論。我們在編程或CR過程中用開閉原則去審視是否可以用五大原則優(yōu)化代碼,久而久之就會形成良好的代碼風(fēng)格。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容