软件设计之“开-闭”原则

来源:互联网 发布:tcp端口阻塞 编辑:程序博客网 时间:2024/05/10 01:04

什么是“开-闭”原则?

一个软件实体应当对扩展开放,对修改关闭;这个原则说的是,在设计一个模块的时候,应当使这个模块可以在不被修改的前提下扩展。换言之,应当可以在不必修改源代码的情况下改变这个模式的行为。

 

       满足“开-闭”原则的设计的优越性:

1.       通过扩展已有的软件系统,可以提供新的行为,以满足对软件的需求,使变化中的软件系统有一定的适应性和灵活性。

2.       已有的软件模块,特别是最重要的抽象层模块的不能再修改,这就使变化中的软件系统有一定的稳定性和延续性。

 

如何做到“开-闭”原则?

       实现“开-闭”原则的关键是抽象化。一个或多个抽象类或接口,规定出所有的具体类必须提供的方法的特征作为系统设计的抽象层。这个抽象层预见了所有的可能扩展,因此,在任何扩展情况下都不会被改变,做到了对修改的关闭。从抽象层导出一个或多个新的具体类可以改变系统的行为,因此系统的设计对扩展是开放的。

 

      “开-闭”原则和对可变性的封装原则:

              “开-闭”原则的另外一个角度就是所谓的“对可变性的封装原则”。

               对可变性的封装原则:

1.       一种可变性不应当散落在代码的很多角落里,而应当被封装到一个对象里面。同一个可变性的不同表象意味着同一个继承等级结构中的具体子类。继承应当被看做是封装变化的方法,而不应该被认为是从一般的对象生成特殊的对象的方法。

2.       一种可变性不应当和另外一种可变性混合在一起。所以一般的设计模式里的继承结构都不会超过两层。

 

“开-闭”原则与其他设计原则的关系

1.       里氏代换原则:任何基类可以出项的地方,子类一定可以出现。是对实现抽象化的具体步骤的规范。违反里氏代换原则,也就违背了“开-闭”原则,反过来不一定成立。

2.       依赖倒转原则:要依赖于抽象,不要依赖于实现。“开-闭”原则是目标,依赖倒转是手段。要想实现“开-闭”原则,就应当坚持依赖倒转原则。违反依赖倒转就不可能到达“开-闭”原则的要求。

3.       合成/聚合复用原则:尽量使用合成/聚合,而不是继承关系达到复用的目的。合成/聚合原则是现实“开-闭”原则的必要条件;违反这一原则就无法使系统实现“开-闭”原则这一目标。

4.       迪米特法则:一个软件实体应当与尽可能少的其他实体发生互相作用。一个迪米特法则设计出来的系统在功能需要修改时,会相对容易地做到对修改的关闭。也就是说迪米特法则是一条通向“开-闭”原则的道路。

5.       接口隔离原则:应当在客户端提供尽可能小的单独的接口,而不要提供大的接口。

 

显然,在设计中使用“开-闭”原则的不能违反里氏代换原则、依赖倒转原则和合成/聚合原则;遵循接口隔离原则与迪米特法则,会使一个软件系统在功能扩展的过程当中,不会将修改的压力传递到其他的对象。

 

       “开-闭”原则在其他设计模式中的体现

1.       策略模式:如果有一组功能,那么就将每一个功能封装起来,使得它们可以互换。策略模式就是从对可变性的封装原则出发,到达“开-闭”原则的一个范例。

2.       简单工厂模式:“开-闭”原则在简单工厂模式中,对于消费角色是成立的,对于工厂角色不成立。

3.       工厂方法的模式:具体工厂类都有共同的接口,它们“生产”出很多的处于一个等级结构中的产品对象。使用这个设计的系统可以允许向系统加入新的产品类型,而不必修改已有的代码,只需要再加入一个相应的新的具体工厂类就可以了。完全支持“开-闭”原则。

4.       抽象工厂模式:封装了产品对象家族的可变化性,可以是系统动态地决定将哪一个产品族的产品实例化;可以在新的产品对象引进到已有系统中时不必修改已有的系统。

5.       建造模式:封装了一个有内部接口的产品对象过程。

6.       桥梁模式:具体实现化类代表不同的实现逻辑,但是所有的具体实现化类又有共同的接口。

7.       门面模式:

8.       调停者模式:使用一个调停者对象协调各个同事对象的相互作用,这些同事对象不再发生直接的互相作用。一个不完美的方式。

9.       访问者模式:使得在节点中加入新的方法变得很容易,仅仅需要在一个新的访问者类中加入此方法就可以了,但是访问者模式不能很好地处理增加新的节点的情况。访问者模式提供了倾斜的可扩展性设计:方法集合的可扩展性和类集合的不可扩展性。

10.   迭代子模式:将访问聚集元素的逻辑封装起来,并且使它独立于聚集对象的封装。这就提供了聚集存储逻辑与迭代独立演变的空间,是系统可以在无需修改消费迭代子的客户端情况下,对聚集对象的内部结构进行功能扩展。

原创粉丝点击