记得2004年刚接触设计模式,买了经典的<<设计模式>>一书,细细地阅读,然后在开发中模仿。一两年时间过去,对23种设计模式弄得还算比较熟悉,也在软件设计中能用则用,比如Singleton, template method, proxy, facade等等。但总感觉用的不爽,当时也说不出原因;就是感觉在使用的过程中,是一种为了使用设计模式而使用上他们,有时候是生搬硬套。总之,自己当时是搞不清楚为什么要使用设计模式,停留在别人说它牛,我就学着用而不落人之后。
我不是一个天质聪颖的人,对软件设计的理解,基本上无法评自己能力单独领悟出来。只有常常督促自己多买国内外软件专家写的好书,来学习他们在这些方面的发现和总结。靠后天学习来弥补先天不足,也是没有办法中的办法。
终于在2007年看到了<<java与模式>>,书中对设计模式的讨论,并没有特别吸引我的地方,不过是用java语言来详细讲解23种模式而已,最多增加一些变体。深深吸引我的是"第二部分 面向对象的设计原则",这一部分虽然篇幅不多,但清晰地说明了我们为什么要用设计模式,使用设计模式是来解决什么问题的,使用之后我们要达到什么效果。软件的生命周期让我们认识到,面向对象的设计要解决的核心问题是可维护性和可复用性,特别是可维护性,一个好软件的维护成本远远大于初期开发成本。
一个软件设计的可维护性很差,原因在于:过于僵硬、过于脆弱、复用率低、黏度过高。相反,一个好的系统设计应该是可扩展的、灵活的、可插入的。在软件发达国家如美国,一些软件界的高手,在20世纪80~90年代,就陆续提出一些设计原则,这些设计原则是在提高一个系统的可维护性的同时,提高系统的可复用性的指导原则:
1、开闭原则:软件架构应该是对扩展开发,对修改关闭
2、Liskov替换原则:任何基类可以出现的地方,子类一定可以出现
3、依赖倒转原则:要依赖于抽象,不要依赖于实现
4、接口隔离原则:应当为客户提供尽可能小的接口,而不是提供大的接口。
5、组合、聚合复用原则:要尽量使用组合、聚合,而不是继承关系以达到复用的目的。
6、Demeter法则:一个软件实体应该与尽可能少的其他实体发生互相作用。
可以说,<<java与模式>>里很好的解决了我心中两三年来的不快,让我真正理解了为什么要使用设计模式。软件开发、设计原则与设计模式的关系,我不恰当的比喻为战争、战略与战术的关系;要取得战争的全面胜利,你首先要在战略上把握好,然后才是战术上指挥好;同样,要开发出好的软件,我们首先要遵循一定的设计原则,为了达到我们的目的,在开发中我们就恰当的使用相应的设计模式。
<<java与模式>>写的好,而且是中国人写的,但它缺少了一个方面的描述:我们怎样在实际的设计开发中做到这些呢?是不是一开始就要遵循这些设计原则,就要使用设计模式?还是有一个什么样的过程?
终于今年初看到了英文版<<敏捷软件开发:原则、模式与实践>>,国外这些大牛就是大牛,在这方面就是理解深刻,实践经验丰富。作者的观点很有点唯物辨证法,就是软件设计开始时,我们如果没有看出抽象的必要,可以先实现一个简单的,当第一次被需求触发而显现出抽象的必要时,我们这时机会就来了,需要很快提取抽象接口,遵循以上设计原则。当然,作者还有很多其它好的思想,这里不一一列举。
认识和理解都需要一个过程,没有理论,我们这些智商一般的人是很难仅仅在项目开发中尽快提高的;同样,光看书不实践,我们也很难真正理解这些别人总结的经验,那将是雾里看花。
丰富经验和软件设计思想以及软件工程思想,对软件开发的重要性真的是如此重要,怪不得我们国家无法开发出大型的高质量的软件来。