写在前面
设计模式是一个非常奇妙的东西。在我们刚刚学代码的时候,身边的高人同事/网上的文章都会说,"设计模式是非常重要的东西"。日常写代码过程中,偶尔也会听到"这块代码用xxx模式感觉很会更好"",但也会感觉,好像我完全不懂设计模式, 也不会影响我写代码,看源码。拿我自己来说,曾两度系统看过设计模式,分别是工作一年半与三年的时候。"我从设计模式中学到了什么?","我对设计模式有什么看法?"我好像也只能说说"策略模式可以解决if else,工厂模式可以创建对象"这些话 所以我决定三顾设计模式,总计了一下之前两次学习的教训,这次学习更多的是跳出某个特定的模式,加入更多的思考。这篇文章主要就是总结一下第三次学完设计模式后,自己的一些想法。
要不要学&&有什么用?
如果你是一位对技术感兴趣,想要在技术这条路持续走下去的人,我的建议是要学的。 你可以不必把所有模式的类结构背的滚瓜烂熟,但至少对常用的设计模式,场景,核心思想要记住。
学习设计模式可以增加你代码的编写与阅读能力。可以增加你的设计能力。 对我来说最大的作用就是加强我对阅读源码的自信以及不再乱使用设计模式。
设计模式是什么?
设计模式是一套通用的可复用的解决方案,用来解决在软件设计过程中产生的通用问题。它不是一个可以直接转换成源代码的设计, 只是一套在软件系统设计过程中程序员应该遵循的最佳实践准则。 ---维基百科 我觉得这句话是每个准备学习设计模式的人需要牢记的一句话, 设计模式不是银弹,不是直接可以套的代码,它只是一个准则。那怎么理解"最佳实战准则""呢? 这里就要引出个人觉得比设计模式更重要的东西,也就是我们熟知的"solid原则""
- S 单一职责原则
- O 开闭原则
- L 里氏替换原则
- I 接口隔离原则
- D 依赖倒置原则 后续也衍生出另外一种说法"六大设计原则""(多了一个迪米特法则(类与类之间的亲疏关系) )。 个人觉得好代码的评判标准就是六大设计原则(我们日常代码加上可读性),满足的越多,代码越优秀。但全部满足只是理论情况,在许多场景,我们可能只能满足其中几条。那设计模式也可以这样描述: 在特定的场景下,在尽可能满足六大设计原则下,所编写出来的最佳的代码。 用生活中的例子来翻译这句话: 假如做项目就是搭建一套完整的乐高,我们每行代码就是其中的小零件, 那六大设计原则就是在用小零件拼凑的完整,牢固的部件,比如三角形,椭圆形。任何乐高模型拆开来看都是由这些部件组成。 而设计模式就是在长期拼乐高的实践中,用六大设计原则作为部件拼凑而成的架子。这些架子在所适用的场景无论是稳定性,精美性,都称得上是最优解。 比如3个长矩形拼成的"工""字+4个圆柱形拼成的车架子, 它在车模型场景中就可以直接使用。 但很多情况下,这些架子与我们所需要的并不能完全契合(或者说只是一开始感觉契合/乍一看契合)。比如上述的车架子在车模型适用,但我们在拼凑别墅模型时,有一个车样式的椅子,它所需要的只是2个轮子+"工""字架子。 这时候我们有三个选择。 1.强行使用这个架子,只是看起来没那么好而已,但内部其实是可靠的。 2.根据拼凑规则,修改架子中的零件来适配
3.发现场景确实不适合,放弃使用这个架子,自己根据拼凑规则来组装 其实这三个选择也就是对应我们学习设计模式的三个阶段,也带出我们如何学习设计模式这个问题。
怎么学习设计模式?
学习设计模式的三个阶段
初学阶段
对应我们上述的第一个阶段,如果你也学过设计模式,你肯定经历过下列阶段。学完策略模式(醍醐灌顶)->发现if else(眼前一亮)->使用策略模式(迫不及待)->后面新需求来了,发现if else的地方并不会扩展了,就算老代码放在那里,好像也没什么问题,并且看起来还更简洁(对自己无语)。 大多数人都会经历这个阶段,这样不考虑后续扩展/完全合适的场景去使用设计模式其实也没问题,只是有时候没这个必要而已。
融会贯通阶段
对应我们上述的第二个阶段,这种做法其实在现在需要源码里面非常非常常见。(比如spring,tomcat里面使用的责任链模式,其包含的类模式都与标准的责任链不同)。 这里其实呼应了我们一开始对设计模式的定义。不是直接使用,只是准则而已。这也 启发了我们学习设计模式最重要的是学习思想以及它遵循的六大设计原则。而它的类模型只是一种参考答案而已。
无形胜有形阶段
对应我们上述的第三阶段,这时候已经对六大设计原则理解透彻,也知道如何遵循原则写出优质代码,对设计模式所使用的场景非常熟悉,在完全契合的场景会使用对应的设计模式。就好比超级学霸写作业,"我不要参考答案,我写的作业就是答案""
如何学习
要
- 常见模式的学习时,要熟记使用场景以及它的核心思想。(比如观察者模式的核心思想就一句话,在两者之间建立一种触发机制)
- 当你理解某个模式的思想时,尝试在生活中想其他场景去契合。(还是观察者模式来说,其实这种场景生活中无处不在。)
- 当你某种模式学着比较难理解时,可以先想一下如果不使用这个模式,代码怎么写。使用过后,解决了什么问题,怎么解决的。自己写一个demo来进行重构。
- 要时常复习,毕竟许多模式日常中很少使用。但毕竟是前人总结出来的精华,每次复习说不定会有新感悟(至少我是这样)
不要
- 不要去死背它的类模型,这只是参考答案。
- 不要学完了demo就完了,最好能结合源码中的使用来学习,加深印象。
什么时候学设计模式?
对于我这种普通人来说。(这里定义一下普通人:天赋一般,记性一般。比如学Jvm背了忘,忘了背。看源码,要么看了很容易忘,要么看着看着就迷糊了,困了。) 个人感觉设计模式有一定门槛的,要写够了"垃圾代码"。真正理解某个模式最佳的场景就是你写了一堆垃圾代码,想要重构,有心无力,发现某个模式恰好可以优化你的垃圾代码。(前提是这部分代码后续不会再改变) 就拿我来说,第一次学完了,我只是单纯的学了所谓的写法,学完过后感觉跟现在的知识水平衔接不上,我没办法去深刻理解它某个含义的核心思想,也没法 灵活的去运用,只能看到某个demo的时候知道,"哦~,这是xx模式""(其实我们很多技术都有这种现象,它是有门槛的,当你在学习某个技术的时候,发现理解困难,这时候就需要想想是否要补一些基础知识了。比如java初学者学习多线程部分非常困难,是因为操作系统基础概念不足)。
最后
最后回答一下我在文章一开始对自己的两个提问。
-
我从设计模式中学到了什么?
-
从技术层面来说
- 开阔眼界:23种设计模式中大部分其实简单易懂,学习完了之后会有种恍然大悟的感觉,在特定的场合,其实只需要Xx模式,代码就可以写的很好。有部分确实很复杂,比如访问者模式,解释器模式。这种模式无论是日常使用还是源码中都很少见,学习过后才发现java代码原来还可以这样写。(在知乎上看到一个高人对设计模式的评价。"设计模式就是弥补编程语言的缺陷""。)
- 加强我阅读源码的能力与自信。主要还是自信方面,让我对任何java源码都有自信花时间读懂(其实不学,只要花时间也能读懂)
-
从思想层面来说
- 加深对六大设计原则以及oo思想的理解。23种设计模式中所使用的技法,无非也就是oo的三大特性:封装,继承,多态加上一个组合/委托的思想。
-
-
我对设计模式有什么看法?
- 在你准备学习之前请先学习六大设计原则。设计模式不是直接使用,只是准则。切勿盲目使用
- 设计模式真的很有用,并且没那么难。如果你准备在技术这条路持续走,建议学习。
- 当你在某源码中发现xx模式,那其实配合该模式所使用的场景,能帮助你理解作者的意图和思想。(毕竟那些作者都是大牛,一定是在适用的场景才会使用)
- 大多数人学习过程中都会经历从炫技到慎重使用再到熟练使用的过程。当你达到熟练使用的地步,设计模式就跟算法一样,成为了你的内功。 这篇文章只是夸夸其谈,后续会分三篇文章分别讲述我对设计模式中三大类型的理解。