适配器模式(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()); } }
有些人可能认为translate3v这个方法很傻逼,跟originalVoltage一点关系的没有,实际情况则这里可能会调用Voltage中的方法如降频等,这里只是简单的表达而已。
VS 装饰模式(Wrapper):