android设计模式的使用之适配器模式
2016-04-21 22:25
429 查看
一.适配器模式
适配器模式的描述:将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
那么一个适配的过程包括了以下的这四个部分:
使用者Client。
目标接口Target
被适配者Adaptee
适配器Adapter
适用场景:
1. 目前的接口Target不符合我们的需求。比如我们还需要Adaptee中的一些功能。
2. 复用代码。目标接口Target和被适配者Adaptee都是不能轻易修改的。
3. 如果使用者Client想要实现以上两点,那么Client就得实现Target和继承Adaptee,或者实现Target和委托Adaptee来实现。但
是,这样Client就耦合了Target和Adaptee,不方便维护和复用。那么,本该Client来实现的这些就由适配器Adapter来完成
了,Client只要调用适配器Adapter就可以了。而Adapter是目标接口Target的实现,经过向上转型:Target mTarget = new
Adapter(),正好对应了描述”将一个类的接口转换成客户希望的另外一个接口”,而Target和Adaptee是两个互不相干的类(接
口),但是在Adapter中却能在一起工作。
适配器模式的实现方式:
类适配器
对象适配器
区别:类适配器使用多继承方式(extends,implements)来实现,而对象适配器使用委托的方式来实现(委托Adaptee进行连接)。由于类适配器使用了继承方式,所以适用范围不大,如果被适配者Adaptee改变的情况下,我们就需要重新定义适配器Adapter了。而对象适配器则不同,我们可以传入不同的被适配者Adaptee而不用重写Adapter,适用性大大的提高了。
例子:
使用者Client-------------------电视TV(4脚插头)
目标接口Target---------------插头
被适配者Adaptee------------插座(只有2孔,3孔)
适配器Adapter---------------多孔适配器
类适配器的实现需要支持多继承。在java中,多继承一般用extends和implements来共同完成。代码如下:
对象适配器
对象适配器跟类适配器的差别在于适配器Adapter的实现上稍有不同,它的Adaptee不是靠继承来获取的,而且通过构造方法传入的。如下:
二.适配器模式在android中的使用
了解了适配器模式后,我们可以来看看android的源码中最常见的适配器例子:listview的适配器Adapter。按照上面的适配器组成,我们也来划分一下:
使用者Client--------------ListView
目标接口Target----------继承于Adapter的ListAdapter
被适配者Adaptee-------数据源,List<T>
适配器Adaper------------继承于BaseAdapter的各种子类ArrayAdapter,CursorAdapter等
Listview适配数据的使用如下:
这里使用了ArrayAdapter这个适配器来说明。android.R.layout.simple_list_item_1是android自带的TextView布局,new ArrayList(Arrays.asList(data))为被适配者Adaptee,也就是数据源。
mListView.setAdapter(mArrayAdapter)真正适配的过程。在使用者Client的角度上是跟我们的例子是很相像的:
主要区别在于为了适配各种类型的数据,android定义了很多listview的适配器,而且在适配的过程中处理的业务非常多。具体的在复习到listview的适配器的时候再写。盗张图:
适配器模式的描述:将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
那么一个适配的过程包括了以下的这四个部分:
使用者Client。
目标接口Target
被适配者Adaptee
适配器Adapter
适用场景:
1. 目前的接口Target不符合我们的需求。比如我们还需要Adaptee中的一些功能。
2. 复用代码。目标接口Target和被适配者Adaptee都是不能轻易修改的。
3. 如果使用者Client想要实现以上两点,那么Client就得实现Target和继承Adaptee,或者实现Target和委托Adaptee来实现。但
是,这样Client就耦合了Target和Adaptee,不方便维护和复用。那么,本该Client来实现的这些就由适配器Adapter来完成
了,Client只要调用适配器Adapter就可以了。而Adapter是目标接口Target的实现,经过向上转型:Target mTarget = new
Adapter(),正好对应了描述”将一个类的接口转换成客户希望的另外一个接口”,而Target和Adaptee是两个互不相干的类(接
口),但是在Adapter中却能在一起工作。
适配器模式的实现方式:
类适配器
对象适配器
区别:类适配器使用多继承方式(extends,implements)来实现,而对象适配器使用委托的方式来实现(委托Adaptee进行连接)。由于类适配器使用了继承方式,所以适用范围不大,如果被适配者Adaptee改变的情况下,我们就需要重新定义适配器Adapter了。而对象适配器则不同,我们可以传入不同的被适配者Adaptee而不用重写Adapter,适用性大大的提高了。
例子:
使用者Client-------------------电视TV(4脚插头)
目标接口Target---------------插头
被适配者Adaptee------------插座(只有2孔,3孔)
适配器Adapter---------------多孔适配器
类适配器的实现需要支持多继承。在java中,多继承一般用extends和implements来共同完成。代码如下:
/** * TV表示电视类,如果这时来一个电脑类,我就不用重写代码了,直接调用适配器Adapter,告诉它我几孔插头就可以了。 */ public class TV { public static void main(String []args){ int type = 4; System.out.println("这是" + type + "孔插头,正在尝试通电..."); //Connect mConnect = new Adapter(new Adaptee()); Connect mConnect = new Adapter(); mConnect.connect(type); } } /* * 目标接口:(表示这是一个插头) * */ interface Connect{ public void connect(int type); } /* * 被适配着,也叫源角色。(表示这是一个插座,只能使用2孔和3孔) * */ class Adaptee{ //这个插座可以使用两孔插头 public void twoHoldsocket(){ System.out.println("这是一个两孔插座"); } //这个插座可以使用三孔插头 public void threeHoldsocket(){ System.out.println("这是一个三孔插座"); } } /* *类适配器,用extends和implements来实现多继承。(表示这是一个适配器,可以适配各种多孔) * */ class Adapter extends Adaptee implements Connect{ @Override public void connect(int type) { switch (type){ //当插头是两孔时,符合插座的使用标准 case 2: this.twoHoldsocket(); System.out.println("找到" + type + "孔插座,可以匹配,通电成功"); break; //当插头是三孔时,符合插座的使用标准 case 3: this.threeHoldsocket(); System.out.println("找到" + type + "孔插座,可以匹配,通电成功"); break; /*当插头是其他孔时,此插座将不能用,需要使用适配器。蛤?那适配器在哪? *本类就是一个适配器,只要调用我这个connect()方法,我想让它支持几孔都可以。 * 没见我default代码的执行吗,来100孔插头,我都能把它转换成三孔的标准连接通电,屌吧。 */ default: this.threeHoldsocket(); System.out.println("没有找到" + type + "孔插座,必须通过适配器通电成功"); break; } } }
对象适配器
对象适配器跟类适配器的差别在于适配器Adapter的实现上稍有不同,它的Adaptee不是靠继承来获取的,而且通过构造方法传入的。如下:
/** * TV表示电视类,如果这时来一个电脑类,我就不用重写代码了,直接调用适配器Adapter,告诉它我几孔插头就可以了。 */ public class TV { public static void main(String []args){ int type = 4; System.out.println("这是" + type + "孔插头,正在尝试通电..."); //Connect mConnect = new Adapter(new Adaptee()); Connect mConnect = new Adapter(new Adaptee()); mConnect.connect(type); } } /* * 目标接口:(表示这是一个插头) * */ interface Connect{ public void connect(int type); } /* * 被适配着,也叫源角色。(表示这是一个插座,只能使用2孔和3孔) * */ class Adaptee{ //这个插座可以使用两孔插头 public void twoHoldsocket(){ System.out.println("这是一个两孔插座"); } //这个插座可以使用三孔插头 public void threeHoldsocket(){ System.out.println("这是一个三孔插座"); } } /* *类适配器,用extends和implements来实现多继承。(表示这是一个适配器,可以适配各种多孔) * */ class Adapter implements Connect{ private Adaptee mAdaptee; public Adapter(Adaptee mAdaptee){ this.mAdaptee = mAdaptee; } @Override public void connect(int type) { switch (type){ //当插头是两孔时,符合插座的使用标准 case 2: mAdaptee.twoHoldsocket(); System.out.println("找到" + type + "孔插座,可以匹配,通电成功"); break; //当插头是三孔时,符合插座的使用标准 case 3: mAdaptee.threeHoldsocket(); System.out.println("找到" + type + "孔插座,可以匹配,通电成功"); break; /*当插头是其他孔时,此插座将不能用,需要使用适配器。蛤?那适配器在哪? *本类就是一个适配器,只要调用我这个connect()方法,我想让它支持几孔都可以。 * 没见我default代码的执行吗,来100孔插头,我都能把它转换成三孔的标准连接通电,屌吧。 */ default: mAdaptee.threeHoldsocket(); System.out.println("没有找到" + type + "孔插座,必须通过适配器通电成功"); break; } } }
二.适配器模式在android中的使用
了解了适配器模式后,我们可以来看看android的源码中最常见的适配器例子:listview的适配器Adapter。按照上面的适配器组成,我们也来划分一下:
使用者Client--------------ListView
目标接口Target----------继承于Adapter的ListAdapter
被适配者Adaptee-------数据源,List<T>
适配器Adaper------------继承于BaseAdapter的各种子类ArrayAdapter,CursorAdapter等
Listview适配数据的使用如下:
<span style="font-size:14px;">String data[] = {"1","2","3","4","5","6","7","8","9","0"}; ListView mListView = (ListView)findViewById(R.id.listview); ArrayAdapter mArrayAdapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,new ArrayList(Arrays.asList(data))); mListView.setAdapter(mArrayAdapter); </span>
这里使用了ArrayAdapter这个适配器来说明。android.R.layout.simple_list_item_1是android自带的TextView布局,new ArrayList(Arrays.asList(data))为被适配者Adaptee,也就是数据源。
mListView.setAdapter(mArrayAdapter)真正适配的过程。在使用者Client的角度上是跟我们的例子是很相像的:
Connect mConnect = new Adapter(new Adaptee()); mConnect.connect(4); </span>
主要区别在于为了适配各种类型的数据,android定义了很多listview的适配器,而且在适配的过程中处理的业务非常多。具体的在复习到listview的适配器的时候再写。盗张图:
相关文章推荐
- Android简单的调用系统相机和相册
- 命令行创建Android应用,命令行生成签名文件,命令行查看签名信息,对APK包签名并编译运行
- Android ADB 端口占用问题解决方案
- Android 学习笔记之一 Status Bar Notifications
- Android Scroll详解(三):Android 绘制过程详解
- android tv开发adb 命令
- android 更加复杂的小鱼游
- android 小鱼在水中游
- Android实现图片自动轮播并且支持手势左右无限滑动
- Fragment使用方法总结
- 最详细的 Android Toolbar 开发实践总结
- Android事件分发机制
- Android学习笔记--Intent
- Java(Android)线程池
- Android 短信箱操作
- Android隐藏以及显示软键盘以及不自动弹出键盘的方法
- Android 使用WebView显示网页
- 生成android的keystore文件有以下两种方法:
- Android通过PendingIntent实现消息通知
- Android基础:获取手机联系人工具类