前言
大家好,我是路由器没有路。
在平时开发工作中,相信很多程序员都会这么想:“如何提升自己的技术呢?基础知识到底重不重要?”。
我想说的是:想要走得更远,夯实基础是必须的。或许你会有如何将基础知识转化为平时开发的“生产力”的疑惑,可能看了很多基础的书籍,比如操作系统、编译原理、计算机网络等,但还是感觉很迷茫,觉得在平时开发中压根就用不上。
事实也是如此,这些基础的知识确实很难在平时的应用中直接转化成开发“生产力”。但是,随着你对这些基础知识的学习和理解,它能潜移默化、间接地提高你对技术的理解。
那么,这次就谈谈设计模式对程序员(开发)的重要性。设计模式虽然算是一门基础知识,但是它和操作系统、编译原理这类基础的学科有点不太一样,设计模式可以说能更直接地影响并提高你的开发能力。
此时,你可能仍会觉得设计模式没什么用,看起来很高大上,面试也经常被问到,但平时开发时也压根没用上,代码也照常运行,一点问题都没有。基于这种想法,下面我们就具体地聊聊:我们为什么要学习设计模式?
可以避免被吐槽代码写的烂
经常看到一些 IT 大佬这么说的:“Talk is cheap,show me the code”。可以看出,程序员之间的较量往往是通过代码体现的,换句话说,代码能力是程序员基础素养的衡量标准。代码能力可以说是程序员最基本、最基础的能力。
尽管平时事情比较多,但我会每天抽出时间坚持写写代码、review 其他同事写的代码和重构遗留系统我认为写的烂的代码。在工作经历中,我见过很多写的烂的代码,比如命名不规范不统一、模块设计不合理而且没有模块化、业务代码和通用代码杂糅一起,结构不清晰、违背“高内聚、低耦合”的理念等等。可想而知,这样的代码阅读起来非常吃力,更不用说后续的维护了。如果需要添加或者修改一个功能,往往会牵一发而动全身,不知从何改起,恨不得将全部的代码删掉重构,但是想想又有些不值得!
当然,在平时工作中,也会看到一些同事写的比较优秀的代码。这种代码风格友好、逻辑和结构清晰、模块化清楚、设计合理等。每当看到这样优秀的代码,都会不由的对同事默默的认可和抱有敬畏之心。从这方面就能看出,他是一个基础扎实而又有潜力的员工,值得培养。因此,代码写得好,不仅能让你在团队中脱颖而出,而且还能得到领导的欣赏。
所以,如果不想被吐槽代码写的烂,就应该从设计模式学习起。
可以在面试中得心应手
如果要问为什么要学习设计模式,那么最功利、最直接的回答就是:应对面试。
不管你是什么职位的开发工程师,在求职面试中,被问到频率最高的一类问题就是设计模式了。尤其是像一些 BAT 这样的大厂,比较重视开发人员的基础知识,就会经常拿数据结构、算法和设计模式之类的问题来考察候选人。
所以,我在求职面试的时候,都会提前准备、温习一遍设计模式。尽管并不是每次面试都会被问到,但一旦被问到,如果回答不上来,给面试官的印象就不好了,这场面试基本上也就没戏了。所以,为了保证万无一失,摆脱一旦被问到答不出来的窘境,对于设计模式这种大概率被问到的问题,应该要未雨绸缪。当然,并不是说快要面试时,临时抱下佛脚。我平时就比较重视设计模式相关知识的积累,所以底子比较好,只需要在每次面试前花很短的时间,重新温习一下,便可以自信满满地去面试,而不是心里老是担心被问到,影响正常的面试发挥。
所以,为了能够顺利通过一些大厂的面试,学好设计模式是很有必要的,甚至这还会成为面试中的亮点。
可以提高代码可维护性和自身的开发能力
软件在不同的阶段和环境下都会面临变化,这与需求和技术的变迁密不可分。如果一模块代码在早期开发阶段就写成了维护性很差的样子,后期针对需求的变化,我们花费的代价是非常大的,显然,这种情况不利于软件的长期发展。设计模式的引入,可以在代码的编写过程中就考虑到软件的发展需求,提高了代码的可维护性。
例如,单例模式(Singleton)常用于在一个系统中,保证全局只有一个实例对象,该实例能够在许多处被访问。使用单例模式,程序员在任何一个地方想要获取该实例时都不需要重新创建一个对象,这样就避免了使用许多全局变量,在维护时很容易造成混乱、出错的情况。
在平时工作开发中,相信大部分程序员比较熟悉的都是开发语言、开发工具、和开发框架,因为每天的工作就是在框架里根据业务需求,填充代码。事实上,在刚开始出来工作的时候,都是如此。相对来说,针对业务开发的工作并不需要你具备很强的代码设计能力,只需要能够理解业务,用代码翻译对应的业务功能就可以了。
但是,如果有一天,你的 leader 让你开发一个跟业务无关的比较通用的功能模块,面对这样稍微复杂的代码设计和开发,你可能就会发现有点力不从心,不知从何下手了。因为此时的你只知道用代码完成业务功能、觉得代码能运行就行、代码比较简单,可能并不会关注写出来的代码的可扩展、可复用性和易维护性如何。
面对 leader 给的任务需求,如果一上来你就“啪啪啪”的开始写代码,那么可以说大概率你会被 leader 批一顿,因为你方案都没想好,或者说方案都没跟 leader 对齐。
那么当面对这种任务需求时,该如何对需求拆解、分层、分模块?是否要用面向对象分析方法?该怎么划分实体类、控制类和边界类?这些类应该对应有哪些对象属性、方法?该用继承还是组合?该使用接口还是抽象类?怎样做到高内聚低耦合?该用单例模式还是静态方法?用工厂模式创建对象还是直接 new 出来?有没有考虑引入设计模式后,在提高代码扩展性的同时,降低了代码可读性的问题?
是的,当你对设计模式相关的知识(包括设计模式、设计原则、面向对象设计思想等)没有太多了解和积累时,你不会考虑上面的问题的,就会一头雾水,不知从何下手。
说实话,对我而言,曾经我也有过这样的经历,因此,我意识到了设计模式这块知识的重要性。从那之后,在平时工作的开发中,我都会有意识地刻意锻炼和积累这方面的知识。面对 leader 给的任务或者接手新需求时,都会进行初步分析、方案设计,然后组织有经验的相关人员参与设计评审,这不仅让我的方案设计得到有效的反馈和优化,而且也提高了自身的开发能力。
后来,我在面对复杂的功能或系统时,通过有决策的设计和开发,开发起来也越来越得心应手,游刃有余了。可以说,不经意间写出高质量的代码已经成为了我的习惯,每当 review 我的代码时,同事都会带着学习的态度一起交流,这也成为了我工作中比较引以为豪的地方。
可以降低代码的错误和风险
软件开发过程中经常会出现各种错误,大多数错误根源在于软件的设计和架构不合理,这些错误可能不会立即出现,但会在软件使用过程中暴露出来,最终导致性能下降和系统崩溃。设计模式可以在代码的设计和架构层面上解决这些问题,从而降低出现错误和风险的可能性。
例如,观察者模式(Observer)的使用可以让被观察对象与观察者解耦,在被观察对象发生改变时,观察者会得到通知并自动更新。使用这种模式,我们只需要关注事件的发生和通知的传播,并不用关注事件的具体实现过程,这样就保证了代码的高内聚性和低耦合性,从而减少了错误和风险。
可以有效地学习框架和源码
作为一个程序员,技术的积累及其重要,不仅要有广度,同时也要有深度。一般有点悟性的程序员都会意识到这一点,所以在学习框架、中间件的时候,都会抽时间去阅读源码,理解其实现原理,而不只是停留在使用的程度上。
据我所知,有些程序员看框架源码的时候,往往是一头雾水、不知所措,经常听到说看不懂,很难坚持看下去的问题。实际上,这个问题的根本原因就是你所积累的基础功底还不够、你的能力还不足以消化这些代码。
通常一个优秀的开源项目、框架,它的代码量会比较多,也比较复杂,一些类、对象、方法之间的调用关系复杂。所以,为了保证代码的扩展性、可复用性、可维护性等,代码设计中就会使用一些设计模式。
如果不懂这些设计模式、设计思想的话,那么在阅读源码时,可能就会琢磨不透作者的设计思路,get 不到作者的初衷。对于一些很明显的设计思路,你可能要花费很多时间才能看懂。相反,如果你对设计模式、原则、思想非常了解,一眼就能悟到作者的设计思路、设计初衷,很快就能明白这么写的原因,代码读起来就会变得轻松了。
所以在我看来,学习设计模式确实可以有效提高读源码的能力,因为框架和库的底层实现都是以设计模式为基础的。
以下也给一些我学习设计模式的建议:
- 熟悉设计模式的分类和原则。掌握各种设计模式之间的联系和区别,了解设计模式的七大原则;
- 学习设计模式的意图和适用场景。对不同的设计模式应该有清楚的认识,了解它们的意图和适用场景,从而能够准确地选用合适的设计模式;
- 阅读并理解经典的设计模式书籍。建议阅读《设计模式:可复用面向对象软件的基础》一书,这是设计模式的经典著作,讲解详细,实例丰富。同时,也可以阅读其他的相关书籍和论文,如《Head First 设计模式》、《深入浅出设计模式》等;
- 探究框架和库的底层实现。通过理解设计模式,可以更好地理解和探究框架和库的实现。可以先查看框架或库的文档和源码,然后结合相关的设计模式,逐步尝试理解其整体架构和各个组件之间的关系;
- 写代码实践。最后,通过自己写代码实践来巩固和应用所学的设计模式。可以针对一些具体的问题或项目,运用设计模式来设计和实现代码,从而更好的理解设计模式和框架的实现。
总结
通过引入设计模式,我们能够提高代码的可读性、可维护性和安全性,从而实现高效的软件开发和维护。
设计模式是程序员们面对复杂软件系统的有力工具,是保证软件质量、代码可维护性和开发效率的重要手段。无论是哪个阶段,都应该时刻牢记设计模式的重要性,从而为软件的长期发展提供良好的基础和保障。
对于这方面的能力,要早点具备,这样在你后面的工作和学习中,才能一直都发挥作用。不然等到几年后,看到了,才恍然大悟,后悔没有尽早去学。