design partterns--introduction

我们根据两条准则(表1 - 1 )对模式进行分类。

第一是目的准则,即模式是用来完成什么工作的。模式依据其目的可分为创建型(C r e a t i o n a l) 、结构型 ( S t r u c t u r a l )、或行为型
( B e h a v i o r a l )三种。创建型模式与对象的创建有关;结构型模式处理类或对象的组合;行为型
模式对类或对象怎样交互和怎样分配职责进行描述。
第二是范围准则,指定模式主要是用于类还是用于对象。类模式处理类和子类之间的关
系,这些关系通过继承建立,是静态的,在编译时刻便确定下来了。对象模式处理对象间的
关系,这些关系在运行时刻是可以变化的,更具动态性。从某种意义上来说,几乎所有模式
都使用继承机制,所以“类模式”只指那些集中于处理类间关系的模式,而大部分模式都属
于对象模式的范畴。
创建型类模式将对象的部分创建工作延迟到子类,而创建型对象模式则将它延迟到另一
个对象中。结构型类模式使用继承机制来组合类,而结构型对象模式则描述了对象的组装方
式。行为型类模式使用继承描述算法和控制流,而行为型对象模式则描述一组对象怎样协作
完成单个对象所无法完成的任务。
还有其他组织模式的方式。有些模式经常会被绑在一起使用,例如, C o m p o s i t e常和
I t e r a t o r或Vi s i t o r一起使用;有些模式是可替代的,例如, P r o t o t y p e常用来替代 A b s t r a c t
F a c t o r y;有些模式尽管使用意图不同,但产生的设计结果是很相似的,例如, C o m p o s i t e和
D e c o r a t o r的结构图是相似的。

1 寻找合适的对象

面向对象程序由对象组成,对象包括数据和对数据进行操作的过程,过程通常称为方法或操作。对象在收到客户的请求(或消息)后,执行相应的操作。

2 决定对象的粒度
对象在大小和数目上变化极大。它们能表示下自硬件或上自整个应用的任何事物。那么
我们怎样决定一个对象应该是什么呢?
设计模式很好地讲述了这个问题。 F a c a d e ( 4 . 5 )模式描述了怎样用对象表示完整的子系统,
F l y w e i g h t ( 4 . 6 )模式描述了如何支持大量的最小粒度的对象。其他一些设计模式描述了将一个
对象分解成许多小对象的特定方法。 Abstract Factory(3.1)和B u i l d e r ( 3 . 2 )产生那些专门负责生
成其他对象的对象。Vi s i t o r ( 5 . 1 0 )和C o m m a n d ( 5 . 2 )生成的对象专门负责实现对其他对象或对象
组的请求。

3指定对象接口
对象声明的每一个操作指定操作名、作为参数的对象和返回值,这就是所谓的操作的型
构( s i g n a t u r e )。对象操作所定义的所有操作型构的集合被称为该对象的接口( i n t e r f a c e )。对象
接口描述了该对象所能接受的全部请求的集合,任何匹配对象接口中型构的请求都可以发送
给该对象。
类型(type) 是用来标识特定接口的一个名字。如果一个对象接受“ Wi n d o w”接口所定义
的所有操作请求,那么我们就说该对象具有“ Wi n d o w”类型。一个对象可以有许多类型,并
且不同的对象可以共享同一个类型。对象接口的某部分可以用某个类型来刻画,而其他部分
则可用其他类型刻画。两个类型相同的对象只需要共享它们的部分接口。接口可以包含其他
接口作为子集。当一个类型的接口包含另一个类型的接口时,我们就说它是另一个类型的子
类型( s u b t y p e ),另一个类型称之为它的超类型( s u p e r t y p e )。我们常说子类型继承了它的超类型
的接口。

