设计模式是软件工程中听起来非常深奥,也非常高端的一个词汇,似乎有了设计模式,我们的代码和项目就能自然的变得非常合理并且易于扩展和维护,然而事情并没有这么简单,软件工程中没有银弹。
我们在今天谈论设计模式时,往往与 1994 年 Erich Gamma, John Vlissides, Richard Helm, Ralph Johnson 四个人出版了《设计模式》一书1有着密切的关系,想要避开这本书讨论设计模式也非常困难。这本书在出版的 6 年后被机械工业出版社于 2000 年引进于中国,刚被引进的时候,因为大环境的原因,这本书还不是特别火热,但是自从 2014 年 5 月开始,由于国内互联网行业的迅速发展和信息产业的进步,设计模式一词也变得越来越热门2。
图 1 - 设计模式在中国的搜索指数
很多工程师都在研究设计模式,企图让自己设计的软件变得更加优秀,一些候选人也在简历上写着自己掌握多少种设计模式并在面试时讨论书中的那 23 种设计模式。与设计模式在中国的流行相比,在全世界范围内,设计模式的热度从 2004 年开始却一直在下降3。
图 2 - 设计模式在全球的搜索指数
上述数据难道说明全世界的开发者都不在乎如何设计更优秀的软件吗,作者觉得这答案一定是否定的,设计出架构良好的软件是工程师追求的目标,设计糟糕的软件是无法持续维护的,只能一次又一次的重构或者重写。为了减少自己的麻烦,虽然从短期看来工程师都倾向于写出容易实现的逻辑,但是从长期看来工程师更倾向于写出容易维护的代码。
作者在本文的观点是,学习设计模式与设计优秀的软件并不相关,盲目追求和套用书中的设计模式只能使项目变得更加糟糕,本文并不是要批判《设计模式》中提出的通用的设计模型,我们需要对书中的内容多一些批判性的思考,想清楚究竟什么样的设计才是能够保留下来的。需要注意的是,这篇文章充满了作者的主观意见和个人经验,如果读者不认同本文的观点,欢迎在文章下面留言并讨论。
在讨论设计模式的作用之前,我们需要先理解它的定义。在软件工程中,软件设计模式是在特定上下文下对于普遍出现问题的可重用解决方案4。这个定义非常严谨,我们可以发现几个关键的形容词,特定的(Specific)、普遍的(Commonly)和可重用(Reusable),这几个形容词说明了设计模式的特性以及它的局限性,本文将分三个部分分析作者为什么觉得设计模式没用。
抽象的设计模式是从不同具体项目中总结出来的通用经验,从具体到抽象的过程相对容易,然而从抽象的模式套用到具体场景却很困难,如果没有足够的经验或者思考只会做出拙劣的设计。设计模式是从具体场景中总结的解决方案,它会站在一个更高的角度提炼实现中的关键细节,这样才能提供更好的通用性。
图 3 - 抽象的模式与具体的实现
因为我们需要在多个不同的实现和场景中寻找类似的模式,所以在提炼设计模式的过程中一定会失去很多实现细节。作为理论来讲,精炼的、抽象的定义才能够更好的传播和重用,但是不同的读者在理解这些定义时会遇到两个问题: