对修改关闭,对拓展开放
书店卖书举例:
//书的抽象类(抽象类包括接口和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<IBook> bookList = new ArrayList<IBook>();
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
*/
现在全球经济下滑,书店为了生存开始打折销售:所有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<IBook> bookList = new ArrayList<IBook>();
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));
}
}
}
其实这种方法也是会修改代码,但我们修改的高层模块,对其他的类没有影响
开闭原则看起来简单,而实际上却需要程序员不断积累经验,从开始设计代码就做好以后修改的准备。只可在经验中收获,不能言传…
不过还是可以告诉你一点:
将变化的部分封装起来;
将不变的部分封装起来