在面向对象系统中,接口是基本的组成部分。对象只有通过它们的接口才能与外部交流,
如果不通过对象的接口就无法知道对象的任何事情,也无法请求对象做任何事情。对象接口
与其功能实现是分离的,不同对象可以对请求做不同的实现,也就是说,两个有相同接口的
对象可以有完全不同的实现。
当给对象发送请求时,所引起的具体操作既与请求本身有关又与接受对象有关。支持相
同请求的不同对象可能对请求激发的操作有不同的实现。发送给对象的请求和它的相应操作
在运行时刻的连接就称之为动态绑定(dynamic binding)。
动态绑定是指发送的请求直到运行时刻才受你的具体的实现的约束。因而,在知道任何
有正确接口的对象都将接受此请求时,你可以写一个一般的程序,它期待着那些具有该特定
接口的对象。进一步讲,动态绑定允许你在运行时刻彼此替换有相同接口的对象。这种可替
换性就称为多态( p o l y m o r p h i s m ),它是面向对象系统中的核心概念之一。多态允许客户对象仅
要求其他对象支持特定接口,除此之外对其假设几近于无。多态简化了客户的定义,使得对
象间彼此独立,并可以在运行时刻动态改变它们相互的关系。
设计模式通过确定接口的主要组成成分及经接口发送的数据类型,来帮助你定义接口。
设计模式也许还会告诉你接口中不应包括哪些东西。 M e m e n t o ( 5 . 6 )模式是一个很好的例子,
它描述了怎样封装和保存对象内部的状态,以便一段时间后对象能恢复到这一状态。它规定
了M e m e n t o对象必须定义两个接口:一个允许客户保持和复制 m e m e n t o的限制接口,和一个只
有原对象才能使用的用来储存和提取m e m e n t o中状态的特权接口。
设计模式也指定了接口之间的关系。特别地,它们经常要求一些类具有相似的接口;或
它们对一些类的接口做了限制。例如, D e c o r a t o r ( 4 . 4 )和P r o x y ( 4 . 7 )模式要求D e c o r a t o r和P r o x y
对象的接口与被修饰的对象和受委托的对象一致。而 Vi s i t o r ( 5 . 11 )模式中,Vi s i t o r接口必须反
映出v i s i t o r能访问的对象的所有类。

1. 类继承与接口继承的比较
理解对象的类( c l a s s )与对象的类型( t y p e )之间的差别非常重要。
一个对象的类定义了对象是怎样实现的,同时也定义了对象的内部状态和操作的实现。
但是对象的类型只与它的接口有关,接口即对象能响应的请求的集合。一个对象可以有多个类型,不同类的对象可以有相同的类型。
当然,对象的类和类型是有紧密关系的。因为类定义了对象所能执行的操作,也定义了
对象的类型。当我们说一个对象是一个类的实例时,即指该对象支持类所定义的接口。
C + +和E i ff e l语言的类既指定对象的类型又指定对象的实现。 S m a l l t a l k程序不声明变量的
类型,所以编译器不检查赋给变量的对象类型是否是该变量的类型的子类型。发送消息时需
要检查消息接收者是否实现了该消息,但不检查接收者是否是某个特定类的实例。
理解类继承和接口继承(或子类型化)之间的差别也十分重要。类继承根据一个对象的实现
定义了另一个对象的实现。简而言之,它是代码和表示的共享机制。然而,接口继承 (或子类
型化)描述了一个对象什么时候能被用来替代另一个对象。
因为许多语言并不显式地区分这两个概念,所以容易被混淆。在 C + +和E i ff e l语言中,继
承既指接口的继承又指实现的继承。 C + +中接口继承的标准方法是公有继承一个含 (纯)虚成员
函数的类。C + +中纯接口继承接近于公有继承纯抽象类,纯实现继承或纯类继承接近于私有
继承。S m a l l t a l k中的继承只指实现继承。只要任何类的实例支持对变量值的操作,你就可以
将这些实例赋给变量。

2. 对接口编程,而不是对实现编程
类继承是一个通过复用父类功能而扩展应用功能的基本机制。它允许你根据旧对象快速
定义新对象。它允许你从已存在的类中继承所需要的绝大部分功能,从而几乎无需任何代价
就可以获得新的实现。
然而,实现的复用只是成功的一半,继承所拥有的定义具有相同接口的对象族的能力也
是很重要的(通常可以从抽象类来继承)。为什么?因为多态依赖于这种能力。
当继承被恰当使用时,所有从抽象类导出的类将共享该抽象类的接口。这意味着子类仅
仅添加或重定义操作,而没有隐藏父类的操作。这时,所有的子类都能响应抽象类接口中的
请求,从而子类的类型都是抽象类的子类型。
只根据抽象类中定义的接口来操纵对象有以下两个好处:
1) 客户无须知道他们使用对象的特定类型,只须对象有客户所期望的接口。
2) 客户无须知道他们使用的对象是用什么类来实现的,他们只须知道定义接口的抽象类。
这将极大地减少子系统实现之间的相互依赖关系,也产生了可复用的面向对象设计的如
下原则:
针对接口编程,而不是针对实现编程。
不将变量声明为某个特定的具体类的实例对象,而是让它遵从抽象类所定义的接口。这
是本书设计模式的一个常见主题。
当你不得不在系统的某个地方实例化具体的类 (即指定一个特定的实现 )时,创建型模式

(Abstract Factory(3.1),B u i l d e r ( 3 . 2 ),Factory Method(3.3),P r o t o t y p e ( 3 . 4 )和S i n g l e t o n ( 3 . 5 ) )可
以帮你。通过抽象对象的创建过程,这些模式提供不同方式以在实例化时建立接口和实现的
透明连接。创建型模式确保你的系统是采用针对接口的方式书写的,而不是针对实现而书写
的。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值