面向对象设计原则之开闭原则

一、问题的提出

随着时间的推移,软件的需求会发生变化。当软件系统面对新的需求时,应该保证系统的设计框架是稳定的,尽量减少对原有代码的修改,否则很有可能在修改过程中引入很多新的错误。

如果一个软件设计符合开闭原则,那么可以非常方便地对系统进行扩展,而且在扩展时无需修改现有代码,使得软件系统在拥有适应性和灵活性的同时具有较好的稳定性和延续性。

二、开闭原则分析

1.定义

开闭原则(Open-Closed Principle, OCP):一个软件实体应当对扩展开放,对修改关闭

2.分析

由定义可知,在设计一个模块时,应当使这个模块可以在不被修改的前提下被扩展,即实现在不被修改源代码的情况下改变这个模块的行为。

为了满足开闭原则,需要对系统进行抽象化设计,抽象化是开闭原则的关键。在面向对象编程语言中,可以为系统定义一个相对稳定的抽象层,而将不同的实现行为在具体的实现层中完成。如果需要修改系统的行为,无需对抽象层进行任何改动,只需要增加新的具体类来实现新的业务功能即可,实现在不修改已有代码的基础上扩展系统的功能,达到开闭原则的要求。

开闭原则还可以通过一个更具体的“对可变性封装原则”来描述,对可变性封装原则(Principle of Encapsulation of Variation, EVP)要求找到系统的可变性因素并将其封装起来。如将抽象层的不同实现封装到不同的具体类中,而且EVP要求尽量不要将一种可变性和另一种可变性混合在一起,这将导致系统中类的个数急剧增长,增加系统的复杂度。

三、实例

1.实例说明

某图形界面系统提供了各种不同形状的按钮,客户端代码可针对这些按钮进行编程,用户可能会改变需求要求使用不同的按钮,原始设计方案如图

面向对象设计原则之开闭原则_第1张图片

如果界面类LoginForm需要将圆形按钮(CircleButton)改为矩形按钮(RectangleButton),则需要修改LoginForm类的源代码,修改按钮类的类名,由于圆形按钮和矩形按钮的显示方法不同,因此还需要修改LoginForm类的display()方法实现代码。

面向对象设计原则之开闭原则_第2张图片 

2.使用开闭原则进行重构

分析上述实例,由于LoginForm类面向具体类进行编程,因此每次更换具体类时不得不修改源代码,而且在这些具体类中方法没有统一的接口,相似功能的方法名称不一致。

如果希望系统能够满足开闭原则,需要对按钮类进行抽象化,提取一个抽象按钮类AbstractButton,LoginForm类针对抽象按钮类AbstractButton进行编程,在Java语言中,还可以通过配置文件、DOM解析技术和反射机制将具体类类名存储在排至文件中,再在运行时生成其实例对象。 

面向对象设计原则之开闭原则_第3张图片

重构后,如果需要增加新的按钮类,只需要增加一个新的类型继承抽象类AbstractButton即可,无需修改原有的源代码。

注意:因为xml和properties等格式的配置文件是纯文本文件,可以直接通过记事本进行编辑,且无需编译,因此在软件开发中,一般不把对配置文件的修改认为是对系统源代码的修改。如果一个软件系统在扩展时只涉及修改配置文件,而原有源代码没有做任何修改,该系统即可认为是一个符合开闭原则的系统。 

 

你可能感兴趣的:(java)