10.3 设计模式六大原则
我们已经了解到,设计模式体现的是软件设计的思想,而不是软件技术,它重在使用接口与抽象类来解决各种问题。在使用这些设计模式时,应该首先遵守如表10-1所示的六大原则。
表10-1 设计模式六大原则
原 则 | 含 义 | 具 体 方 法 |
开闭原则 | 对扩展开放,对修改关闭 | 多使用抽象类和接口 |
里氏代换原则 | 基类可以被子类替换 | 使用抽象类继承,不使用具体类继承 |
合成复用原则 | 要依赖于抽象,不要依赖于具体 | 针对接口编程,不针对实现编程 |
接口隔离原则 | 使用多个隔离的接口,比使用单个接口好 | 建立最小的接口 |
迪米特法则 | 一个软件实体应当尽可能少地与其他实体发生相互作用 | 通过中间类建立联系 |
依赖倒转原则 | 尽量使用合成/聚合,而不是使用继承 | 尽量使用合成/聚合,而不是使用继承 |
下面我们通过简单的实例来讲解这六大原则的具体含义。
10.3.1 开闭原则(Open Closed Principle)
通常,对于开发完的代码都需要多种测试才能够投入使用,这包括:
首先要经过开发人员的单元测试、集成测试。
然后再到测试人员的白盒测试、黑盒测试。
最后还要由用户进行一定的测试。
经过漫长的测试,代码才能够投入使用。但是软件产品的维护和升级又是一个永恒的话题,在维护的过程中,你可能要不断地增加一些小功能;在升级的过程中,你要增加一些较大的功能。
因此,软件产品随时都有扩展功能的要求。这种功能的扩展,就要求我们改变原有的代码。但是,对原代码的修改就会深刻地影响到原来的功能的方方面面:
可能对旧代码引入了新的错误,使你不得不对旧代码进行大规模的修改。
可能引起你不得不重新构造系统的架构。
即使新增的代码对旧代码没有影响,你也不得不对原来的系统做一个全面的测试。
所有上述列出来的问题,都是对系统功能进行扩展所不能承受的代价。换句话说,我们设计出来的系统,一定要是扩展性良好的系统。如何才能够设计出扩展性良好的系统呢?这就需要在软件系统设计时遵守开闭原则:
软件系统必须对扩展开放,对修改关闭。
换句话说,我们的系统必须是可扩展的系统,而不是可修改的系统。
做到开闭原则,就注意以下两点。
1)多使用抽象类
在设计类时,对于拥有共同功能的相似类进行抽象化处理,将公用的功能部分放到抽象类中,所有的操作都调用子类。这样,在需要对系统进行功能扩展时,只需要依据抽象类实现新的子类即可。如图10-1所示,在扩展子类时,不仅可以拥有抽象类的共有属性和共有函数,还可以拥有自定义的属性和函数。
![]() |
2)多使用接口
与抽象类不同,接口只定义子类应该实现的接口函数,而不实现公有的功能。在现在大多数的软件开发中,都会为实现类定义接口,这样在扩展子类时实现该接口。如果要改换原有的实现,只需要改换一个实现类即可。如图10-2所示,各子类由接口类定义了接口函数,只需要在不同的子类中编写不同的实现即可,当然也可以实现自有的函数。
![]() |
以上两点将会在后续的各个设计模式中得到充分的体现。