1 开闭原则
开闭原则:一个软件实体应当对扩展开放,对修改关闭。
在设计一个模块的时候,应当是这个模块可以再不被修改的前提下被扩展,换句话说就是,应当可以再不必修改源代码的情况下改变这个模块的行为。
满足开闭原则的设计可以给一个软件系统俩个无可比拟的优越性:
1.通过扩展已有的软件系统,可以提供新的行为,以满足对软件的新需求,使变化中的软件系统有一定的适应性和灵活性。
2.已有的软件模块,特别是最重要的抽象层模块不能再修改,这使变化中的软件系统有一定的稳定性和延续性。
如何做到开闭原则?
解决问题的关键在于抽象化。在想java语言这样的面向对象的编程语言里面,可以给系统定义一个一劳永逸的,不在更改的抽象设计,此设计允许有无穷无尽的行为在实现层被实现。在java语言里面,可以给出一个活多个抽象java类货真java接口,规定出所有的具体类必须提供的方法特征作为系统设计的抽象层。这个抽象层预见了所有的可能扩展,因此在任何扩展情况下都不会改变。这就使得系统的抽象层不需修改,从而满足了开闭原则的第二条:对修改关闭。
同时,由于从抽象层导出一个或者多个新的具体类可以改变系统的行为,因此系统的设计对扩展是开放的。这就满足了开闭原则的第一条:对扩展开放。
对可变性的封装原则
开闭原则如果从另外一个角度讲述,就是所谓的“对可变性的封装原则”。
对可变形的封装原则思想:找到一个系统的可变因素,将它封装起来。
1.一种可变性不应当散落在代码的很多角落里,而应当被封装在一个对象里面。同一种可变性的不同表象意味着同一继承等级结构中的具体子类。
2.一种可变性不应当与另外一种可变性混合在一起。例如:所有类图的继承结构一般都不会超过俩层,不然就意味着将俩种不同的可变性混合在了一起。
与其他设计原则的关系
做到开闭原则是一件非常不容易的事情,但是也是有很多规律可循的。这些规律也同样以设计原则的身份出现,但是他们都是开闭原则的手段和工具,是附属于开闭原则的。
1 里氏替换原则
里氏替换原则:任何基类可以出现的地方,子类一定可以出现。
里氏替换原则是对开闭原则 的补充,实现开闭原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,所以里氏替换原则是对实现抽象化的具体步骤的规范。
一般而言,违反里氏替换原则的,也违背开闭原则,反之不一定成立 。
2 依赖倒转原则
依赖倒转原则:要依赖于抽象,不依赖于实现。
开闭原则是目标,而达到这一目标的手段是依赖倒转原则。换言之,要实现开闭原则,就应当坚持依赖倒转原则。
3 合成/聚合复用原则
合成/句很复用原则:要尽量使用合成/聚合,而不是继承关系达到复用的目的。
显然,合成/聚合复用原则与里氏替换原则相辅相成的,俩者又都是对实现开闭原则的具体步骤的规范。
4 迪米特法则
迪米特法则:一个软件实体应当与尽可能少的其他实体发生相互作用。
一个遵守迪特米原则设计出来的系统在功能需要扩展时,会相对更容易的做到对修改的关闭。
5 接口隔离原则
接口隔离原则:应当为客户端提供尽可能小的单独的接口,而不要提供大的总接口。
接口隔离原则和迪米特法则都是对一个软件实体与其他的软件实体的通信的限制。遵守接口隔离原则和迪米特法则会使一个软件系统在功能扩展的过程中。不会将修改的压力传递到其他的对象。