六大设计原则详解(6)-开闭原则
简介:
开闭原则(OCP)是面向对象设计中“可复用设计”的基石,是面向对象设计中最重要的原则之一,其它很多的设计原则都是实现开闭原则的一种手段。对于扩展是开放的,对于修改是关闭的,这意味着模块的行为是可以扩展的。当应用的需求改变时,我们可以对模块进行扩展,使其具有满足那些改变的新行为。也就是说,我们可以改变模块的功能。对模块行为进行扩展时,不必改动模块的源代码或者二进制代码。模块的二进制可执行版本,无论是可链接的库、DLL或者.EXE文件,都无需改动。
软件实体包括:
项目或软件产品中按照一定的逻辑规则划分的模块
抽象和类
方法
下面通过实例来详细了解一下:
现在有个书店售书的场景,首先定义一个IBook类,里面有两个属性:名称、价格。
public interface IBook{ public String getName(); public int getPrice(); }
定义小说类NovelBook-实现类
public class NovelBook implements IBook{ private String name; private int price; public NovelBook(String name,int price){ this.name = name; this.price = price; } public String getName(){ return this.name; } public int getPrice(){ return this.price; } }
下面是Client类
public class Client{ public static void main(Strings[] args){ NovelBook novel = new NovelBook("笑傲江湖",100,"金庸"); System.out.println("书籍名字:"+novel.getName()+"书籍价格:"+novel.getPrice()); } }
下面有个需求需要更改,"如果书籍的价格在50以上,就打九折出售" 对于这样的需求变化,下面有三种方法可以解决:
1.修改接口
在IBook接口中新增一个getDisPrice(),专门用来打折处理,实现类重新实现该接口。这样的修改NoverlBook和Client都要修改,而且接口本身就要求稳定,不能随意修改,所以这个方法不可取。
2.修改实现类
修改NoverlBook类中的方法,直接在房里加入打折的逻辑,但是有个问题,别人很难知道此书是否被打折了,而且写在这里容易造成价格对不上等错误,所以此方法不可取。
3.扩展实现变化
新增一个子类DisNoverlBook类,并覆写getPrice()方法,产生新的对象,修改的代码很少,影响也小。下面是DisNoverlBook类具体代码:
public class DisNovelBook implements NovelBook{
public DisNovelBook (String name,int price){
super(name,price,author);
}
//覆写价格方法,当价格大于50,就打9析
public int getPrice(){
if(this.price > 50){
return this.price * 0.9;
}else{
return this.price ;
}
}
}
在Client中只要修改一下实现类对象就可以了:
public class Client{
public static void main(Strings[] args){
DisNovelBook disnovel = new DisNovelBook ("笑傲江湖",100,"金庸");
System.out.println("书籍名字:"+disnovel .getName()+"书籍价格:"+disnovel .getPrice());
} }
开闭原则对扩展开放,对修改关闭,并不意味着不做任何的修改,底层模块的变更,必然有高层模块进行耦合。
二.如何使用开闭原则
抽象约束
通过接口或者抽象类约束扩展,对扩展进行边界限定,不允许出现在接口或抽象类中不存在的public方法;
参数类型、引用对象尽量使用接口或者抽象类,而不是实现类;
抽象层尽量保持稳定,一旦确定即不允许修改。
元数据(metadata)控制模块行为
元数据就是用来描述环境和数据的数据,通俗地说就是配置参数,参数可以从文件中获得,也可以从数据库中获得。
Spring容器就是一个典型的元数据控制模块行为的例子,其中达到极致的就是控制反转(Inversion of Control)
制定项目章程
在一个团队中,建立项目章程是非常重要的,因为章程中指定了所有人员都必须遵守的约定,对项目来说,约定优于配置。
封装变化
三.为什么使用开闭原则
开闭原则非常有名,只要是面向对象编程,在开发时都会强调开闭原则
开闭原则是最基础的设计原则
开闭原则可以提高复用性
开闭原则可以提高维护性
面向对象开发的要求
推荐阅读