设计模式总结(《Head First设计模式》学习总结)
写在前面:
学习过程中不仅要熟练掌握技能,理论的消化吸收也必不可少。虽然个人更倾向于学习技术类的东西(短时间的精力投入很快就能看到成效...),但看了很多前辈的经验总结后才知道理论性的东西是绝对不能忽视的,毕竟理论对实践有着重要的指导意义。而了解“设计”相关的东西,会对“实现”产生潜移默化的影响,虽然不能在短时间内看到让人欣喜的变化,但可能有一天回过头来一想“哦~,原来我这个不错的小习惯是当年在那本书上学到的啊”
一.什么是设计模式?
绕了一圈之后让我们又回到这个话题吧(看书之前问自己一遍,看完之后再问自己一遍,答案之间的差异就是感悟了)
之前:
自问:设计模式是什么?
自答:是一些系统设计的指导原则吧,不过我现在天天写代码,应该也用不到设计层面上的东西。
自问:哦,那具体是什么?
自答:不清楚,不过我见过一些前辈的代码,结构很复杂,一看就很上档次的那种,那些应该就用了设计模式吧,所以代码有没有应用设计模式应该就是高手与新手的区别了。等我成了高手之后,这种东西还不信手拈来,嗯,不说了,我写代码去了,好好积累项目经验。
...
之后:
自问:设计模式是什么?
自答:设计模式是由代码结构优化经验萃取出来的理论知识,应用成熟的设计模式能够增强代码的可复用性、可扩展性与可维护性。
自问:你好像很专业的样子,那好,既然设计模式有这么多好处,那是不是应用了设计模式的设计都是好设计?
自答:当然不是,我们不能为了使用模式而使用模式。设计模式可不能滥用,毕竟应用设计模式必须要作出一些牺牲(比如增加类结构的复杂性...),所以滥用设计模式的话是会出事的。而且,就算我们有了锤子,也不能把所有问题都看作钉子吧?
...
P.S.还记得学习正则表达式的总结:能不用就尽量不要用(最大限度的避免滥用),设计模式与之类似,不能看到什么问题都往模式上靠,只有当我们非常确定在当前情景下确实需要用设计模式来优化我们的设计时,才考虑使用设计模式(至于到底用不用,还要权衡重构的成本与优化的收益...)
二.要不要使用设计模式?
这是个值得思考的问题,毕竟现在我们已经拥有了一把锤子,要不要用它当然成了问题,毕竟不是所有的问题都可以用锤子来解决。退一步讲,即便所有问题都能用锤子解决,我们也不确定使用锤子是不是最好的解决方案(拔钉子的话,可能用钳子更好些...)
当我们拿着某个设计模式想放进我们的代码中时,最好权衡一下利弊,诚然,设计模式具有的设计上的弹性一定会给我们之后的维护变更带来些便利。但是利与弊到底哪个更多一些,我们需要先回答几个问题再做决定:
- 我们的项目是不是几乎不涉及维护或者没有后续版本,那么我们引入设计模式还有必要吗?
- 我们项目的规模是不是大到了不用设计模式不行的地步?
- 这个设计模式用在这里合适吗?有没有更合适的?
- 非要用设计模式吗?可不可以用几个简单的设计原则来代替?
- 引入设计模式之后,代码结构的复杂度大大增加,重构的成本我们可以接受吗?
如果深思熟虑之后,还是觉得使用设计模式比较好,那么,放心去用吧,之后好好享受设计模式带来的好处吧
三.设计原则总结
设计原则都是一些简单的指导意见,没有固定的实现,因而设计原则也更加灵活,常见的设计原则如下:
- 封装变化(把易于发生变化的部分抽出来,以减少其变化对其它部分的影响)
- 多用组合,少用继承(组合比继承更有弹性)
- 针对接口编程,不针对实现编程(使用接口可以避免直接依赖具体类)
- 为交互对象之间的松耦合设计而努力(更松的耦合意味着更多的弹性)
- 类应该对扩展开放,对修改关闭(open-close原则)
- 依赖抽象,不要依赖具体类(减少对具体类的直接依赖)
- 只和朋友交谈(密友原则)
- 别找我,我会找你(Don't call me, I will call you back.安卓开发的大原则)
- 类应该只有一个改变的理由(单一责任原则)
能用设计原则解决的问题就不要用设计模式(杀鸡焉用宰牛刀...),因为设计原则实现起来更加灵活,更加轻巧(不用去考虑模式的条条框框...)
四.设计模式总结
名称 | 特点 |
策略模式(Strategy) | 把可以替换的算法步骤封装成一个个算法族,供运行时动态选择 |
观察者模式(Observer) | 定义并维护对象之间的一对多关系 |
装饰者模式(Decorator) | 建立拥有共同超类的装饰者与被装饰者来实现功能的动态扩展 |
工厂模式(Factory) | 封装对象的创建过程,包括工厂方法模式和抽象工厂模式 |
单件(例)模式(Singleton) | 用来创建唯一的对象(比如数据库连接对象,线程池对象等等) |
命令模式(Command) | 封装方法调用细节,解耦请求者与执行者 |
适配器模式(Adapter) | 用来实现不同接口间的转换 |
外观模式(Facade) | 为复杂的子系统提供简单易用的高层接口 |
模版方法模式(Template Method) | 用来封装算法骨架(流程),某些步骤由子类实现 |
迭代器模式(Iterator) | 用来封装遍历细节 |
组合模式(Composite) | 提供一种层级结构,使得我们能够忽略对象与对象集合间的差异,一视同仁地对待它们 |
状态模式(State) | 把所有动作都封装在状态对象中,状态持有者将行为委托给当前状态对象 |
代理模式(Proxy) | 通过插入第三方(代理对象)来分离调用者和被调用者(不同于执行者) |
复合模式(Compound) | 将多个模式组合结合起来形成一个“框架”,以解决一般性问题 |
桥接模式(Bridge) | 将抽象的控制类与具体实现类通过组合解耦,使得抽象层类与实现层类可以对立与对方而变化 |
生成器模式(Builder) | 用来封装组合结构(树形结构)的构造过程,与迭代器模式类似,都隐藏了组合结构的内部实现,只提供一组用于创建组合结构的接口 |
责任链模式(Chain of Responsibility) | 让一个请求可以被一组接收者顺序处理,类似于Android处理请求的方式:一个接收者捕获请求后可以return true消费掉请求,也可以return false传递给接收者队列中的下一个接收者(观察者) |
蝇量模式(Flyweight) | 抽象出对象管理层来统一管理大量的同类型对象,以减少运行时对象实例的个数,减少内存消耗 |
解释器模式(Interpreter) | 用来为简单语言创建解释器,将语法规则直接映射为各个类,结构简单,但效率较低 |
中介者模式(Mediator) | 引入中介者来封装多个对象间的复杂交互,以降低同级(在类结构统一层次上的)对象间的依赖 |
备忘录模式(Memento) | 支持对象状态的保存与恢复,并将对象状态数据封装起来,独立于客户代码以提供保护(Java中可以结合序列化反序列化技术来实现该模式) |
原型模式(Prototype) | 以现有的对象为原型,通过clone得到新的对象(以简化新对象的创建过程) |
访问者模式(Visitor) | 为组合结构添加新的操作,而不需要频繁的改变组合结构 |
五.面向对象的设计(Object Oriented Design)
一直伴随着OOD的问题就是“折衷”(或者说是“取舍”),最简单的例子——要不要用设计模式?
- 用,意味着将产生复杂的类关系,多层的抽象,我们将牺牲易读性换取易扩展性、易维护性或者其它特性
- 不用,意味着我们不需要对现有代码进行重构(或者不用去在复杂的设计上耗费过多的时间),但使用设计模式的所有好处我们就都享受不到了
二者选其一,这就是一个“取舍”,或者创造第三个选项(比如使用设计原则),这就是一个“折衷”
写在后面:关于《Head First设计模式》
很少写书评,因为每个人的喜好不同,不好作推荐(甚至有时候喜欢一本书仅仅是因为喜欢作者的行文风格而已,从而不自觉的认为书籍内容不错。。)
这本书是前辈推荐的,看完之后觉得大部分章节讲的很不错,既细致又通俗,但感觉某些章节并不是很好(比如第一章策略模式的例子不很贴切,和后面的远程代理部分细节展开的不合理)
总体来说,作为入门书籍的话,《Head First设计模式》还是不错的,个人感受,仅供参考
设计模式总结(《Head First设计模式》学习总结)的更多相关文章
- C#面向对象设计模式纵横谈——1.面向对象设计模式与原则
一:设计模式简介 每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心. ---- Christopher Alexander 软件设计领域设计模式: 设计模式描述了软件设计过 ...
- [Head First设计模式]餐馆中的设计模式——命令模式
系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 [Head First设计模式]山西面馆中的设计模式——观察者模式 [Head First设计模式]山西面馆中的设计模式— ...
- 从零开始单排学设计模式「简单工厂设计模式」黑铁 III
阅读本文大概需要 2 分钟. 本篇是设计模式系列的第二篇,虽然之前也写过相应的文章,但是因为种种原因后来断掉了,而且发现之前写的内容也很渣,不够系统.所以现在打算重写,加上距离现在也有一段时间了,也算 ...
- java-23种设计模式概述【软件设计模式基本介绍(是什么、作用、优点)、模式的分类和介绍】
一.设计模式基本介绍(是什么.作用.优点) 1.软件设计模式是什么? 软件设计模式(Software Design Pattern),又称设计模式. 2.设计模式的作用 ★ 提高代码的可复用性.可维护 ...
- 1.设计模式第一步-《设计模式从头到脚舔一遍-使用C#实现》
更新记录: 完成第一次编辑:2022年4月23日20:29:33. 加入小黄人歌曲:2022年4月23日21:45:36. 1.1 设计模式(Design Pattern)是什么 设计模式是理论.是前 ...
- PHP设计模式三:原型设计模式
一.什么是原型设计模式 原型设计模式使用一种克隆技术来复制实例化的对象,新对象是通过复制原型实例创建的.原型设计模式的目的是通过使用克隆以减少 实例化对象的开销. 在原型设计模式中,Client类是不 ...
- Java基础-Java中23种设计模式之常用的设计模式
Java基础-Java中23种设计模式之常用的设计模式 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.设计模式分类 设计模式是针对特定场景给出的专家级的解决方案.总的来说设 ...
- java软件设计模式只单例设计模式
概述 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. 毫无疑问,设计 ...
- 1.2 《硬啃设计模式》 第2章 学习设计模式需掌握的UML知识
要看懂设计模式,你需要懂类图(Class Diagram),也需要懂一点对象图(Object Diagram),下面介绍一些UML的必要知识,以便你学习设计模式. 属性.操作 下图简单介绍类的属性和操 ...
- JavaScript设计模式之策略模式(学习笔记)
在网上搜索“为什么MVC不是一种设计模式呢?”其中有解答:MVC其实是三个经典设计模式的演变:观察者模式(Observer).策略模式(Strategy).组合模式(Composite).所以我今天选 ...
随机推荐
- ThreadPoolExecutor常识
线程池技术在并发时经常会使用到,java中的线程池的使用是通过调用ThreadPoolExecutor来实现的.ThreadPoolExecutor提供了四个构造函数,最后都会归结于下面这个构造方法: ...
- log4j每天,每小时产生一日志文件
log4j每天,每小时产生一日志文件 2016年08月05日 14:14:33 阅读数:6254 一.之前的文章中有log4j的相关配置以及属性的介绍,下面我们先把配置列出来: log4j.roo ...
- c语言指针数组和结构体的指针
指向数组的指针,先初始化一个数组,使用传统方式遍历 void main() { ] = { ,,,, }; ; i < ; i++) { printf("%d,%x\n", ...
- Linux CentOS6.6 NFS服务的配置与安装
一.简介 NFS(Network File System)即网络文件系统,是FreeBSD支持的文件系统中的一种,它允许网络中的计算机之间通过TCP/IP网络共享资源.在NFS的应用中,本地NFS的客 ...
- dede 复制文章,远程图片无法本地化
解决方法: 1.找到dede的后台目录,在后台目录下的inc下找到inc_archives_functions.php 2.搜索GetCurContent函数,找到如下这段代码: preg_match ...
- Castle ActiveRecord学习(二)配置、引用、程序启动
来源:http://www.cnblogs.com/zxj159/p/4082987.html 配置数据库驱动: Model层引用:Castle.ActiveRecord.dll.NHibernate ...
- js回车、ESC、F2按钮事件
<script type="text/javascript" language=JavaScript charset="UTF-8"> docume ...
- html转义字符对照表
常用的html转义字符 字符 描述 实体名称 实体编号 " quotation mark(双引号“半角”) " " ' apostrophe (单引号‘半角’) & ...
- OSGi 系列(十三)之 Configuration Admin Service
OSGi 系列(十三)之 Configuration Admin Service OSGi 的 CM 就是 Configuration Admin Service,是用于管理 Bundle 属性.并在 ...
- 【Maven】Nexus(Maven仓库私服)下载与安装
Nexus介绍 Nexus 是Maven仓库管理器,如果你使用Maven,你可以从Maven中央仓库 下载所需要的构件(artifact),但这通常不是一个好的做法,你应该在本地架设一个Maven仓库 ...