一. 开闭原则的定义
0.开闭原则是由波兰特·梅耶在1988年的著作《面向对象软件构造》中提出,
1.开闭原则(Open Closed Principle,OCP),是编程中最基础的、最重要的原则,设计模式的目的就是遵循开闭原则;
2.软件实体(项目中划分出的模块、类与接口 和 方法函数),应该 对扩展开放(对提供方),对修改关闭(对使用方),用抽象构建框架,用实现扩展细节;
3.当应用需求改变时,在不修改软件实体的源代码前提下,可扩展模块功能使其满足新的需求,新的或改变的特性,应通过新建不同的类实现,
新建的类可通过继承的方式来重写原类的代码;(让程序更稳定、更灵活)。
二.开闭原则的作用
1. 对软件测试的影响
软件遵守开闭原则的话,软件测试时只需要对扩展的代码进行测试就可以了,因为原有的测试代码仍然能够正常运行。
2. 可以提高代码的可复用性
粒度越小,被复用的可能性就越大;在面向对象的程序设计中,根据原子和抽象编程可以提高代码的可复用性。
3. 可以提高软件的可维护性
遵守开闭原则的软件,其稳定性高和延续性强,从而易于扩展和维护。
三.开闭原则的实现方法
1.通过“抽象约束、封装变化”来实现开闭原则
2.参数类型,引用对象尽量使用接口或抽象类,而不是现实类;
3.通过接口或抽象类为软件实体定义一个相对稳定的抽象层,一旦确定就不允许修改;
4.将相同的变化封装到一个接口或抽象类中;
5.将不同的变化封装到不同的接口或抽象类中;
因为抽象灵活性好,适应性广,只要抽象的合理,可以基本保持软件架构的稳定。而软件中易变的细节可让抽象派生来的实现类来进行扩展,
当软件需要发生变化时,只需要根据需求重新派生一个实现类实现抽象方法即可,这样使用方的代码就不需要修改了->满足开闭原则。
四.实例--图形编辑器
1.类图
2.相关代码
/**
* 开闭原则
* @author xuezhihui
* @date 2020/11/25 20:53
*/
object Client {
@JvmStatic
fun main(args: Array<String>) {
val g = GraphicEditor()
g.drawShape(Rectangle())
g.drawShape(Circle())
g.drawShape(Triangle())
}
}
/**
* 把创建Shape类做成抽象类,并提供一个抽象的draw方法,让子类去实现即可,
* 这样在我们有新的图形类时,只需让新的图形继承Shape,并实现draw方法即可;
* 使用方的代码就不需要修改了->满足开闭原则
*/
class GraphicEditor {
//接收Shape对象,调用draw()
fun drawShape(s: Shape) {
s.draw()
}
}
//基类
abstract class Shape{
abstract fun draw() //抽象方法,使之对扩展开放
}
class Rectangle: Shape() {
override fun draw() {
println("绘制矩形")
}
}
class Circle : Shape() {
override fun draw() {
println("绘制圆形")
}
}
class Triangle : Shape() {
override fun draw() {
println("绘制三角形")
}
}