1 什么是设计模式
Christopher Alexander 说过: "每一个模式描述了一个在我们周围不断重复发生的问题, 以及该问题的解决方案的核心. 这样, 你就能一次又一次地使用该方案而不必做重复劳动". 尽管 Alexander 所指的是城市和建筑模式, 但他的思想也同样适用于面向对象设计模式. 只是在面向对象的解决方案里, 我们用对象和接口代替了墙壁和门窗. 两类模式的核心都在于提供了相关问题的解决方案.
基本要素
一般而言, 一个模式有四个基本要素:
-
模式名称( pattern name ) 一个助记名, 它用一两个词来描述模式的问题, 解决方法和效果. 命名一个新的模式增加了我们的设计词汇. 设计模式允许我们在较高的抽象层次上进行设计. 基于一个模式词汇表, 我们自己以及同事就可以讨论模式并在编写文档时使用它们. 模式名可以帮助我们思考, 便于我们与其他人交流设计思想及设计结果. 找到恰当的模式名也是设计模式编目工作的难点之一.
-
问题( problem ) 描述了应该在何时使用模式. 它解释了设计问题和问题存在的前因后果, 它可能描述了特定的设计问题, 如怎样用对象表示算法等. 也可能描述了导致不灵活设计的类或对象结构. 有时候, 问题部分会包括使用模式必须满足的一系列先决条件.
-
解决方案( solution ) 描述了设计的组成成分, 还有它们之间的相互关系及各自的职责和协作方式. 因为模式就是一个模板, 可应用于多种不同场合, 所以解决方案并不描述一个特定而具体的设计或实现, 而是提供设计问题的抽象描述和怎样用一个具有一般意义的元素组合(类或对象组合)来解决这个问题.
-
效果( consequence ) 描述了模式应用的效果及使用模式应权衡的问题. 尽管我们描述设计决策时, 并不总提到模式效果, 但它们对于评价设计选择和理解使用模式的代价及好处具有重要意义. 软件效果大多关注对时间和空间的衡量, 它们也表述了语言和实现问题. 因为复用是面向对象设计的要素之一, 所以模式效果包括它对系统的灵活性, 扩充性或可移植性的影响, 显示地列出这些效果对于理解和评价这些模式很有帮助.
出发点的不同会产生对什么是模式和什么不是模式的理解不同. 一个人的模式对另一个人来说可能只是基本构造部件. 我们以后将在一定的抽象层次上讨论模式, 来描述在特定场景下解决一般设计问题的类和相互通信的对象.
一个设计模式命名, 抽象和确定了一个通用设计结构的主要方面, 这些设计结构能被用来构造可复用的面向对象设计. 设计模式确定了所包含的类和实例, 它们的角色, 协作方式以及职责分配. 每一个设计模式都集中于一个特定的面向对象设计问题或设计要点, 描述了什么时候使用它, 在另一些设计约束条件下是否还能使用, 以及使用的效果和如何取舍. 既然我们最终要实现设计, 后面我们会提供示例代码来阐明其实现.
描述设计模式
我们怎么描述设计模式呢? 图形符号虽然很重要也很有用, 却还远远不够, 它们只是将设计过程的结果简单记录为类和对象之间的关系. 为了达到设计复用, 我们必须同时记录设计产生的过程, 选择过程和权衡过程. 具体的例子也很重要, 它们让你看到实际的设计.
我们将采用统一的格式描述设计模式, 每一个模式根据以下的模块被分成若干部分. 模板具有统一的信息描述结构, 有助于我们更容易地学习, 比较和使用设计模式.
-
模式名和分类
模式名简洁的描述了模式的本质. 一个好的名字非常重要, 因为它将成为你的设计词汇表中的一部分.
-
意图
是回答下列问题的简单陈述: 设计模式是做什么的? 它的基本原理和意图是什么? 它解决的是什么样的特定设计问题?
-
别名
模式的其他名称
-
动机
用以说明一个设计问题以及如何用模式中的类和对象来解决该问题的特定情景. 该情景会帮助你理解随后对模式更抽象的描述.
-
适用性
什么情况下可以使用该设计模式? 该模式可用来改进哪些不良设计? 你怎样识别这些情况?
-
结构
采用基于对象建模技术(OMT)的表示法对模式中的类进行图形描述. 我们也使用了交互图来说明对象之间的请求序列和协作关系.
-
参与者
指设计模式中的类和/或对象以及它们各自的职责.
-
协作
模式的参与者怎样协作以实现它们的职责.
-
效果
模式怎样支持它的目标? 使用模式的效果和所需做的权衡取舍? 系统结构的哪些方面可以独立改变?
-
实现
实现模式时需要知道的一些提示, 技术要点及应避免的缺陷, 以及是否存在某些特定于实现语言的问题.
-
代码示例
用来说明怎么实现该模式的代码片段.
-
已知应用
实际系统中发现的模式的例子. 每个模式至少包括了两个不同领域的实例.
-
相关模式
与这个模式紧密相关的模式有哪些? 其间重要的不同之处是什么? 这个模式应与那些其他模式一起使用?