原创声明
本文作者:黄小斜
转载请务必在文章开头注明出处和作者。
系列文章介绍
本系列文章主要围绕程序员,特别是Java或者后端程序员必须掌握的一些技术和技能,这些文章都是结合我个人的编程学习经历,总结和沉淀下来的方法论。作者目前在阿里做Java,忙里偷闲分享一些技术文章,希望能让更多人更容易地学习编程。
系列文章将会把一些技术学习方法、过程、要领与我的学习经验相结合,更加浅显易懂,并且我也会把我学习时用的资料,书籍和文章拿出来分享给大家,节省你我的时间。所谓授人以鱼也要授人以渔,是本系列文章希望达到的目标。
一个热爱分享的程序员,一个爱生活的斜杠青年。分享程序员编程学习干货和个人成长心得,期待你的关注,让我们一起进步!
本文思维导图
什么是设计模式
学习编程的朋友,想必对于设计模式这个词并不陌生,至少你一定也听说过,如果你是做Java的,那么就更加需要了解设计模式了,为什么这么说呢,因为Java作为一门面向对象语言,很多代码都可以通过设计模式得到简化、规范,提升编码效率和可读性。
按照百度百科的说法,软件设计模式(Design pattern),又称设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。
也就是说,代码可复用性是设计模式的核心要义。
平时我们听说过的设计模式有哪些呢,比如工厂模式,单例模式,代理模式,观察者模式等等,这些设计模式不仅在面试经常问到,而且在Java生态中也得到了广泛的应用,比如JDK里就有很多单例、工厂模式的应用,spring框架基本上也都用到了这几个设计模式,而Tomcat这种web应用容器,也是集设计模式之大成,对于观察者模式的应用特别多。
为什么要学习设计模式
那么,我们学习设计模式有什么用呢,一来,是帮助你更好地在日常开发中使用到设计模式,二来,想要理解JDK、spring以及Tomcat的实现原理和源码,你就必须要掌握相关的设计模式,否则你连代码都看不懂,又哪里谈得上开发呢。
这一点我体会很深,在大公司里,很多核心系统的代码都写得非常的高端大气上档次,对于设计模式的使用可以说是用到了极致,像是模板方法、策略模式、工厂模式等等适用于大型应用开发的一些设计模式,都会得到广泛的应用。先看懂代码,再进行开发,这肯定是程序员的自我修养之一。
学习设计模式,短期利于面试,长期则可以应用于工作,看来对设计模式的学习,已经是刻不容缓了。
新手上路
对于新手来说,设计模式完全是陌生的事物,一般常见的20多个设计模式,能够记住它的名字和用法都已经很困难了,更不用说自己能不能懂得如何去使用了。
我刚学设计模式的时候,就是抱着一本书啃半天,看完了所有的设计模式,但是过几天就忘得差不多了,面试的时候问我工厂模式,观察者模式,还是支支吾吾半天答不上来,说白了就是没有理解。
比如这个工厂模式,就分为简单工厂,工厂模式,以及抽象工厂模式,每个模式的用法都不太一样,当时就困扰了我很长一段时间。
如果你理解了它的内涵之后,就可以大概知道,简单工厂就是用来生成单一实例的,而工厂模式是可以根据输入输出不同的实例,抽象工厂则是根据不同的工厂生成不同产品的实例。
我们学习设计模式的时候,往往书本上给的栗子和demo都比较不切合实际,有的例子是动物,有的例子是食物,这个时候,如果我们自己去写一写,替换成工作中的一些场景,或者是自己熟悉的场景,比如说蔡徐坤,奥利给等等,相信更有助于你的理解和记忆。
花一些时间,跟着《head first 设计模式》这本书,把书上的设计模式案例都实现一下,能够跑得起来,要比你一遍一遍地看书来得靠谱多了。
学习源码
很多朋友看到“源码”两个字就望而却步,就好像让你玩游戏你一百个答应,让你拆开机箱看看哪块电路板因为玩游戏而严重发热,你就完全提不起兴趣。
学习设计模式,除了实战以外,最好的方式就是去看一些源码,比如JDK的源码,Spring的源码,甚至是Tomcat的源码。
如果你自己啃不动,那也可以跟着一些书籍和博客去啃,网上随便一搜就是一大把,spring里的xx设计模式、Tomcat里常见的n种设计模式,JDK里的20种设计模式等等,可能你平时都没有注意,一看自己平时用的API里居然有这么多设计模式,你就会觉得很有意思了。
举个栗子,JDK里的IO流,就使用了装饰者模式,比如对于一个IO输出流,它可能是字节流,也可能是字符流,它还可以是带缓冲的输出流,而这些特性都是通过装饰者模式实现的,IO流的实例可以不断的被转化成另一种流,只需要通过 “(装饰物)IO流”这种写法就可以不断地进行包装,就好像你买了一杯奶茶,可以往里面加椰果,加波霸,加奶加糖一样。
spring里最常用的几个设计模式就是单例模式,代理模式。大家都知道spring的IOC和AOP,spring本身提供一个bean容器,而每个bean其实都是单例的(同一个堆里只有一个实例)这其实就是用了单例模式来实现的。
那么,AOP用的是什么设计模式呢,其实就是代理模式,AOP是通过动态代理来实现的,首先,AOP是作用于某些方法或者是某些类的,你可以把这些方法或者类当成一个切面,也就是被代理的对象,而我们希望在这个切面上添加的功能,就是代理对象,比如统一的登录管理,请求拦截,安全检查等功能。如果你了解过动态代理,应该就会理解我的这个描述。
而对于Tomcat来说,设计模式就更多了,我们这里只讲一个观察者模式,Tomcat的启动是有一个生命周期(pipeline)的,你可以把这个生命周期当成一系列要执行的方法,而Tomcat的实现允许你监听这些方法的调用,你可以在pipeline上面注册自己的监听器,每当pipeline执行到你监听的方法时,它们就会通知你,然后你去执行相应的动作。
不得不说,设计模式在Java生态中的应用实在是太多了,当然,理解设计模式这件事于是需要你花一定时间的。
结合工作
理解抽象的事物往往都是具有挑战性的。学习设计模式,我们一般都是看书或者看教程,一般会有对一个模式的介绍,以及相应的代码,既然有代码实现,那就不能算是太抽象的东西,不过,这些样例代码往往和我们开发工作中的实现相去甚远,所以,我们学习设计模式的时候也往往会学了就忘,更无法应用到开发工作中。
在工作中,有一项神秘的技能,可以让你的代码能力突飞猛进,让你的代码质量、规范,以及可复用程度大大提升,这项神秘的技能,其实就是CV,没错,就是复制粘贴。
什么?不就是抄代码吗,我上我也行啊。不不不,程序员的事怎么能叫抄呢,那叫学习!参考!复用!
不过,在大公司里,CV这件事虽然可耻但是有用,毕竟大厂里的大牛多,代码写的好的人也多,每个团队都有那么些神仙代码,值得我们效仿学习,我就经常看到一些代码,是好几年前的大牛写的,被一直传承到现在,有时候即使要做重构或者是做迁移,都要把这些大牛的核心代码继续搬过来,可见这类优质代码的影响力之大。
我们先不管这些牛人的代码是怎么写出来的,但是这些优质的典范确实值得我们学习,比如我在开发一个系统的时候,发现里面的核心业务代码都是通过模板方法+注解化配置的方式来进行开发的,于是从头到尾看了一遍,十分佩服,觉得自己一定写不出来,那么这种代码风格就可以借鉴到另一个系统中。
比如最近我全程负责另一个系统的开发,我自己可以定义规范和风格,那么我当然要大展身手了,于是,这些优质的代码模板和设计风格就都被我拿来参考了,毕竟,在大公司里尽量不要重复造轮子,多借鉴多学习一定是没有坏处的,等到你掌握了这些东西的内核之后,自己再去创造一套规范和风格也未尝不可。
其实,不仅是设计模式,还有很多东西都是可以这样通过模仿来学习的,比如架构的设计,系统的分析,技术栈的选择等等,所谓书读百遍其义自见,熟读唐诗三百首,不会做诗也会吟,讲究的就是一个“熟能生巧”吧。
推荐资源
书籍
《head first设计模式》
《大话设计模式》