一直想整理一下23种设计模式,因而给本身定了一个一天一模式的任务,工做之余用一天时间整理一种模式。算法
这么作的缘由是:编程
至少在我工做和学习的过程当中,在需求变动时、阅读源码时、修改BUG时,设计模式帮助了我不少。设计模式
在记录的过程当中,虽然对每种模式都进行了分析,而后尝试给出反例,再用设计模式优化这个反例达到预期的效果,但缺乏了从总体上去理解设计模式的一些说明。因此,在记录完成后写一个总结,也算善始善终,对本身负责。缓存
下面就说说现阶段的我,是怎么理解设计模式的。安全
- 若是你想要你的项目扩展性更强,请使用设计模式。
- 若是你想要你的程序复用率更高,请使用设计模式。
- 若是你想要你的代码可读性更好,请使用设计模式。
设计模式(Design Pattern)是前辈们对代码开发经验的总结,是解决特定问题的一系列套路。它不是语法规定,而是一套用来提升代码可复用性、可维护性、可读性、稳健性以及安全性的解决方案。网络
软件的设计模式来自于1995 年,GoF(Gang of Four,四人组/四人Bang)合做出版了《设计模式:可复用面向对象软件的基础》一书,共收录了 23 种设计模式,今后树立了软件设计模式领域的里程碑,人称「GoF设计模式」。数据结构
我认为设计模式最大的价值在于,能够拥抱需求变动,让程序具有快速开发,快速测试的能力。并发
例如建筑工程,建造一座桥,不会建到一半的时候甲方提出桥的长度要在加200米这种离谱的要求。而软件工程不同,在软件开发钱,开发中,开发后,都会有需求变动。因此要经过对一些特定的场景使用合适的设计模式拥抱需求变动。框架
下面总结一下为何要使用设计模式的几个点,现阶段技术水平的我能想到的好处以下:高并发
对上面三点,用一句话总结就是,设计模式的本质是面向对象设计原则的实际运用,是对类的封装性、继承性和多态性,以及类的关联关系和组合关系的充分理解,最终让程序具有高内聚与低耦合这两个特性。
高内聚是指将相关的行为汇集在一块儿,把不相关的行为放在别处。由于若是要改变某个行为时,最好可以只在一个地方修改,而后就能够尽快的测试和发布。
低耦合是指将尽量少的让实现业务的一些服务或模块有很深度的交互,若是能够作到,那么会减小在修改某些功能时出现按下葫芦起来瓢的状况。
其实一个好的软件设计就是在追求高内聚与低耦合,而后作到快速完成需求变动,快速完成测试,快速发布上线。
为了作到这一点,软件设计的大师们总结出了6个设计原则,正是基于这6个设计原则,对实际开发过程当中出现频率很高23个场景,提供了23种设计模式,下面来讲说这6个原则。
23种设计模式都是在帮助系统具有开闭原则。
网上对这六个原则的介绍已经有不少了,在这里就不一一介绍了。
主要就说说开闭原则,开闭原则的定义是:
对新增开放,对修改关闭。
就是说在设计时,对有可能从此发生需求变动的地方作好预留,保证当需求变动发生时,不修改已经开发过的代码部分,以新开发代码的方式来完成此次需求变动。
举个例子,系统要求有基于用户名和密码登陆系统的功能,设计人员在设计这个需求时,应该考虑,有可能有一天客户会要求系统加入经过用户名和短信验证码登陆的功能。那么对登陆模块须要稍微设计一下,当需求变动时,不须要修改已经开发完成的用户名密码登陆的代码,就能够加入新功能。
上图中,前5个设计原则的定义就是为了引出开闭原则,简单理解就是具有了前5个设计原则,就等于具有了开闭原则。
下面就开始说说设计模式。
设计模式能够分为三大类:
下面是我整理的23种设计模式的表格,尽量以一句通俗易懂的话来讲明何时可使用该模式(这很困难),而后提供每种模式的我整理的记录的链接,但愿对你们有所帮助。
序号 | 分类 | 名称 | 使用场景 | 备注 |
1 | 建立型 | 单例模式 | 对象在程序的生命周期内只存在一份时,可使用单例模式。 | 有5种单例的实现方式。 |
2 | 工厂模式 | 建立对象时,不一样场景下建立的对象不一样,可使用工厂模式。 | 父类定义通用部分,子类实现不一样部分 | |
3 | 抽象工厂模式 | 建立一族对象,且对象的类别维度大于1时,可使用抽象工厂模式。 | 一个维度是工厂数量,另外一个是工厂内方法的数量。 | |
4 | 建造者模式 | 分步建立一个对象,且步骤顺序要求可变化时,可使用建造者模式。 | 经过链式表达式建立对象。 | |
5 | 原型模式 | 把一个对象做为模板来建立新对象且有性能要求时,可使用原型模式。 | 使用Java的clone方法。 | |
6 | 结构型 | 适配器模式 | 把一个接口转化成另外一个接口,达到本来不能在一块儿工做的两个对象变的能够一块儿工做(适配),可使用适配器模式。 | 想象变压器的使用场景。 |
7 | 桥接模式 | 当类的功能层次结构与实现层级结构混杂在一个层级结构中,为了便于后续扩展,可使用桥接模式。 | 桥接模式使用场景很少,但能够帮助很好的理解面相对象。 | |
8 | 组合模式 | 将不一样的对象组合成树状结构,且要求某些场景下各个层级的节点无差异时,可使用组合模式。 | 常见的有多级结构均可以考虑组合模式。 | |
9 | 装饰者模式 | 要在不改变对象的状况下,动态的给对象附加功能,可使用装饰者模式。 | 想象Java的InputStream结构。 | |
10 | 门面模式 | 一个功能须要不少对象协同工做完成,能够把协同工做的过程封装到一个新对象种,让调用者不须要知道不少细节,这时可使用门面模式 | 讲复杂业务作类提炼。 | |
11 | 享元模式 | 把不变的外部资源加载到缓存池中,加载后就只从缓存池中读取,这时可使用享元模式。 | 理解为缓存中有从缓存中取,没有则从文件系统或网络上加载。 | |
12 | 代理模式 | Client调用某对象时,在调用前,调用后添加额外业务,但不想修改被调对象,这时可使用代理模式。 | 代理模式有静态代理,JDK动态代理和Cglib。 | |
13 | 行为型 | 责任链模式 | 某项业务须要通过一系列审批(验证),且要求审批过程可变化,这时可使用责任链模式。 | 能够设置责任链环节的顺序,随时可实现新验证环节。 |
14 | 命令模式 | 业务相似一些命令动做,切须要可撤回命令,同时想解除发号施令者与执行命令者之间的耦合,这时可使用命令模式。 | Client建立命令对象,而后指派某个对象去完成命令,不须要调用指派对象的方法(低耦合)。 | |
15 | 迭代器模式 | 不想把对象内部的可遍历的数据结构暴露给Client,但还须要Client能够遍历这个数据结构,这时可使用迭代器模式。 | Java中好多方法都使用Iterator。 | |
16 | 中介者模式 | 当为了完成某个业务时,发现不少对象的调用关系成网状了,这时可使用中介者模式下降耦合度。 | 这些对象只跟中介者有耦合。 | |
17 | 备忘录模式 | 要为对象记录一个快照,且可经过快照覆盖对象时,可使用备忘录模式。 |
将对象保存到一个新对象中,在必要时覆盖回来。快照不可修改。 |
|
18 | 观察者模式 | 当某个对象状态发生变化时,要批量通知多个对象,这时可使用观察者模式。 | Java有内置观察者模式,可是须要使用继承的方式去实现,更推荐本身实现 |
|
19 | 状态模式 | 对象的行为,在不一样状态时有不一样实现,这时可使用状态模式。 | 将状态用类表示,经过状态建立类,调用方法 | |
20 | 策略模式 | 对象的某些业务算法,在不一样场景下有不一样实现,这时可使用策略模式。 | 算法不一样时使用策略模式,作法与状态模式差很少,是场景上的区别。 | |
21 | 模板方法模式 | 对象的业务算法流程相同,但在不一样场景,某些步骤不一样,这时可使用模板方法模式。 | 父类中实现通用的步骤,将不一样的步骤定义成抽象方法,等着子类去实现。 | |
22 | 访问者模式 | 将对象中操做其数据结构的方法拆分出来,可使用访问者模式。 | 操做数据结构的方法太多,使用该模式提升可读性。 | |
23 | 解释器模式 | 相对某种语法进行解析,但是使用解释器模式。 | 使用场景很少。 |
设计模式的优势有不少,讲解这方面知识的书也有不少,只要是稍有一些面向对象编程经验的同窗都能看懂。
推荐几本我看过的书《Head First设计模式》、《图解设计模式》、《设计模式之禅》,《大话设计模式》这些书都很浅显易懂。
另外除了设计模式,还有不少书籍也讲解了能够提升代码的扩展性,重用性和可读性的方法,例如《重构》,《代码整洁之道》,《领域驱动设计》等等。
学习这些的目的是为了写出高质量的代码,维护时出错概率小,交接时可读性强。
在同窗们天天都学习处理高并发,海量数据之余,提高下本身的代码质量也是不错的选择,就当是换换脑子。
另外打开那些经常使用框架(例如Spring,MyBatis等等)和中间件(例如Eureka,Ribbon等等),会发现他们的代码编写的很是优雅,也用到了不少设计模式。
因此学习学习设计模式对阅读源码还颇有帮助,另外,说不定某天本身作开源项目时,就用获得了。
从自学编程开始就时不时看看设计模式,但一直没有系统的记录和整理,这篇博客做为这段时间笔记的一个总结和一个传送门,善始善终。
以上就结束了23种设计模式的整理,同时也准备下一轮的知识整理,目标还没选好,先给本身点份炸鸡不过度吧,哈哈。