设计模式系列:开闭原则

引入

  “需求总是变化”、“世界上没有一个软件是不变的”,这些言论是对软件需求最经典的表白。从中透射出一个关键的意思就是,对于软件设计者来说,必须在不需要对原有的系统进行修改的情况下,实现灵活的系统扩展。而如何能做到这一点呢?

  只有依赖于抽象。实现开放封闭的核心思想就是对抽象编程,而不对具体编程,因为抽象相对稳定。让类依赖于固定的抽象,所以对修改就是封闭的;而通过面向对象的继承和对多态机制,可以实现对抽象体的继承,通过覆写其方法来改变固有行为,实现新的扩展方法,所以对于扩展就是开放的。这是实施开放封闭原则的基本思路,同时这种机制是建立在两个基本的设计原则的基础上,这就是Liskov替换原则和合成/聚合复用原则。

  对于违反这一原则的类,必须进行重构来改善,常用于实现的设计模式主要有Template Method模式和Strategy模式。而封装变化,是实现这一原则的重要手段,将经常发生变化的状态封装为一个类。

  在我们最初编写代码时,假设变化不会发生。当变化发生时,我们就创建抽象来隔离以后发生的同类变化。比如,之前写的加法程序,你可以很快在一个client类中就完成,此时变化还没有发生。然后我让你加一个减法功能,你发现,增加功能需要修改原来这个类,这就违背了“开放-封闭原则”,于是你就该考虑重构程序,增加一个抽象的运算类,通过一些面向对象的手段,如继承,多态等来隔离具体加法、减法与client耦合,需求依然可以满足,还能应对变化。即面对需求,对程序的改动是通过增加新代码进行的,而不是更新现有的代码。

定义

开闭原则是面对对象的可复用设计的第一块基石,它是最重要的面对对象设计原则。

一个软件实体应该对扩展开发,对修改关闭。即软件实体应尽量在不修改原有代码的情况下进行扩展。

  • 其核心的思想是: 软件实体应该是可扩展,而不可修改的。也就是说,对扩展是开放的,而对修改是封闭的。 因此,开放封闭原则主要体现在两个方面:对扩展开放,意味着有新的需求或变化时,可以对现有代码进行扩展,以适应新的情况。/对修改封闭,意味着类一旦设计完成,就可以独立完成其工作,而不要对类进行任何修改。

  • 为了满足开闭原则,需要对系统进行抽象化设计,抽象化是开闭原则的关键。在java、c#等编程语言中,可以为系统定义一个相对稳定的抽象层,而将不同的实现行为移至具体的实现层中完成。在很多面对对象编程语言中都提供了接口、抽象类等机制,可以通过他们定义系统的抽象层,再通过具体类来进行扩展。如果需要修改系统的行为,无须对抽象层进行任何改动,只需要增加新的具体类来实现新的业务功能即可,实现在不修改已有代码的基础上扩展系统的功能,达到开闭原则的要求。

  • 大部分设计模式都符合开闭原则。

如何使用开闭原则

  开闭原则是一个口号,我们怎么把这个口号应用到实际工作中呢?

1.抽象约束
  通过接口或抽象类可以约束一组可能变化的行为,并且能够实现对扩展开发,其包含三层含义:第一,通过接口或抽象类约束扩展,对扩展进行边界限定,不允许出现在接口或抽象类中不存在的public方法。第二,参数类型、引用对象尽量使用接口或者抽象类,而不是实现类。第三,抽象层尽量保持稳定,一旦确定就不允许修改。不能有修改接口的思想,除非是彻底的大返工。

2.封装变化
  对变化的封装包含两层意思:第一,将相同的变化封装到一个接口或抽象类中;第二,将不同的变化封装到不同的接口或抽象类中,不应该有两个不同的变化出现在同一个接口或抽象类中。封装变化,也就是受保护的变化,找到预计有变化或不稳定的店,我们为这些变化点创建稳定的接口,准确的讲是封装可能发生的变化。

例子

  引用大话设计模式中的例子,如果事先实现了一个加法的功能,后来添加减法功能的时候,你要考虑如何去扩展你的代码,而不是去修改已有的代码;
  对于这个例子而言,本来只有一个加法运算的类,按照开放封闭原则,要加入减法功能做法就是抽象一个运算类,然后分别去实现加法和减法类;这样就能保证原有的加法运算的代码不被修改。
  然而,并不是所有的代码碰见需求变更的时候,都只扩展而不修改,开发封闭原则的运用要掌握好时机,通常是在需求经常变更的环节使用这个原则;否则滥用这个原则反而会导致代码更加复杂。

优缺点

  开闭原则是最基础的一个原则,剩下的5个原则都是开闭原则的具体形态,也就是说前5个原则就是指导设计的工具和方法,而开闭原则才是其精神领袖,换一个角度来理解,依照java语言的称谓,开闭原则是抽象类,其他5大原则是具体的实现类,开闭原则在面对对象设计领域的地位就类似于牛顿第一定律在力学、勾股定理在几何学领域的地位,其地位无人能及。

1.开闭原则可以提高复用性。

2.开闭原则可以提高可维护性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值