前言
很多程序员都已经意识到基础知识的重要性,觉得要夯实基础,才能走得更远。但同时对于如何将基础知识转化成开发'生产力'仍然有些疑惑。
所以,你可能看了很多基础的书籍,比如操作系统、组成原理、编译原理等,但还是觉得很迷茫,觉得在开发中用不上,起码在平时的 CRUD 业务开发中用不上。实际上,这些基础的知识确实很难直接转化成开发'生产力'。但是,它能潜移默化地、间接地提高你对技术的理解,让你在遇到深层问题时能迅速定位根源。
不过,我觉得,设计模式和操作系统、组成原理、编译原理等这些基础学科是不一样的。它虽然也算是一门基础知识,但是它和数据结构、算法更像是一道儿的。相比那些更加基础的学科,设计模式能更直接地提高你的开发能力。我在开篇词里也说了,如果说数据结构和算法是教你如何写出高效代码,那设计模式讲的是如何写出可扩展、可读、可维护的高质量代码,所以,它们跟平时的编码会有直接的关系,也会直接影响到你的开发能力。
不过,你可能还是会觉得设计模式是把屠龙刀,看起来很厉害,但平时的开发根本用不上。基于这种观点,接下来,我们就具体地聊一聊,我们为什么要学习设计模式?
1. 应对面试中的设计模式相关问题
学习设计模式和算法一样,最功利、最直接的目的,可能就是应对面试了。
不管你是前端工程师、后端工程师,还是全栈工程师,在求职面试中,设计模式问题是被问得频率比较高的一类问题。特别是一些像 BAT、TMD 这样的大公司,比较重视候选人的基本功,经常会拿算法、设计模式之类的问题来考察候选人。
常见的面试题包括:单例模式的线程安全问题、工厂模式的应用场景、观察者模式与发布订阅模式的区别、策略模式如何消除大量的 if-else 判断等。如果你对这些概念一知半解,很容易在技术面环节失分。
所以,我在求职面试的时候,都会提前准备、温习一遍设计模式。尽管并不是每次面试都会被问到,但一旦被问到,如果回答得不好,就是一个败笔,这场面试基本上也就凉凉了。所以,为了保证万无一失,摆脱一旦被问到答不出来的窘境,对于设计模式这种大概率被问到的问题,我都会未雨绸缪,提前准备一下。
当然,我并不是临时抱佛脚。我平时就比较重视设计模式相关知识的积累,所以底子比较好,只需要在每次面试前花很短的时间,重新温习一下,便可以自信满满地去面试,而不是心里老是担心被问到,影响正常的面试发挥。
所以,如果你也不想让设计模式相关问题成为你面试中的短板,那跟着我把专栏中的知识点都搞清楚,以后面试再遇到设计模式相关的问题,就不会惧怕了,甚至还会成为你面试中的亮点。
2. 告别写被人吐槽的烂代码
在这些年的工作经历中,我也看到过很多让我眼前一亮的代码。每当我看到这样的好代码,都会立刻对作者产生无比的好感和认可。且不管这个人处在公司的何种级别,从代码就能看出,他是一个基础扎实的高潜员工,值得培养,前途无量!因此,代码写得好,能让你在团队中脱颖而出。
好的代码通常遵循 SOLID 原则,即单一职责原则(SRP)、开闭原则(OCP)、里氏替换原则(LSP)、接口隔离原则(ISP)和依赖倒置原则(DIP)。
- 单一职责原则:一个类应该只有一个引起它变化的原因。如果一个类承担了过多的职责,一旦需求变更,修改的风险就会变大。
- 开闭原则:软件实体应当对扩展开放,对修改关闭。这意味着我们应该通过增加新的类来实现新功能,而不是修改现有的稳定代码。
- 依赖倒置原则:高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象。
所以,我不仅仅只是讲解设计模式,更加重要的是,我会通过实战例子,手把手教你如何避免刚刚提到的代码问题,告别被人诟病的烂代码,写出令人称道的好代码,成为团队中的代码标杆!而且,写出一份漂亮的代码,你自己也会很有成就感。
3. 提高复杂代码的设计和开发能力
大部分工程师比较熟悉的都是编程语言、工具、框架这些东西,因为每天的工作就是在框架里根据业务需求,填充代码。实际上,我刚工作的时候,也是做这类事情。相对来说,这样的工作并不需要你具备很强的代码设计能力,只要单纯地能理解业务,翻译成代码就可以了。
但是,有一天,我的 leader 让我开发一个跟业务无关的比较通用的功能模块,面对这样稍微复杂的代码设计和开发,我就发现我有点力不从心,不知从何下手了。因为我知道只是完成功能、代码能用,可能并不复杂,但是要想写出易扩展、易用、易维护的代码,并不容易。
如何分层、分模块?应该怎么划分类?每个类应该具有哪些属性、方法?怎么设计类之间的交互?该用继承还是组合?该使用接口还是抽象类?怎样做到解耦、高内聚低耦合?该用单例模式还是静态方法?用工厂模式创建对象还是直接 new 出来?如何避免引入设计模式提高扩展性的同时带来的降低可读性问题?……各种问题,一下子挤到了我面前。
而我当时并没有对设计模式相关的知识(包括设计模式、设计原则、面向对象设计思想等)有太多的了解和积累,所以一时间搞得我手足无措。好在因此我意识到了这方面知识的重要性,所以在之后很多年的开发中,我都一直刻意锻炼、积累这方面的能力。面对复杂代码、功能、系统的设计和开发,我也越来越得心应手,游刃有余。写出高质量代码已经成为了我的习惯,不经意间写出来的代码,都能作为同事学习、临摹的范例,这也成为了我职场中最引以为豪的亮点之一。
架构设计的核心思考
在设计复杂系统时,我们需要考虑系统的生命周期。一个系统往往需要运行数年甚至数十年,期间需求会频繁变更。如果初期没有良好的设计,后期维护成本将呈指数级上升。例如,使用策略模式可以将不同的算法实现封装在不同的类中,当需要更换算法时,无需修改调用方代码,只需切换策略实例即可。这种灵活性是硬编码逻辑无法比拟的。


