design_patterns4
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第4章结构型模式
结构型模式涉及到如何组合类和对象以获得更大的结构。结构型类模式采用继承机制来组合接口或实现。一个简单的例子是采用多重继承方法将两个以上的类组合成一个类,结果这个类包含了所有父类的性质。这一模式尤其有助于多个独立开发的类库协同工作。另外一个例子是类形式的A d a p t e r(4.1)模式。一般来说,适配器使得一个接口( a d a p t e e的接口)与其他接口兼容,从而给出了多个不同接口的统一抽象。为此,类适配器对一个 a d a p t e e类进行私有继承。这样,适配器就可以用a d a p t e e的接口表示它的接口。
结构型对象模式不是对接口和实现进行组合,而是描述了如何对一些对象进行组合,从而实现新功能的一些方法。因为可以在运行时刻改变对象组合关系,所以对象组合方式具有更大的灵活性,而这种机制用静态类组合是不可能实现的。
Composite (4.3) 模式是结构型对象模式的一个实例。它描述了如何构造一个类层次式结构,这一结构由两种类型的对象(基元对象和组合对象)所对应的类构成. 其中的组合对象使得你可以组合基元对象以及其他的组合对象,从而形成任意复杂的结构。在Proxy (4.7) 模式中,p r o x y对象作为其他对象的一个方便的替代或占位符。它的使用可以有多种形式。例如它可以在局部空间中代表一个远程地址空间中的对象,也可以表示一个要求被加载的较大的对象,还可以用来保护对敏感对象的访问。P r o x y模式还提供了对对象的一些特有性质的一定程度上的间接访问,从而它可以限制、增强或修改这些性质。
F l y w e i g h t(4.6)模式为了共享对象定义了一个结构。至少有两个原因要求对象共享:效率和一致性。F l y w e i g h t的对象共享机制主要强调对象的空间效率。使用很多对象的应用必需考虑每一个对象的开销。使用对象共享而不是进行对象复制,可以节省大量的空间资源。但是仅当这些对象没有定义与上下文相关的状态时,它们才可以被共享。 F l y w e i g h t的对象没有这样的状态。任何执行任务时需要的其他一些信息仅当需要时才传递过去。由于不存在与上下文相关的状态,因此F l y w e i g h t对象可以被自由地共享。
如果说F l y w e i g h t模式说明了如何生成很多较小的对象,那么F a c a d e(4.5)模式则描述了如何用单个对象表示整个子系统。模式中的f a c a d e用来表示一组对象,f a c a d e的职责是将消息转发给它所表示的对象。B r i d g e(4.2)模式将对象的抽象和其实现分离,从而可以独立地改变它们。
D e c o r a t o r(4.4)模式描述了如何动态地为对象添加职责。D e c o r a t o r模式是一种结构型模式。这一模式采用递归方式组合对象,从而允许你添加任意多的对象职责。例如,一个包含用户界面组件的D e c o r a t o r对象可以将边框或阴影这样的装饰添加到该组件中,或者它可以将窗口滚动和缩放这样的功能添加的组件中。我们可以将一个D e c o r a t o r对象嵌套在另外一个对象中就可以很简单地增加两个装饰,添加其他的装饰也是如此。因此,每个 D e c o r a t o r对象必须与其组件的接口兼容并且保证将消息传递给它。D e c o r a t o r模式在转发一条信息之前或之后都可以完成它的工作(比如绘制组件的边框)。
许多结构型模式在某种程度上具有相关性,我们将在本章末讨论这些关系。
4.1 ADAPTER(适配器)—类对象结构型模式
1. 意图
将一个类的接口转换成客户希望的另外一个接口。A d a p t e r模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
2. 别名
包装器Wr a p p e r。
3. 动机
有时,为复用而设计的工具箱类不能够被复用的原因仅仅是因为它的接口与专业应用领域所需要的接口不匹配。
例如,有一个绘图编辑器,这个编辑器允许用户绘制和排列基本图元(线、多边型和正文等)生成图片和图表。这个绘图编辑器的关键抽象是图形对象。图形对象有一个可编辑的形状,并可以绘制自身。图形对象的接口由一个称为S h a p e的抽象类定义。绘图编辑器为每一种图形对象定义了一个S h a p e的子类:L i n e S h a p e类对应于直线,P o l y g o n S h a p e类对应于多边型,等等。
像L i n e S h a p e和P o l y g o n S h a p e这样的基本几何图形的类比较容易实现,这是由于它们的绘图和编辑功能本来就很有限。但是对于可以显示和编辑正文的Te x t S h a p e子类来说,实现相当困难,因为即使是基本的正文编辑也要涉及到复杂的屏幕刷新和缓冲区管理。同时,成品的用户界面工具箱可能已经提供了一个复杂的Te x t V i e w类用于显示和编辑正文。理想的情况是我们可以复用这个Te x t V i e w类以实现Te x t S h a p e类,但是工具箱的设计者当时并没有考虑S h a p e的存在,因此Te x t V i e w和S h a p e对象不能互换。
一个应用可能会有一些类具有不同的接口并且这些接口互不兼容,在这样的应用中象Te x t V i e w这样已经存在并且不相关的类如何协同工作呢?我们可以改变Te x t V i e w类使它兼容S h a p e类的接口,但前提是必须有这个工具箱的源代码。然而即使我们得到了这些源代码,修改Te x t V i e w也是没有什么意义的;因为不应该仅仅为了实现一个应用,工具箱就不得不采用一些与特定领域相关的接口。
我们可以不用上面的方法,而定义一个Te x t S h a p e类,由它来适配Te x t V i e w的接口和S h a p e 的接口。我们可以用两种方法做这件事:1) 继承S h a p e类的接口和Te x t V i e w的实现,或2) 将一个Te x t V i e w实例作为Te x t S h a p e的组成部分,并且使用Te x t V i e w的接口实现Te x t S h a p e。这两种
A d a p t e r模式的类和对象版本。我们将Te x t S h a p e称之为适配器A d a p t e r。
方法恰恰对应于