1 模式定义
将一个类的接口转换成客户希望的另外一个接口,Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作
2 应用场景
- 系统需要使用现有的类,而此类的接口不符合系统的需要,即接口不兼容
- 想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的一些类一起工作
- 需要一个统一的输出接口,而输入端的接口不可预知
3 .1 组成部分
- 目标角色(Target):客户所期待的接口。目标可以是具体的或抽象的类,也可以是接口(注意:在类适配器模式中它只能是接口,目标角色不可以是类。)
- 源角色(Adaptee): 也是被适配的角色(需要被适配者)
- 适配器角色(Adapter):通过包装一个需要适配的对象,把源接口转换成目标接口,这一角色不可以是接口,必须是具体类
3.2 模式分类
- 类适配器和对象适配器,这两种的区别在于实现方式上的不同,一种采用继承,一种采用组合的方式。
- 类适配器:通过继承需要被适配者(extends Adaptee)
对象适配器:直接将需要被适配者的对象传递到适配器类里面,并且适配器类实现目标的接口,从而在内部进行接口的转换,组合的形式实现接口兼容的效果
对象适配模式
类适配模式
4 场景说明
电源适配器,笔记本电脑的电源一般在5V电压,但是在我们生活中的电线电压一般是220V。显然是不能直接接线笔记本上通电的,傻子都知道那样会把笔记本烧坏,所以就需要一个笔记本的电源适配器把220V转换成5V电压,在软件开发中称为接口不兼容,此时就需要适配器来进行一个接口转换.
5 示例代码:
5.1类适配器
//Target 目标接口
public interface Target5 {
public void V5();
}
//Adaptee 需要被适配者
public class Adaptee220 {
public void V220(){
System.out.println("220V");
}
}
//适配器
public class Adapter extends Adaptee220 implements Target5{
@Override
public void V5() {
// TODO Auto-generated method stub
System.out.println("5V");
}
}
//客户测试类
public class ClientMain {
public static void main(String[] args) {
Adapter adapter = new Adapter();
adapter.V5();
adapter.V220();
}
}
打印输出:
对象适配器
新建一个对象适配器封装类
public class ObjectAdapter implements Target5{
public Adaptee220 mAdaptee220;
public void setAdaptee220(Adaptee220 mAdaptee220){
this.mAdaptee220 = mAdaptee220;
}
public Adaptee220 getAdaptee220(){
return this.mAdaptee220;
}
@Override
public void V5() {
// TODO Auto-generated method stub
System.out.println("5V");
}
}
客户测试类
public class ClientMain {
public static void main(String[] args) {
// Adapter adapter = new Adapter();
// adapter.V5();
// adapter.V220();
ObjectAdapter oAdapter = new ObjectAdapter();
Adaptee220 m220 = new Adaptee220();
oAdapter.setAdaptee220(m220);
oAdapter.V5();
oAdapter.getAdaptee220().V220();
}
}
结果输出:
上述对象适配器模式中,把源Adaptee作为一个参数传入适配器,然后执行接口所要求的方法,这种适配器模式可以为多个源进行适配,弥补了类适配器的不足。
小结:
- 类适配器模式用于单一源的适配,由于它的源的单一化,代码实现不用写选择逻辑,很清晰
- 对象适配器模式可用于多源的适配,使得原本用类适配器模式需要写很多适配器的情况不复存在,弱点是,源数目可能比较多,所以具体实现条件选择分支比较多,不太清晰
类适配器与对象适配器之间的不同:
- 类适配器使用对象继承的方式,是静态的定义方式;而对象适配器使用对象组合的方式,是动态组合的方式。
- 对于类适配器,由于适配器直接继承了Adaptee,使得适配器不能和Adaptee的子类一起工作,因为继承是静态的关系,当适配器继承了Adaptee后,就不可能再去处理 Adaptee的子类了。而对于对象适配器,一个适配器可以把多种不同的源适配到同一个目标。换言之,同一个适配器可以把源类和它的子类都适配到目标接口。因为对象适配器采用的是对象组合的关系,只要对象类型正确,是不是子类都无所谓。
- 对于类适配器,适配器可以重定义Adaptee的部分行为,相当于子类覆盖父类的部分实现方法。而对于对象适配器,要重定义Adaptee的行为比较困难,这种情况下,需要定义Adaptee的子类来实现重定义,然后让适配器组合子类。虽然重定义Adaptee的行为比较困难,但是想要增加一些新的行为则方便的很,而且新增加的行为可同时适用于所有的源。
- 对于类适配器,仅仅引入了一个对象,并不需要额外的引用来间接得到Adaptee。而 对于对象适配器,需要额外的引用来间接得到Adaptee。
Android源码模式分析:
待续....
- 最常见的ListView、GridView、RecyclerView等的Adapter