适配器模式(Adapter):将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本接口不兼容而不能一起工作的那些类可以一起工作。
白话:适配器模式就相当于一个变压器,变压器的一头电压可对应与类的接口,另一头则对应于客户希望的接口,变压器则用于适配。
角色:
(1)Target:客户端希望的接口;
(2)Adaptee:被适配接口
(3)Apateer:适配器,简单的用组合的方式将Adaptee转成Target的接口。适配器和被适配类本身是合成的关系。
使用场景:请慎用,一般情况下请维持客户端与自己的类接口一致,如果一致,则适配毫无意义。
(1)维护代码:如果自己的类接口与客户端的接口保持一致时引起很大改动,则可以考虑。
(2)封装好的第三方库,因为改动不了,而自己类的接口也没必要与第三方接口一致,可以考虑。
例子:Android的BaseAdapter,将数据适配成ListView等的View;这里可以看到适配器模式可以将两个毫不相干的类(数据类和View类)联系在一起。
另外,BaseAdapter的notifyDataChanged则是用了观察者模式。
以适配3v电压为例:
客户端想得到3V电压的接口
interface Target {
public int get3V();
public void setAdapter(Voltage voltage);
}
已经实现的电压类:
abstract class Voltage {
abstract int getVoltage();
}
class _220V extends Voltage {
@Override
int getVoltage() {
return 220;
}
}
class _110V extends Voltage {
@Override
int getVoltage() {
return 110;
}
}
具体将不同的电压适配成3V的适配类:
class _3VAdpater implements Target {
public Voltage voltage;
public void setAdapter(Voltage voltage) {
this.voltage = voltage;
}
public int get3V() {
return translate3v(voltage.getVoltage());
}
private int translate3v(int orginalVoltage) {
return 3;
}
}
客户端调用:
public class Client {
public static void main(String[] args) {
Target adpater = new _3VAdpater();
adpater.setAdapter(new _220V());
System.out.print("voltage:" + adpater.get3V());
adpater.setAdapter(new _110V());
System.out.print("voltage:" + adpater.get3V());
}
}
这样:不管输入的是220V,还是110,adapter都将适配成3v了;
有些人可能认为translate3v这个方法很傻逼,跟originalVoltage一点关系的没有,实际情况则这里可能会调用Voltage中的方法如降频等,这里只是简单的表达而已。
VS 装饰模式(Wrapper):