设计模式笔记

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

设计模式笔记

2017-02-07

| 导语“计算机科学领域的任何问题都可以通过增加一个间接的中间层来解决” “Any problem in computer science can be solved by anther layer of indirection.”

设计模式这个词源于城市建筑设计,由Alexander提出:“每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心”。引用《head first设计模式》书中的一句话--“把模式装进脑子里,然后在你的设计和已有的应用中,寻找何处可以使用它们”。也就是说学习设计模式不能纸上谈兵,学习新的设计模式,要去思考在以前的代码中哪里可以用到。并且对比设计模式之间的差异来加深理解。

设计模式分为三类,创建型,结构型和行为型。创建型比较好理解,它抽象了实例化过程,将系统与实例的创建解耦。实例由专门的工厂来创建,从而使系统针对实例的抽象接口编程,不依赖任何具体的实现。结构型和行为型有点难以理解,GoF的解释是,结构型模式涉及到如何组合类和对象以获得更大的结构;行为模式涉及到算法和对象间职责的分配。行为模式不仅描述对象或类的模式,还描述它们之间的通信模式。

总体来说设计模式分为三大类:

创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

大部分行为型和结构型设计模式的特点还是挺明显的,但是有少部分的界限就没那么清晰。比如说代理模式属于结构型模式,但是它也承担了职责的分配。它通过一个代理类,直接处理客户请求,但是把大部分实际职责交给原始的工作类。将设计模式划分为三种类型,可以理解为是划分出一种层级,帮助模式的使用者记忆和理解。

GoF提到的23种设计模式中有的特点是比较鲜明的,它们有明显的中间层,并且与其它设计模式不容易混淆,但是有的却不那么容易理解其意图。下面就按照是否容易理解分成两类来记录这些设计模式。

那些容易理解,有明显中间层的设计模式

单件模式

单件模式很好理解,就是这么一个类,它在任何情况下都只会产生一个实例(多线程异常情况除外)。当然只会产生一个实例不是绝对的,我们可以改成只会产生两个或者任何其它有限个。单件模式的产生就是为了取代我们之前使用全局变量的情况。直接使用全局变量有很多局限性,比如可能会被实例化多次,不能灵活扩展成多个,难以支持延迟实例化(就是到真正使用时才实例化)等。

中间层的思考:单件模式在系统和全局变量之间中添加了一个中间层,之前系统直接调用全局变量,而使用单件模式后,系统使用类静态方法Instance来获取全局实例。在Instance函数中可以做很多事情,包括延迟实例以及指定实例数量,甚至返回不同的子类实例。

适配器模式

下图这个转接头就是适配器最好的例子。香港的iphone插头是三个脚的,而内地的插头却是两个脚的,香港插头没法直接插到我们平时使用的插板上面。一般会去淘宝上面买个转接头,这个转接头的一面可以插入香港的插头,另一面可以插到我们平时使用的两脚插板上去,完美地解决了香港插头和内地插板不适配的问题。

适配器模式要解决的就是新加模块与系统已有接口不匹配的问题。通过新增一个适配器Adapter,它保存一个新模块Adaptee的实例,并向外提供系统已有接口,适配器Adapter内部使用新模块Adaptee的实例来实现系统接口。

中间层的思考:适配器模式在新加模块和已有系统之间加入了一个中间层-- Adapter,来解决接口不兼容的问题。比如我们如果要在系统中新加一种网络日

志,网络日志库提供了一套与系统中已有的本地日志库不一样的接口,此时就可以添加一个适配层,将网络日志库进行封装,提供一套与已有本地日志库一样的接口,这样系统可以轻松地在本地日志库和网络日志库之间切换,而不用修改太多代码。

外观模式

从外观模式这个名字没法直观看出它到底是做什么的,消息后台有一个注册代理就是外观模式的一个例子。在它注册代理存在以前,手Q4.5从登陆到拉完全部消息并更新消息Tab耗时会超过30秒,因为手Q登陆需要负责向消息后台分别拉取未读好友消息和群讨论消息,拉取群/讨论组的消息比较复杂,需要先拉去一遍群组seq,然后同本地每一个群组seq比较判断出哪些群组有未读消息,再分别去把未读群组消息拉回来。整个过程非常复杂和耗时。为了解决这个问题,消息后台搭建了一个注册代理模式,手Q登陆只需要发一个登陆请求给注册代理,注册代理会把上述拉消息的脏活累活全都干了,把最终的结果返回给手Q,这样手Q的登陆时间缩小到了几秒。这里注册代理就相当于外观模式,它向手Q屏蔽了消息后台关于好友消息和群/讨论组的复杂细节,只暴露给手Q一个简单的请求和回复包接口。

中间层的思考:很明显可以看出外观模式的中间层就是在客户和复杂的子系统之间提供了一套简洁的接口,让客户对子系统的了解程度和耦合达到最小。在外观模式中也不会限制客户直接使用子系统类,但这会增加耦合性,所以需要在系统的易用和可扩展性之间作出取舍。

模式迷思:有没有觉得外观模式和适配器模式有点像?它们都提供了一个中间层,中间层负责封装了一些对象,然后提供了一套接口,做的事情简直一模一样!冷静想一想,这两个模式的结构确实是基本上一致的,但是它们的目的却完全不一样。适配器模式的目的是为了兼容新模块和老系统,而加入中间层做适配。而外观模式的目的是为了降低系统使用某个外接系统的成本和耦合。再看看设计模式的定义--“每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心”。也就是说设计模式是由两部分组成的,即它描述的问题以及解决方案。两个设计模式的解决方案可能是相同的,甚至可以说所有设计模式的解决方案都是相同的(添加中间层),但是所有设计模式描述的问题绝对是不相同的。后续还

相关文档
最新文档