设计模式之禅——六大设计原则之开闭原则(精神领袖)

”对修改关闭,对拓展开放“。
一个书店卖书的例子,见代码

//书的抽象类(抽象类包括接口和Abstract类)
public interface IBook {
    public String getName();
    public int getPrice();
    public String getAuthor();
}
----------
//书的具体实现类
package com.sdkd.hms;

public class NovelBook implements IBook {

    private String  name;
    private int price;
    private String author;
    public NovelBook(String name, int price, String author) {
        super();
        this.name = name;
        this.price = price;
        this.author = author;
    }   
    @Override
    public String getName() {
        // TODO Auto-generated method stub
        return this.name;
    }


    @Override
    public int getPrice() {
        // TODO Auto-generated method stub
        return this.price;
    }

    @Override
    public String getAuthor() {
        // TODO Auto-generated method stub
        return this.author;
    }

}
----------
//书店类
package com.sdkd.hms;

import java.text.NumberFormat;
import java.util.ArrayList;

public class BookStore {

    private final static ArrayList bookList = new ArrayList();
    static{
        bookList.add(new NovelBook("天龙八部",3200,"金庸"));
        bookList.add(new NovelBook("巴黎圣母",5600,"雨果"));
        bookList.add(new NovelBook("悲惨世界",3500,"雨果"));
        bookList.add(new NovelBook("金瓶梅",2147483647,"兰陵笑笑生"));
    }
    public static void main(String[] args) {
        NumberFormat formatter = NumberFormat.getCurrencyInstance();
        formatter.setMaximumFractionDigits(2);
        System.out.println("----------书店的卖出去的书记录如下-------");
        for(IBook book : bookList){
            System.out.println("书籍名称:" + book.getName() + "\t书籍作者:" + book.getAuthor() + "\t书籍价格" +
                    formatter.format(book.getPrice()/100));
        }
    }

}
/*
----------书店的卖出去的书记录如下-------
书籍名称:天龙八部   书籍作者:金庸 书籍价格¥32.00
书籍名称:巴黎圣母   书籍作者:雨果 书籍价格¥56.00
书籍名称:悲惨世界   书籍作者:雨果 书籍价格¥35.00
书籍名称:金瓶梅    书籍作者:兰陵笑笑生  书籍价格¥21,474,836.00
*/

ok,现在全球经济下滑,书店为了生存开始打折销售:所有40以上的书9折,其他的8这,我们应该如何应对这样一个需求变化?
三种方法:
1、修改接口。在IBook接口中加一个getOffPrice()方法。可是这样你需要修改NovelBook类,你也需要修改main中的方法。嗯….
2、修改实现类。直接在getPrice()中实现打折处理,这个办法挺好的,但是也有缺陷。例如采购书籍人员也是要看价格的,由于该方法已经实现了打折处理价格,因此采购的人看到的也是打折处理价格,这就不太好了,会因信息不对称而出现决策失误的情况
3、通过拓展实现变化

//打折书的具体实现类
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 bookList = new ArrayList();
    static{
        bookList.add(new OffNovelBook("天龙八部",3200,"金庸"));
        bookList.add(new OffNovelBook("巴黎圣母",5600,"雨果"));
        bookList.add(new OffNovelBook("悲惨世界",3500,"雨果"));
        bookList.add(new OffNovelBook("金瓶梅",2147483647,"兰陵笑笑生"));
    }
    public static void main(String[] args) {
        NumberFormat formatter = NumberFormat.getCurrencyInstance();
        formatter.setMaximumFractionDigits(2);
        System.out.println("----------书店的卖出去的书记录如下-------");
        for(IBook book : bookList){
            System.out.println("书籍名称:" + book.getName() + "\t书籍作者:" + book.getAuthor() + "\t书籍价格" +
                    formatter.format(book.getPrice()/100));
        }
    }
}

其实这种方法也是会修改代码,但我们修改的高层模块,对其他的类没有影响~

开闭原则看起来简单,而实际上却需要程序员不断积累经验,从开始设计代码就做好以后修改的准备。只可在经验中收获,不能言传…

不过还是可以告诉你一点:
将变化的部分封装起来;
将不变的部分封装起来

~~~

你可能感兴趣的:(设计模式,设计模式之禅)