定义:
适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。
概念:
适配器模式是一种结构型模式,对类对象进行结构上的组合,解决一些代码结构问题。 适配器这个词简单的解释就是对接,把两个原本没有办法连接转换的事务进行一个对接,转换。如果是放到代码上来理解的话就是通过代码进行一个替换。把需要被替换的部分换成新的部分。
下面举个例子就是我们的苹果和安卓的充电头,常常没办法通用,这个时候就有人提供一个转换器,把他们对接起来,实际上就是完成了一个替换。
代码示例:
1.首先定义一个安卓部件的接口
public interface AndroidPartsInterface {
void androidParts();
}
2.安卓充电接头实现这个接口 给Android手机充电
public class AndroidPartsImp implements AndroidPartsInterface {
@Override
public void androidParts() {
Log.d("TAG", “使用安卓接口充电中...");
}
}
3.使用这个接口进行充电咯,一个充电的工具类,传入一个Android充电接接口部件,然后进行充电
public class ChargeUtils {
private AndroidPartsInterface androidParts ;
public ChargeUtils(AndroidPartsInterface androidParts) {
this.androidParts = androidParts;
}
public void use(){
if(androidParts != null)
androidParts.androidParts();
}
}
4.上面的代码没什么好说的,真正的调用也很简单
AndroidPartsInterface androidPartsImp = new AndroidPartsImp();
ChargeUtils chargeUtils = new ChargeUtils(androidPartsImp); // 充电的工具类
chargeUtils.use();
就这么简单的使用起来, 输出的是“安卓手机充电中…”, 现在有个问题来了,如果你只有一个苹果的接口你怎么对安卓手机充电呢,这个时候适配器就登场了。想象一下,适配苹果到安卓,那他必定是要把两者结合起来,对于程序来说,我们自然回想到继承、实现、依赖、组合等等方法。
1.让适配器继承安卓接口,实现安卓接口的功能。
2.通过构造器的参数传入苹果接口对象
3.再在安卓接口的地方,替换成使用苹果的接口。
这样就悄无声息的把安卓接口适配上苹果的接口了
public class AdapterImp implements AndroidPartsInterface { // 实现安卓接口
private ApplePartsInterface applePartsInterface;
public AdapterImp(ApplePartsInterface applePartsInterface) { // 在构造过程中传入一个苹果接口
this.applePartsInterface = applePartsInterface;
}
@Override
public void androidParts() { // 重写安卓充电方法
applePartsInterface.AppleParts();
}
}
下面是定义的苹果接口和具体实现
public interface ApplePartsInterface { //接口
void AppleParts();
}
// 具体实现
public class ApplePartsImp implements ApplePartsInterface {
@Override
public void AppleParts() {
Log.e("TAG", "使用苹果接口充电中...");
}
}
那具体怎么调用呢?
//AndroidPartsInterface androidPartsImp = new AndroidPartsImp();
//ChargeUtils chargeUtils = new ChargeUtils(androidPartsImp ); // 用安卓接口充电
AdapterImp adapterImp = new AdapterImp(new ApplePartsImp());
ChargeUtils chargeUtils = new ChargeUtils(adapterImp); // 通过适配器使用苹果接口充电
chargeUtils.use();
注释掉的两行代码是用安卓的接口进行充电,现在我们没有安卓的接口了,就搬出一个适配了苹果的适配器出来,为什么让她继承安卓的接口呢,而不是通过组合或者内部类的的方式呢,可以看到这样的话就可以把适配器对象当作安卓接口传到充电工具类中,这样可以复用之前的代码而不需要做什么修改。
这样就完成了接口转换,实现适配。
进阶分析:
上面写了一大堆的类和接口,感觉有点绕。我们来拆解一下,不搞那些貌似花里胡哨的东西。
- 苹果和安卓配件的接口直接去掉。AndroidPartsInterface 和 ApplePartsInterface 就先不定义了,直接上来两个类ApplePartsImp 和 AndroidPartsImp ,这两个代表的就是两个接头。用苹果代替安卓来充电,那就直接用安卓来代替苹果嘛。粗暴的我们直接让ApplePartsImp 继承 AndroidPartsImp 这样就轻松完成转换了。(前提是苹果同意用安卓的标准,但是大家知道骄傲的苹果不会这么做的)如果这样的话,这个问题其实就最简单,解决这个问题就仅仅是一个类的继承,然后重写相关方法就好了。
- 苹果不会答应,这个时候就不能在ApplePartsImp 这个类上乱来了,那就有商家发现商家,制造出适配两者的适配器。把两个事务进行一定的组合。
- 仅仅是这样直接对类进行组合势必会有些代码结构上的问题,有些限制,根据设计模式的几大原则,面向抽象编程是比较好的方式,这个时候就有了上面例子中两个抽象类AndroidPartsInterface 和ApplePartsInterface 的定义。这样一个完整的结构比较清晰的适配器就做好了。这种方式就有了一个专门的名称,适配器模式。
我回想自己的编码过程就是按上面这样的思维和路径一步步升级的。刚开始写代码的时候遇到这样的问题就是直接继承,强行撸码,后来遇到继承不了的情况就会到了第二种阶段,哪有什么面向接口编程,慢慢的才意识到抽象接口的使用。这样的一个认识深入的过程是学习和经验的积累。想起当时看设计模式的时候也是经常想不明白为什么会要这样处理,显得大费周折,现在想想只能用年轻来形容。
这段总结算是对自己作为一个程序员进阶过程的思考和总结吧。适配器模式就写到这里,关于Android中的适配器使用有很多相关文章,可能后续分析源码的时候再具体分析把。