文章首发于公众号「陈树义」及个人站点(https://shuyi.tech),欢迎访问。
设计模式的本质
说起设计模式,就不得不说起重构。在 2017 年,当我还是一个工作 3 年的菜鸟,我重构了公司一个十几年的老系统,弄得心力交瘁。为了能深刻吸取这次重构的教训,我写了一篇文章记录这次重构的心得:浅谈重构中踩过的坑 – 陈树义的博客。
时隔三年,我再次刷了一遍设计模式相关知识,这次我对设计模式有了更深刻的认识。所以今天我们就来聊聊:设计模式的本质是什么?它的存在有什么价值?学了设计模式有什么好处?
在这篇文章中,我对设计模式的总结是:设计模式用于承载复杂的业务逻辑,使写出的代码简洁、易扩展。 简单地说,你需要去了解业务中哪些是变化的,哪些是不变的。这些变化的东西就是复杂的业务逻辑,你需要思考如何用一种合适的设计模式去承载它,使得当它发生变化的时候,能具有很好的扩展性。这时候如果你学过设计模式,对每种设计模式的使用场景都谙熟于心,那你做起来会更加得心应手。
有些人说,我看有些人也没学过设计模式,但他们代码也写得挺好啊。这里我想表达我的第二个观点:抽象思维才是设计模式的内核。 有些人接触的项目多了,其在项目中不知不觉地就用到了一些设计模式。这些人一般都具有一个共同点:抽象总结能力强。他们接触到了东西多了,会不断思考他们的共同之处,然后试图总结出经验。如果你具有这种抽象的思维,那即使你没看过设计模式,你也能写出类似于设计模式的代码。甚至到最后,你也可以设计出一种独特的设计模式。到时候你可能就成为了自创门派的「一代宗师」了。
设计模式的价值
对于设计模式,不少人也有很多见解。有的人觉得设计模式名过其实,实际编程中远远没有那么重要。在我看来,设计模式存在即合理,至少它有下面三点实在的意义。
设计模式是经验沉淀,便于后来者快速学习。 人类之所以能一代更比一代强,靠的就是用文字符号实现经验传承。而在编程领域,我们的设计模式其实就是前人在实战中的经验总结,他们将这些经验归纳出来成为设计模式。
对于经验不是很多的人来说,学习设计模式可以让他们有个初步的印象,等到他们有对应的项目经验时,他们可以更好地应用上。而对于项目经验丰富的人来说,设计模式可以丰富他们的项目场景,进一步提高他们对于复杂场景的掌控。
设计模式可以方便交流。 有些同学会觉得一些设计模式自己都用过,只不过先辈们给它起了个名字而已,没什么大不了的。但不知道这位同学是否有思考过:为什么要给各个设计模式起一个名字?
我们的知道有显性知识和隐形知识之分。显性知识就是大家一说,我们都能听得懂的。例如锤子可以用来钉钉子,例如搜索引擎可以用来搜索知识。而隐形知识则是指那些我们做事的经验,我们很难描述出来的东西。
我们这里说的设计模式,落地下去其实就是对应的代码结构。但我们如何将这种实战中的经验描述出来呢?一个最直接的方法是:我每次跟别人交流的时候,我都说:你这个创建一个接口,然后这个类继承这个接口,然后 bla bla …… 可能你说了半天,人家也还没听懂。即使听懂了,你下次还是得叽里呱啦说半天,别人才能听得懂。
怎样才能让别人一下子领会到我们的意思呢?很简单,就是给这种代码结构起个名字嘛!这也才有了工厂方法、策略模式、模板模式这些名词。当你跟别人一说这个名字,别人就知道是怎么回事,这不就大大提高了沟通效率嘛!
生活中其实也有很多类似的例子。我们为什么会有很多思考模型,例如:SMART 模型、PDCA 模型?本质上就是用来帮助记忆,以及便于沟通的。
想想看「搜索引擎」这个词,在 50 年前还不存在,那为什么有搜索引擎这个词呢?不就是为了便于交流,让别人知道是怎么回事吗?假设没有「搜索引擎」这个词,我们要描述百度,我们得怎么描述?我们试一下:就是你打开一个网页,输入词语,然后会挑出来一大堆相关的信息。这样还是挺麻烦的吧。
想想「五花肉」这个词,可能在古代还真没这个词。那我们要怎么形容?古代人说:就是那种一点肥、一点瘦的猪肉。现代人三个字搞定:五花肉!多高效啊!
文章首发于公众号「陈树义」及个人站点(https://shuyi.tech),欢迎访问。
学设计模式的好处
聊完了设计模式的本质和意义,最后我们聊聊设计模式的好处。
提高系统设计能力,代码更简洁,更易于扩展。 在互联网公司干过的都知道,研发流程里最确定的东西就是变化本身。需求是不可能一成不变的,唯一不变的就是需求会一直变。这就对研发人员提出了更高的要求,需要在系统设计的时候考虑到后续的扩展。
设计模式本质上就是对变化的封装,用结构化的代码结构去承载变化的需求。 当你明白这一点后,你需要做的就是去分析出系统中变化的部分,之后采用合适的设计模式(代码结构)去实现。只要变化的部分拆解得好,那你就有足够强大的结构去应付变化的需求。
在这一个层次上,考验的其实是你对业务的理解,还有你掌握的设计模式的数量。这些将直接决定你是否能抽离出变化的部分,而抽离出变化的部分之后,你能不能找到合理的设计模式去承载。如果找不到,那你的「抽象思维」层次决定了你是否能自我创造一种设计模式。
设计模式可以帮助阅读源码、写框架。 在我们现在使用的不少框架中,都使用了很多的设计模式。越是底层的系统,他们就需要越抽象,他们使用到的设计模式就越多。例如:Spring 框架中使用到的设计模式就多达十几种,有工厂模式、代理模式、模板模式等等。
当你理解了这些设计模式之后,你再去阅读源码,你就能够更快速地领会框架作者的意思。否则你看源码只会像看天书一样,完全看不懂,还吐槽这代码怎么这么垃圾。
设计模式有利于你面试。 这点可以说是挺功利的一点,但也确实是最实在的一点。工作三年以上的工程师,至少要会学习一些设计模式。只有掌握了合理的设计模式,你写的功能才能更易于扩展。这也是我们这些工作多年的老码农,和刚毕业的小年轻的区别。
如果你工作了好几年,写代码的时候还是从头写到尾短平快,不考虑一点扩展性,那么你可能真的很容易被替代。现今的面试中,也越来越考察面试者的代码编写能力了。掌握设计模式的思维方式,可以帮助你在面试中拿到更多的筹码、赢得更高的薪资。
小结
设计模式本质上是用于承载变化的业务逻辑,使写出的代码简洁、易扩展。它们就像武功中的招式,但具体的招式并不是目的,抽象思维才是设计模式的内核。掌握了抽象的思维,你也能设计出属于自己的模式。
设计模式是前人经验的总结,便于后来者快速学习。设计模式与菜名、标签一样,是对代码结构的一种描述,便于我们交流。掌握了设计模式,能够让我们提高系统设计能力,使系统更易于扩展。同时也能让我们读源码、写框架时事半功倍。
文章首发于公众号「陈树义」及个人站点(https://shuyi.tech),欢迎访问。
参考资料
- 为什么要学习设计模式 | 大专栏
- 设计模式就该这么学:为什么要学设计模式?(开篇漫谈) – 骑白马的菜鸟 – 博客园