一 Adapter模式
意图:
将一个类的接口转换成客户希望的另外一个接口。
Adapter模式使得原本由于接口不兼容而不能在一起工作的那些类可以在一起工作。
适用性:
- 使用一个已存在的类,而它的接口不符合你的要求;
- 你想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配他们的接口,而是使用对象适配器适配他们的父类接口;
- 你想创建一个可以复用的类,该类可以与其他不相关的类或者不可预见的类(接口可能不一定兼容的类)协同工作;
看看其结构图:
这是一个对象适配器结构图;
其实类似这样的类结构图(一个类包含了另一个类的实例并使用其中的方法等)是很多的:
是不是只要具备这样的结构都可以称之为Adapter模式呢?
Adapter有两种形式:对象适配器和类适配器。
这是一个类适配器结构图;
理解:
从继承的角度来理解:Adapter既然能够继承了Adaptee,那么可以认为Adapter就是一个Adaptee,
只有具备这样的关系才可以继承。但是对于Java中的接口可能不同,接口仅仅只是一些列方法声明的集合。
但是如果一个类实现了某个接口XXX,我们说这个类是一个XXX,这样似乎也是不合理的;接口实现是继承也不是,
对Java的接口这个地方搞的不是很明白感觉有些不严密。
所以并不是具备了这样的类结构都可以称之为Adapter模式;Target和Adaptee之间的关系就是:
有一个新的Target想要使用Adaptee提供的接口,但是不能直接使用需要对其进行改造,于是进行扩展——Adapter模式。
如果Target是一个抽象类,Adaptee也是一个抽象类,那么结果将是什么样子呢。
Adapter的目的就是为连接Target和Adaptee而生。
使之扩展的余地变得更灵活更广阔,那这还是Adapter模式吗?暂且不管往下走。
下面通过学习Android中的AdapterView和Adapter对于 Adapter模式和Bridge模式的应用,
来理解Adapter模式和Bridge模式的应用上的经典设计实例。
二 Android中AdapterView显示分析
看一下两个类:
AdapterView(定义public abstract class AdapterView<T extends Adapter> extends ViewGroup,
<>是Java的泛型,表示T的类型必须是Adapter或其派生类):抽象的ViewGroup类;
Adapter(public interface Adapter):一个接口,是AdapterView和Data的桥梁。
看看一个ListView显示需要的条件:
l 对象控制,属性设置,事件派发处理
对于对象控制事件处理等属于ViewGroup系统提供稳定的维护和控制方式,也会提供于我们接口去控制某些东西;
l 显示布局控件ViewItem,属性等
对于显示上所用的控件布局,系统可能提供缺省的,但是这里我们使用自己的方式的去提供的可能性非常的大;
l 显示数据Data
对于数据明显只能是我们动态的提供。
从代码中可以看到AdapterView及其派生类是系统提供用于显示控制,属性设置,事件派发处理等,是显示的控制中心;
Adapter派生类是提供显示ViewItem和Data。具体了解可以看看源代码。
这两个一个是抽象类一个是接口,所以需要做的就是连接这两个类实现SubAdapterView的显示——Adapter模式。
下面学习一下ListView的大概结构及Adapter模式的应用。
三 Android中ListView的Adapter模式应用
看一下ListView与ListAdapter的结构图:
AbListView与LIstAdapter就是一个Adapter模式的应用。
AbListView:抽象类;
ListAdapter:接口;
这还是Adapter模式吗:
哈哈,到这里我突然间茫然了,这还是一个Adapter模式吗!怎么看都更像是一个Bridge模式了。
看来理解还是不深刻啊,一是受名称所严重欺骗,二是感觉结构实在和Adapter也很像(将两个类通过对象适配一起工作满足新的应用)。
搞了大半天我实在不想推翻自己无奈……设计模式学习过程中理解太肤浅了。
Adapter模式里面的适用性所提到:你想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配他们的接口。
但是可以适配它的父类接口。从这样理解似乎也没有错啊:我们现在匹配的就是ListAdapter子类。
既然可以匹配父类适配子类,那么为什么又不可以匹配AblistView以适应子类呢?那这样的结果就是两边都是抽象类或者接口;
那这到底是哪一个模式呢。
下面看一下Bridge模式的描述。
四 AbListView及ListAdapter和Bridge模式
先看看Bridge模式:
意图:
将抽象部分与它的实现部分分离,使它们都可以独立的变化。
抽象部分AbListView:派生类有ListView,GridView等;
实现部分ListAdapter:派生类有SimpleAdapter,CursorAdapter等;
满足了定义中将抽象部分与实现部分分离的原则;
适用性:
你不希望在抽象类和它的实现部分之间有一个固定的绑定关系;
类的抽象以及它的实现都应该通过生成子类的方法加以扩充;
抽象类的实现部分修改应该对客户不产生影响;
多个对象之间实现共享;
结构图:
与AbListView和ListAdapter图比较一下:
两个图结构是不是基本上就是一样的呢?
Adapter与Bridge比较:
看看书中对于这两个模式的比较:
Adapter模式用来帮助无关的类协同工作,它通常是在系统设计完成之后才会被使用;
Bridge模式则是在系统设计开始的时候就被使用,它使得抽象接口和实现部分可以独立的进行改变。
实际分析:
那么此中的设计会是在设计完成之后发现不对劲,使用Adapter模式来帮助这些类协同工作的吗,
很明显是在设计之前就已经确定了框架是要如此设计。而且AbListView和ListAdapter是不相关的类吗?
明显非常相关的两个类,关系紧密结合亲密无间。
Bridge模式要抽象和实现分离:
是因为其中存在两个两个变化的因素;抽象会有多个派生类,实现也会有多个依赖。
在AbListView和ListAdapter结构中:有多个AbListView派生类,也有多个ListAdapter实现。
不管是AblistView派生出新的类还是ListAdapter派生出新的类,都不会对对方产生影响,互相修改也不会互相影响,
AblistViewListAdapter之间是没有固定的绑定关系,很容易通过派生新的子类对应用加以扩充。
综上所述,AbListView和ListAdapter结构设计应当属于Bridge模式。
Adapter模式和Bridge同属于结构性模式,结构图看似差别很大,但其实这两个模式给我感觉很相似,
通过这里的学习有一些理解了其实是有很大不同的。