共计 5098 个字符,预计需要花费 13 分钟才能阅读完成。
简介:设计模式是开发同学常常聊到的话题,也常常被用到理论的开发我的项目中,纯熟的人能够做到信手拈来,不相熟的人陷入苦思冥想中。笔者认为,不仅仅要把握设计模式的用法,更要洞察设计模式的底层逻辑,只有那样,能力做到遇到理论的问题能够应用适合的设计模式去解决。
作者 | 不拔
起源 | 阿里技术公众号
设计模式是开发同学常常聊到的话题,也常常被用到理论的开发我的项目中,纯熟的人能够做到信手拈来,不相熟的人陷入苦思冥想中。笔者认为,不仅仅要把握设计模式的用法,更要洞察设计模式的底层逻辑,只有那样,能力做到遇到理论的问题能够应用适合的设计模式去解决。
一 你应该关注底层逻辑
1 设计模式的段子
段子一:你让他给你讲设计模式,他给你讲故事,听完后,又蹦又跳,乐坏了;看原著设计模式和理论写代码时,又是又蹦又跳,那是疯了。
段子二:你让他给你讲设计模式,他给你讲架构;你和他讲架构,他和你讲建筑学;你和他讲建筑学,他和你讲哲学……
下面两个典型的段子,能够看到大家平时学习设计模式的无奈,故事听懂了,但仍然没有把握设计模式,甚至设计模式的类图大家也画得出,却还是不能灵便把握设计模式。究其基本的起因是没有把握设计模式的内核思维,只是晓得设计模式的外在模式,相当于只学到了“招式”,没有学到“内功”。
2 底层逻辑的实质
很多事物都有底层逻辑,当把握了事物的底层逻辑之后,很多事就好办了,如果你曾经洞察到了最外围的法则,在理论工作中就只须要依照法则去执行就能够。例如,咱们看到很多营销文案让人眼前一亮、叹为观止,如果要让咱们去写这些营销文案,一开始还找不到门道,写进去的题目平平淡淡,不够吸引人。那营销文案背地的底层逻辑是什么呢?咱们看到很多文案如“激发学习潜能的四大策略”、“如何在 10 天内记忆 5000+ 单词”、“一文提醒为什么你比他人差”……这些文案有的应用陈说手法,有的应用疑难手法,有的应用比照手法,有的应用感叹手法……再往下开掘,不论应用哪种手法,实质来讲是命中了人的爽点或痛点,再用这个底层逻辑去看各种文案,有的命中你的痛点,比方你想记忆更多的单词,事实记不住单词;比方你想胜利,但致力了很久还没有成果……有的命中你的爽点:你花更少的钱就能取得更好的服务;你不必出门就能赚到钱……当你洞察到了营销文案背地的底层逻辑,你当初也能够写出吸引眼球的文案,这就是底层逻辑的力量!
咱们学习 23 种设计模式,它们被划分成创立型设计模式、结构型设计模式、行为型设计模式,这就像营销文案的写作手法一样,那么设计模式的底层逻辑到底是什么呢?
二 设计模式的底层逻辑
1 设计模式的基石
平时咱们在写代码的时候,常常见到如下三种类型的代码:面条型的代码、过程式的代码和面向对象的代码,这里以一个例子来阐明这三种类型的编码特点。
面条型代码就是所有逻辑堆砌在一起,就像写一篇文章,不怎么分段落。比方现代雕刻文字,在一块木板上雕刻一首诗,如果诗人要把其中的一个批改下,那得从新雕刻这首诗。非常容易发现这种模式的毛病:耦合太重大,牵一发而动全身。
过程式代码在面条型代码根底上有了很大的提高,它遵循“自顶向下,逐步求精”的思维,把一个大问题划分成若干个小问题,分而治之。对应下面雕刻诗的例子,诗是由若干个行组成的,如果每块木板上只雕刻一行诗,万一要改某个字,只用从新雕刻那一行就行,不必从新雕刻整首诗。但如果要批改多个字,而且在不同的行时,这种极其状况下整个首诗又得从新雕刻了。
面向对象代码换了一种思考形式,诗是由行组成的,行又是由一个个字组成的,这也即是活字印刷的思维,这些字还能够复用于其它不同的诗,复用性十分强。
从下面的例子能够看到,外围还是洞察到事物的构造和关系,首先答复的是 what,而不是 how。过程式就是过分强调了 how,一开始就思考怎么去做,过程式思维是以本人为核心,导演了整个性能流程,本人承当了太多本人不应该承当的职责,整个设计就显得不灵便。面向对象是从对象的角度去看问题,解决问题是由各个对象合作实现,设计模式的基石就是面向对象,脱离了面向对象去谈设计模式那是耍流氓。
2 设计模式的鼻祖
设计模式有一本经典的书籍:《设计模式:可复用面向对象软件的根底》,在书中作者提到了一句话:“找到变动,封装变动”,这才是设计模式的底层逻辑。很多人漠视了这句话,反而去追寻各种模式的招式,遇到理论的问题又找不到适合的设计模式去解决了。“找到变动,封装变动”十分简练地提醒了设计模式的实质,细细品味这句话,再去看 23 种设计模式,每种设计模式都在应答变动的事,比方策略模式,具体的策略在变动;工厂模式,创立的对象在变动;模板模式,具体模板算法实现在变动……这就好比营销文案的底层逻辑:命中了你的痛点或爽点,具体痛点和爽点是什么须要去寻找。在理论问题中,须要咱们去看什么在变动,抉择哪种设计模式比拟适合。
3 再谈底层逻辑
再回过头看底层逻辑,平时咱们看到的景象只是景象层,外围是要洞察到事物的底层逻辑,只有那样能力真正了解景象、使用法则,如果你不懂营销文案背地的底层逻辑,你所有的怠惰都是低水平的反复,很难写出高质量的营销文案,偶然一两次起得了良好的成果你也不晓得为什么能吸引人。设计模式也是一样,你能相熟地画出各种模式的 UML 图,可你仍然还是用不好设计模式,实质还是没有把握设计模式的底层逻辑,只看到了设计模式的景象层的招式。设计模式的底层逻辑是“找到变动,封装变动”,这里就有两个问题:什么在变动,如何封装变动,巨匠认为咱们都晓得,所以并没有讲具体怎么去寻找变动,怎么去封装变动。接下来具体谈谈怎么去使用设计模式的底层逻辑。
三 设计模式要答复的两个问题
1 什么在变动
“找到变动,封装变动”这句话,首先要答复的是什么在变动,如果变动没有找到,就不可能封装变动。笔者这里以对象生命周期的视角去对待对象的变动,对象是由创立而产生,而后被应用,最初是沦亡。对象有三个不同维度的变动:对象构造的变动、对象规格的变动、对象行为的变动。以对象构造变动为例,对象的关系划分成两类:线性关系和非线性关系(树和图),在线性关系中,如何解决一个对象的变动不会影响到关联的对象?在树型构造中,如何解决一直新减少对象的问题?在图型构造中,如何解决用户方便使用简单零碎的问题?
找到变动是最为要害,不同的业务问题,遇到的变动问题也是不一样的,外围是要找到这些变动。比方对象规格的变动,有数量的变动、类型的变动、外观的变动,在理论编码的过程中就要有这种思考,比方创立一个对象,再深刻思维下,有没有其它类型的对象?数量有没有变动?……只有找到了这些变动,具体怎么去封装变动就是技术的问题,接下来探讨如何封装变动。
2 如何封装变动
从封装的类型上看,有数据的封装、办法的封装、类型的封装等。就具体的封装办法而言,常见的有配置项、接口、形象办法、类、注解、插件等具体的伎俩,再往上看次要应用了继承、组合的办法,再往上看封装的准则,常见的准则有繁多职责、开闭准则、依赖倒置、隔离准则……大部分人平时更多地关注如何封装变动,并没有深刻去思考什么在变动。
四 用底层逻辑推导结构型设计模式
1 寻找对象构造的变动
从 UML 看,对象之间的关系有依赖、泛化、组合、聚合,但就构造关系上看只有两种,线性关系和非线性关系。线性关系比较简单,就是一对一的关联关系,非线性关系分成两种:树型关系和图型关系。
关系构造有变动,意味着依赖产生了变动,比方线性关系中的变动,A 依赖的 B 产生了变动,此时 B 变动了就会影响 A,怎么做到 B 的变动不影响 A 就是要思考的问题。
2 应答线性变动
如下面所讲,如果 B 产生了变动,因为 A 依赖 B,则对象 A 也要改变动,如何缩小对 A 的影响呢?这里有两种办法:一种是通过减少适配来解决,另一种是通过代理来解决。这两种办法的要点都是一个对象不与变动的对象间接关联,不论是适配还是代理,都是引入了第三方来与 B 关联,第三方负责与 B 进行交互,B 对 A 是没有感知的。有的人马上发现了一个问题,这不是把问题转移到第三方上了吗?乍一看,还真是这么回事,如果咱们再发散思考,如果除了 A 要与 B 关系,还有 E、F……,如果 B 一改就关联的所有对象就要变动,这种代价就比拟高,如果只与第三方关系,只用改一个中央,老本要少得多。
3 应答非线性变动
非线性关系比线性关系要简单,常见也有两种办法:一种是通过注册机制,另一种通过形象层屏蔽复杂性。当一个对象蕴含多个对象时,如果间接去治理,须要承当的职责太多,通过注册机制就比拟好解决,减少一个对象,是通过注册机制被动告知对象。另外一种办法就是通过形象层屏蔽复杂性,比方门面模式,在门面内把所有的复杂度都躲避,对外提供简洁的接口。
五 业务变动之道
设计模式还是要利用到理论的业务中能力施展它的价值,Alan Shalloway 提到一个观点:无奈预测哪里有变动,但能晓得哪里可能有变动。平时咱们在做业务需要开发时,要有这种辨认变动的意识,先不要陷入面向过程的思维中,不要一上来就思考如何去实现,而是思考它是什么,会有哪些变动,比方对象的数量、对象的外观、对象的品种……当把这些思考分明之后,能力设计得更正当。
比方笔者之前做清结算业务时,投资人理财到期后,会将本息金额的钱打给投资人,刚开始只有大华领取通道,这里就要想到一个问题,大华领取只是一种具体的实现形式,还会有没有其它的领取形式,如果有就要做形象设计,设计一个通用的领取模板类,每接一种新的领取通道时,只用重写模板类中的几个办法即可,后续又接了民生银行领取、连连领取。
六 对象设计之道
有了后面所讲内容的铺垫,这里再深刻总结下对象设计的一些思考。对象设计有三个问题:有哪些对象?对象之间的关系是怎么的?对象的职责有哪些?当把这三个问题梳理分明了,对象设计也就容易得多,也是面向对象分析与设计的外围。失常来讲,咱们晓得构造决定性能,性能决定行为,这是十分合乎人的逻辑意识,但要想理解分明对象的构造又是十分难的,就像新冠病毒的分子结构也不是那么容易破解的,尤其是简单业务,它所蕴含的业务对象并不那么容易弄清楚它的构造。
咱们能够反过来思考,当有一种业务场景时,先思考它的职责是什么,再去思考应该由哪些业务对象去承当,这也是典型的演绎思维。比方在优惠券业务中,它的业务流动就三个:建券、发券、用券,也就是任何一个优惠券零碎,它要提供这三个最为根底的能力,这三个能力又对应到两个业务对象:券批次和券实例,券批次相当于是券的模板,告知优惠券的估算有多少、券面额是多少、应用条件是什么……,具体发放到用户手上的才是券实例。
当有了业务对象之后,就要通过用例去思考对象模型的所蕴含的属性和办法有哪些,这个过程并不是一次就能完满实现的,而是通过屡次打磨才行,这外面就要遵循一些准则,比方繁多职责、开闭准则、依赖倒置的准则……,让整个模型的可扩展性更好。
七 一个案例
最初拿一个案例来讲,店铺类目是卖家为了不便买家有针对性地选购商品而对商品做出的归类,比方上新类目,把最近 30 天上架的商品归类在一起,不便买家查找。遇到的挑战就是怎么用一套业务模型去反对不同业务方高度定制化的需要,有的需求方要求有三级类目,有的业务方要求浮动的两级类目,同时圈品形式也不一样,有的业务方要求有主动圈选商品,圈选商品的条件还不一样,如按价格圈选、按商品上架工夫圈选、按评估圈选……
怎么去设计这套模型呢,还是从店铺类目标定义去看,店铺类目至多蕴含两个要害的因素:类目构造和类目圈品,因为归类产生了构造,商品产生了圈品,思考到类目有不同的层级和圈品条件,所以第一版模型就很快设计进去了,从模型中能够看到能撑持业务的诉求,尤其是圈品条件中业务方能够自定义各种条件注册到平台上,看到这个设计,笔者心田还是快慰的。
但在实现的过程中,发现了一些问题,如根类目和子类目,在业务模型中有这两个概念,在代码上也要有这两个概念,正是引入了这两个概念,代码写起来就比拟麻烦,自身它们并没有什么区别,当初人为地把它们辨别开来,很多逻辑都要写两遍。笔者又进模型进行了优化,变成了第二版模型,这个模型就更简略了。
这里想谈的两点是要保障模型的简洁性和升高技术复杂度,技术人喜爱钻研技术,喜爱把一些学到的技术利用到我的项目中,这实际上是一种技术偏见,认为这样能力体现出技术复杂度和技术能力。简单并不见得有技术含量,就像设计模式的底层法则,作者并没有长篇大谈,而是只有 8 个字 ” 找到变动,封装变动 ”,大道至简就是这个情理,咱们学习设计模式,不要为了用设计模式而用,肯定要思考为什么用,解决了什么问题,这样才有价值。
原文链接
本文为阿里云原创内容,未经容许不得转载。