我们常说一个好的系统设计在于其有较高的可维护性和较高的可复用性。其实可维护性与可复用性是两个独立的目标,并不总是方向一致。
软件的维护就是软件的再生。一个好的软件设计,必须能够允许新的设计要求以较为容易和平稳的方式加入到已有的系统中。但实际上,现有大多数软件系统不具备这样的特性。导致一个软件的可维护性较低的原因有四个:
1.过于僵硬(Rigidity):很难在系统中加入新功能。因为会波及其它模块,最后会变成跨越几个模块的大改动。
2.过于脆弱(Fragility):与过于僵硬同时存在。对一个地方的修改,往往导致看上去没有什么关系的另一个地方发生故障。修改完成前,系统的原始设计师甚至无法预测可能会波及到地方。
3.复用率低(Immobility):当发现有一段代码、函数、模块可用于新功能时,这些已有的代码总是依赖一大堆其它的东西,很难将它们分开。
4.黏度过高(Viscosity):对系统的改动可以采取保存原始设计意图和设计框架的方式,也可以以破坏原始意图和框架的方式进行。前者对系统未来有利,而后者是权宜之计,可以解决短期问题,但会牺牲中长期利益。如果一个系统设计,总是使得第二种办法比第一种容易,就叫黏度过高。
一个好的系统设计应该有如下的性质:
1.可扩展性(Extensibility):新的性能可以很容易地加入到系统中去。这是”过于僵硬“的相反面。
2.灵活性(Flexibility):允许代码修改平稳的发生,而不会波及到其它模块。这是”过于脆弱“的相反面。
3.可插入性(Pluggability):可以很容易将一个类抽出去,同时将另一个有同样接口的类加进来。这是”黏度过高“的相反面。
设计原则是在提高一个系统的可维护性的同时,提高可复用性的指导原则。这些原则包括:
1.开闭原则(Open-Closed Principle, OCP)
2.里氏代换原则(Liskov Substitution Principle, LSP)
3.依赖倒转原则(Dependency Inversion Principle, DIP)
4.接口隔离原则(Interface Segregation Principle, ISP)
5.组合/聚合复用原则(Composition/Aggregation Reuse Principle, CARP)
6.迪米特法则(Law of Demeter, LoD)
这些设计原则首先都是复用的原则,可以提高系统的复用性,同时提高可维护性。设计模式则是对设计原则的具体指导,可以恰当地将理论应用到实践中。设计模式可以划分为创建模式、结构模式和行为模式三大类别。
单纯说理论有些晦涩,在《大话设计模式》这本书中举了活字印刷的故事,我觉得很好的说明了什么样的设计是好的设计。
第一,活字印刷要改印版,只需更改要改之字,此为可维护;
第二,这些字并非用完这次就无用,完全可以在后来的印刷中重复使用,此乃可复用;
第三,若要加字,只需另刻字加入即可,这是可扩展;
第四,字的排列其实有可能是竖有可能是横排,此时只需将活字移动就可做到满足排列需求,此是灵活性好。