开放封闭原则(SCP:Open-Closed Principle)

本文深入解析软件工程中的开放封闭原则,强调软件实体应对扩展开放,对修改封闭,以确保系统的稳定性和灵活性。通过实例说明如何在不影响现有代码的基础上,通过扩展来满足新的需求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

定义

GoF定义

Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.

软件实体(类、模块、函数等)应该对扩展开放,对修改封闭。这个概述是面向对象编程的最基本,也是最重要的一条思想。是其他原则的基础,所以务必要先理解这条原则。

为了理解这个概念,我们以类为示例,通过理解类的定义和类的使用这两个概念,进一步介绍开放和封装的原则。

类的定义

类是对一个事物的状态和行为的定义。在实际的编码过程中,表现为一个类的源文件,比如 Student 类。类的源文件中通过多行代码对类进行细说的定义和实现。

类的使用

当有了类的源文件以后,我们就可以利用这个类生成此类的对象,比如 Student s1 = new Student()

问题描述

很多初级程序员没有意识到的非常重要的一点就是:同一个类可能会有多名不同的开发人员在使用。因此,类在定义好以后,如果发生修改,那么很多时候会引发用到此类的地方都要进行修改。当某些类的使用的场景很多的时候,在项目的很多地方都用上了这些类,那么比较大的变更,会产生连锁反应,导致整个项目都要进行大幅的修改,这对整个项目都是灾难性的。

让我们以JDK为例。大家都知道,在JDK中包括了大量的类,而我们在进行实际的项目开发的过程中都会用到,比如 java.util 这个包中的类相应使用面是最广泛的。如果Java官方对这个类在新一版本中进行修改,比如删除了 System.out.println() 方法,那么相信全球的程序员都要骂娘了。

解析

这就是开放封闭原则诞生的最重要的背景。既然一个类一旦定好以后,就可能会广泛被使用(模块、函数、接口等,只要公开的都是一样),那么就要求其定义的稳定性,即不会发生名称、作用域、参数列表等的变动。因此,一旦发生变化,所有用到的地方都得发生修改。为了实现这个目标,保证其稳定性,SCP提出了两点重要原则:

  • 对修改封闭
    上面的示例已经非常清楚地表明这点。即类的源代码是不能轻易修改(修改包括变更和删除)的。即便在不得已需要修改的情况下,比如一些Bug的修正,也要尽可能最小化变更。举例来说,C#和Java都有 Thread 类,而这个类中也都有个 stop() 方法用于中止线程。然而由于初期设计时的认识水平的限制,在类设计时都未能发现其可能导致的线程死锁的问题。所以,现在两种语言都想移除这个函数。但是由于开放封闭原则,又不能直接删除这个方法,否则,全球使用C#和Java的大量项目都可能因此而无法运行,尤其是一些已经在线上运行的项目。因此,两个官方(微软和Sun),不约而同地都非常慎重地推出一个 desperated 关键字,用于提醒用户,这个类的 stop 方法已经不推荐使用,可能在某个版本中就会被移除,以给用户提前准备时间。从这个示例中,我们可以看到,大公司都修改是多么小心谨慎。也可以看到,对修改封闭这个原则是多么严格和重要。
  • 对扩展开放
    我们知道需求总是不断变化的,所以类的定义一定写好后,迟早会有一天不能满足实际需求,要求进行变更。这时候,我们应该对我们进行使用的类进行扩展,即利用类的继承性从原类中进行派生,然后在派生类中修改相应的属性或方法。在面向对象的语言中,都提供了类或接口的继承和派生,我们可以很容易的地扩展类中进行修改,以满足实际的需求。

总结

在实际的项目设计中, 我们要时刻记住:需求总是变化。实际上,世界上也没有一个软件是永远不变的。因此,我们无论如何设计,都没有办法一劳永逸。这些言论是对软件需求的最经典的认识。从这些描述中,我们可以看出重要一点,即对于软件设计者而言,必须在不需要对原有的系统进行修改的情况下,实现灵活的系统扩展。而实现这一点的重要原则之一就是开放封闭原则。通过封闭,保证现有的设计能够长期稳定运行,通过扩展满足全新的需求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值