概述
对于适配器相信大家不会陌生,生活中有各种各样的例子,像耳机转接线,充电器适配器,水管适配接口等等。通过类比我们很容易理解适配器的作用:
将已有的本无法使用的类通过适配器转换,从而达到资源复用,节省开销的目的。
那要如何通过代码实现这一点呢?既然要将被适配者转换为目标接口类,那么适配器肯定是要实现自该接口的,以保证类型、行为的一致,但要如何转换呢?很简单,只需要通过继承或组合被适配者就能轻易的实现。注意基于多使用组合,少使用继承的原则,我们一般会选择组合的方式来实现,这种方式叫对象适配器,而通过继承实现的叫类适配器,后者一般用于一个适配器需要转换多个被适配者的情况;但Java中没有多继承,因此此处仅讨论对象适配器。类图如下:
Coding
小明有一台用肾换来的IPhone,某天IPhone的充电器坏了,但IPhone的充电器太贵,小明没钱买新的了,他想到之前的Android充电器还是好的,但是不兼容IPhone手机啊,不过小明知道网上有Android和IPhone的接口转换器卖,而且很便宜,立马就买了一个回来,完美解决,不用再卖肾了。我们就用代码来实现这个过程,首先是IPhone和Android: ···java public class IPhone {
代码语言:javascript复制// 注意IPhone充电器现在是不能正常工作的
public void iPhoneCharging() {
System.out.println("充电器坏了。。。");
}
}
public class Andriod {
代码语言:javascript复制public void andriodCharging() {
System.out.println("充电中....");
}
} ··· 可以看到这两个东西完全没有关联,但小明需要Android充电器和IPhone充电器一样为IPhone充电:
代码语言:javascript复制public class AndriodAdatper extends IPhone {
private Andriod andriod;
public AndriodAdatper(Andriod andriod) {
this.andriod = andriod;
}
@Override
public void iPhoneCharging() {
andriod.andriodCharging();
}
}
有了这个适配器小明就可以正常充电了:
代码语言:javascript复制public class XiaoMing {
public static void main(String[] args) {
Andriod andriod = new Andriod();
IPhone iPhone = new AndriodAdatper(andriod);
iPhone.iPhoneCharging();
}
}
实现适配器非常容易,通过上述代码,我们也可以看到被适配者对于客户端而言是完全透明的,具体需要适配什么也是由客户端来决定的,通过适配器就将现有的接口类和被适配者完全解耦了,但是我们也可以发现每当需要转换一个类时都需要一个适配器,这样就会导致系统结构变得非常复杂,因此使用时也需要格外注意。
小结
适配器模式可以将一个不兼容的类转化为可复用的类,这样可以使得我们不用添加额外冗余臃肿的代码,但同时也会产生许多的适配器类,也会增加系统的复杂性。同时,既然是转换不兼容的类,那么该模式应尽可能的用于项目后期的补偿,而不是初期的详细设计中,否则就应该好好考虑下初期设计是否合理。