定义
software entities like classes, modules and functions should be open for extension but closed for modifications.
一个软件实体应该对扩展开放,对修改关闭。
什么是开闭原则
闭原则的定义已经非常明确告诉我们:软件实体应该对扩展开放,对修改关闭,其含义是说一个软件实体应该通过扩展来实现变化,而不是通过修改已有的代码来实现变化。那什么又是软件实体呢?软实体包括以下部分:
项目或软件产品中按照一个逻辑规则划分的模块
抽象或类
方法
我们思考这样一个问题:一个软件产品只要在生命期内,都会发生变化,变化既然是一个既定的事实,我们就应该在设计时候尽量适应这些变化,以提高项目的稳定性和灵活性,真正实现“拥抱变化” ,开闭原则告诉我们通过尽量通过扩展软件实体的行为来实现变化,而不通过修改来已有的代码来完成变化,它是为软件实体的未来事件而制定的对现行开发设计进行约束的一个原则,我们举例什么是开闭原则,以书店销售书籍为例,类图如下:
IBook 是定义了数据的三个属性:名称、价格和作者,小说类 NovelBook 是一个具体的实现类,所有小说书籍的总称,BookStore 指的是书店,我们先来看 IBook接口:
public interface IBook {
//书籍有名称
public String getName();
//书籍有售价
public int getPrice();
//书籍有作者
public 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;
}
//获得作者是谁
public String getAuthor() {
return this.author;
}
//书籍叫什么名字
public String getName() {
return this.name;
}
//获得书籍的价格
public int getPrice() {
return this.price;
}
}
然后我们看书店是怎么销售书籍的:
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("金瓶梅",4300,"兰陵笑笑生"));
}
//模拟书店买书
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.0)+"元");
}
}
}
注意,我们在 BookStore 中声明了一个静态模块,实现了数据的初始化,这部分应该是从持久层产生的,由持久层工具进行管理。运行结果如下:
------------书店买出去的书籍记录如下:--------------------