前言
买过港版手机的都知道,包装盒里送的充电头是港标的。和我们大陆日常使用的国标是不兼容的。也就是说,港版手机直接用送的充电头是无法在大陆直接充电的。这是由于大陆使用国标插座,而香港是使用的英标插座。如下图所示,可以看到国标,港版英标的是不同接口的插座。
各国插座标准而为了解决这个不兼容的问题,通常使用电源接头转换器,这种转换器一头是英标接口,另一头是国标插头。有了转换器,我们可以在不更换插座接口,也不更换充电器的前提下,成功将我们的港版手机充电。
电源接头转换器在软件开发中,我们也会遇到需要“电源接头转换器”的时候。比如说,需要使用现有的类,但是类的接口并不符合我们的需要,甚至是并没有这些类的源代码。此时,适配器模式就是我们的转化器。
是什么
适配器模式(Adapter Pattern):将一个接口转换成客户希望的另一个接口,使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)。适配器模式既可以作为类结构型模式,也可以作为对象结构型模式。常用作在不修改源代码的情况下让已经存在的类能和其他类一起使用。
根据适配器类和适配者类的关系,适配器模式可以分为以下两种:
-
对象适配器模式(组合的方式)
-
类适配器模式(继承的方式)
两种适配器模式(左边对象适配器模式,右边类适配器模式) -
Target:目标抽象类,定义客户所需的接口,可以是抽象类/接口/具体类。
-
Adaptee:适配者类,也就是被适配的对象。定义一个已经存在的接口。一般是一个具体类,其中包含了客户希望使用的业务方法。
-
Adapter:适配器类,转换器,对目标类和适配者类进行适配。
为什么
试想一下,如果我们不使用适配器模式,我们可以选择修改源码或者更改我们的目标接口。而修改源码或是更改接口很大的代价很大,甚至是我们根本就没有源码。就好像我们无法更换插座接口或是充电器的接头一样。
怎么做
由于适配器模式有多种,下面通过几个代码片段来分别学习一下:
- 对象适配器模式
首先是我们要使用的目标接口,这个就好比是国标插座。
/**
* 目标接口
*/
public interface Target {
void request();
}
然后是我们的适配者类,同样这个好比是港版英标插头。
/**
* 适配者类
*/
public class Adaptee {
/**
* 客户期望使用的业务方法
*/
public void specificRequest(){
System.out.println("Adaptee Specific request!");
}
}
下面是适配器类,使用的是对象适配器模式,适配器类以组合的方式引用适配者类。这个就相当于电源接头转换器。
/**
* 适配器类(对象适配器模式实现)
*/
public class Adapter implements Target {
//以组合的方式关联适配者
private Adaptee adaptee;
public Adapter(Adaptee adaptee){
this.adaptee = adaptee;
}
public void setAdaptee(Adaptee adaptee) {
this.adaptee = adaptee;
}
/**
* 对接口进行转换
*/
@Override
public void request() {
adaptee.specificRequest();
}
}
- 类适配器模式
而类适配器模式则是通过继承的方式,而Java语言只支持单继承,所以用得不多。
/**
* 类适配器模式
*/
public class Adapter extends Adaptee implements Target {
@Override
public void request() {
specificRequest();
}
}
实际使用:
public class Client {
public static void main(String[]args){
Adaptee adaptee = new Adaptee();
Target target = new Adapter(adaptee);
target.request();
}
}
网友评论