前人的思考,我们的阶梯,欢迎收听JJ五分钟设计模式。
回忆一下自己刚入行软件开发那会,只会一点编程语言的皮毛,但是却有股无脑的自信。接到一个上级的需求,都不带思考,就已经操起键盘盘起来了。结果不用说大家也能猜得到…
那时候写出来的基本上都是面条代码,if套着if,随着业务的增加,方法冗长,控制结构复杂,混乱而难以理解。
后来自己的编码能力也得到了提高,发现面条代码越来越不适应发展的需要,此时编码习惯演化了结构化编程,即面向过程开发。
面向过程的开发,要求把需求理解成一条一条的业务流程,每次开发前我总爱问项目经理“你的业务流程是怎么样的?”,然后分析这些流程,把这些流程交织组合在一起,再划分成一个又一个功能模块,最终通过一个又一个的函数,实现了需求。这对于项目的初级阶段来说,也许是最简捷的做法。
但是问题很快就出现了
面向过程关注业务流程,随着业务不断的复杂化,无论多么努力工作,分析做的多么好,也是永远无法从市场用户那里获得所有需求的。(产品经理流泪)而业务流程确是需求中最有可能变化的地方,业务流程的制定需要收到很多条件的限制,甚至程序的效率、运行方式都会反过来印象业务流程。有时候产品也会为了更好的实现商业目的,主动的改变业务流程。并且一个流程的变化,通常会带来一系列的变化。这就使得按照业务流程设计的程序经常面临变化。流程的易变性,使得把流程看的很重,并不能适应变化。
面向过程通过划分功能模块,函数间相互调用来实现功能,当需求变化时,就需要更改函数。而你改动的函数有多少的地方再调用它,关联多少数据?这是很不容易弄清楚的地方。或许开发者本人弄得清楚,但下一位维护代码者是否也了解所有函数之间相互调用的关系呢?函数的修改极有可能引起不必要的BUG的出现,维护和调试中所消耗的大部分时间不是花在修改BUG上,而是花在寻找BUG上,更是花在弄清代码调用逻辑上。种种迹象表明,面向过程的开发也不能适应软件的发展。
于是面向对象的编程方式诞生了
面向对象关注的是对象,而非过程。它的优点在于可以定义自己负责的事物,做它自己该做的事情,对自己负责,清楚的划定责任。
我们需要把需求理解成一个一个对象,我们应该问自己**“这个东西叫什么,他从哪里来,他能做什么事情?”**,然后制造这些对象,让这些对象相互调用。
优点:
-
需求的变化是必然,尽管我们无法预测变化是什么,但是通常能 预测哪里会发生了变化。面向对象能 封装 这些变化区域,从而更容易的将代码和变化的影响 隔离 开来。代码可以设计的使需求的变化不至于产生太大的影响。代码可以随着业务逐步迭代,新的(指重复的)代码可以更少的加入。
-
对象比流程更加稳定,更加封闭。业务流程的每一个步骤都可能改变某个数据内容,对外界产生影响。而对象则是完全通过接口与外界联系,接口内部的事情与外界无关。
缺点:
- 容易出现馄饨代码。即业务过程或算法的所有细节被拆分的支零破碎,分散到不同的类和方法中,为了理解一个过程或算法,必须在类和方法间跳来跳去,如果有多态存在,你都不知道到底是哪个子类的相关方法被执行
- 代码层次逐渐复杂,软件需要解决的需求越来越复杂,问题的解决看上去不再是那么直截了当,需要首先设计业务对象,然后才能实现业务流程。
总之,面向过程开发相对容易,但不容易维护与拓展;面向对象开发困难(这里指的困难是指你真正的实践了这个概念),但却能更好的应对变化的世界,所以我们需要面向对象的设计与开发。
设计模式是面向对象技术的重要运用
由于面向对象开发的复杂性,所以我们都需要做出应对变化,提高复用的设计方案,而设计模式就能帮助我们做到这样的效果----通过复用已经认证过的设计套路,我们能够在解决问题时避免前人所犯的错误,可以从学习他人的经验中获益,用不着为那些总是会重复出现的问题再次设计解决方案。显然,设计模式有助于提高我们的思考层次,让我们站在更高的角度来俯视我们的设计。
设计模式的定义:
“(每个)设计模式是对一个在我们周围不断重复发生的问题的描述,以及该问题的解决方案。这样,你就能一次又一次地使用该方案而不必做重复劳动”————Alexander
设计模式的组成:
-
模式名称: 一个助记名,它用一两个词来描述模式的问题、解决方案和效果。
-
阐述冲突:描述了应该在何时使用模式。它解释了设计问题和问题存在的前因后果,它可能描述了特定的设计问题,也可能描述了导致不灵活设计的类或对象结构。有时候,问题部分会包括使用模式必须满足的一系列先决条件。
-
解决方案:描述了设计的组成成分,它们之间的相互关系及各自的职责和协作方式。解决方案并不描述一个特定而具体的设计或实现,而是提供设计问题的抽象描述和怎样用一个具有一般意义的元素组合(类或对象组合)来解决这个问题。
-
使用效果:描述了模式应用的效果及使用模式应权衡的问题。模式效果包括它对系统的灵活性、扩充性或可移植性的影响,显式地列出这些效果对理解和评价这些模式很有帮助。
用设计模式的好处:
- 方便复用程熟解决方案,避免重复犯错与重复造轮。
- 模式本身即业务,当使用了正确的设计模式,业务实现与迭代更轻松。
- 预测、封装、隔离了变化,减少“改需求”产生的抵触情绪。
- 方便测试与维护,程序测试结构稳定,方便单元测试与集成测试。
现如今,好的设计模式已经沉淀,但是真正了解他们的人依旧很少,我们五分钟设计模式的目的,就是为了让更多小伙伴了解他们,运用他们,让他们为你工作排忧解难。
存在哪些成熟的设计模式
按设计模式的使用目的来划分,可分为创建型(Creational)、结构型(Structural)、 行为型 (Behavioral)三种。
- 创建型模式与对象的创建有关;
- 结构型模式处理类或对象的组合;
- 行为型模式对类或对象怎样交互和怎样分配职责进行描述。
按设计模式的作用目标来划分,可分为 类模式、对象模式
- 类模式处理类和子类之间的关系,这些关系通过继承建立,是静态的,在编译时刻便确定下来了。
- 对象模式处理对象间的关系,这些关系在运行时刻是可以变化的,更具动态性。
建议大家从使用目的角度来划分和记忆不同的设计模式,这样做有助于加深对该模式的理解与开发实践中更快的选择使用。
创建型类模式
:将对象的部分创建工作延迟到子类。
创建型对象模式
:将对象的部分创建工作延迟到另一个对象中。
结构型类模式
:使用继承机制来组合类。
结构型对象模式
:描述了对象间的组装方式。
行为型类模式
:使用继承描述算法和控制流。
行为型对象模式
:描述一组对象怎样协作完成单个对象所无法完成的任务。
生产中怎么使用设计模式
1、多在优化代码的时候考虑设计模式
在初学设计模式阶段,你对设计模式的理解并不是很深入,如果直接生搬硬套,可能会导致很多问题。所以宁可忘记你学过设计模式,先按业务流程去写。
写完了之后,你需要对你的代码进行优化,那么这个时候你就需要尝试去找问题了。在你的代码中是否有很多重复片段,是否有很多冗长的代码,一个类的职责是否过多,如果产品提出修改业务是否能快速迭代。此时你如果发现问题,并刚好适用于某种设计模式,你就可以进行使用了。
这样的好处是,你明显能感觉到使用设计模式前后,你代码的变化,以及这个设计模式带来的好处,在以后的工作中就有经验了。
缺点是前期容易采坑,拖慢开发进度,我觉得踩踩坑也没什么不好的,设计这件事经验胜过一切。
2、请使用设计模式的专有命名方式
比如说,在一个地方你需要使用工厂模式,那么你就在工厂类的名字后面加Factory,其他的设计模式也是类似的。
这种行业黑话一个是为了你自己以后维护的方便,一个是为了别人阅读你代码的理解设计思路,你们交流就有了共同的语言。
3、阅读优秀代码,观察运用场景,加深概念理解
想明白一个设计模式具体在什么场景使用,最好的办法就是阅读源码
如:当你看到MyBatis源码中产生SqlSession对象使用工厂模式,那么你先去想为什么它要这么做,这样做的好处是什么,你的业务是否也是和他相同的状况呢?
当你了解了运用场景后,使用起设计模式会变得更加得心应手。
4、避免滥用与生搬硬套
设计模式多用于复杂系统,方法设计,负责业务逻辑,增加代码可维护性方面 。
在实际的项目中,其实如果不是非常复杂的项目基本上用不到设计模式,不需要强行安插进去一个设计模式,就好像你不需要用火箭来打鸟一样,毕竟铺设发射井不是一件轻松愉悦的事情。强行的生搬硬套只会让代码的复杂度上升。
当你看的多,用的多,改的多,设计模式将会成为日常工作中的神兵利器。