适配器模式,即通俗理解,适配无法直接使用的接口以便可以利用。
适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。
适配器模式的组成角色
- 目标角色(Target):适配所期待的得到的接口,目标角色可以是类或接口。这里,我更倾向于是接口,因为我理解目标角色更倾向于一种接口规范。
- 源角色(Adaptee):需要适配的接口或类。
- 适配器(Adapter):适配器模式的核心。通过继承或实现将源角色转换成目标角色接口。
在设计模式总,适配器模式有两种类型,类适配器模式和对象适配器模式。由于在Java中只支持单继承,所以类适配器模式会有些限制。
类适配器模式
UML图
通过上面的UML图可以看到,适配器Adapter继承自被适配类Adaptee,同时实现客户端要求的标准接口Target。
来看具体的实例:
定义标准的客户端接口:
/**
* 定义电动车要求的充电标准
* @author Iflytek_dsw
*
*/
public interface IElectrombile {
//电动车充电
void electricize();
}
定义充电器类:
/**
* 发电站,发电220V
* @author Iflytek_dsw
*
*/
public class Powerplant {
public void discharge(){
System.out.println("电压器释放220V的电压");
}
}
定义客户端对象,电动车。
/**
* 电动车
* @author Iflytek_dsw
*
*/
public class Electrombile {
/**
* 充电器,要求是规格70V的充电器
*/
private IElectrombile electrombile;
public Electrombile(IElectrombile electrombile){
this.electrombile = electrombile;
}
/**
* 使用指定充电器充电
*/
public void electricize(){
electrombile.electricize();
}
}
由于发电站发出来的电压是220V,而电动车直接充电要求的是70V,所以需要将220V电压进行降压适配。
public class Charger60V extends Powerplant implements IElectrombile{
@Override
public void electricize() {
super.discharge();
/**
* 通过降压处理,处理成电动车能用的电压
*/
System.out.println("降压处理,给电动车充电60V");
}
}
客户端调用演示:
public static void main(String[] args) {
IElectrombile electrom = new Charger60V();
Electrombile electrombile = new Electrombile(electrom);
electrombile.electricize();
}
上面演示的就是类适配器模式。
对象适配器模式
对象的适配器模式把被适配的类的API转换成为目标类的API,与类的适配器模式不同的是,对象的适配器模式不是使用继承关系连接到Adaptee类,而是使用委派关系连接到Adaptee类。
UML图
通过上面的UML图中,我们可以看到,在适配器和被适配类之间用了关联的关系作为连接,而不是继承关系。这样我们的目标接口就可是一个类或者接口进行实现。
在上面的例子中,我们稍加改造。
public class ObjectAdapterCharger implements IElectrombile{
/**
* 这里,我一直没考虑清楚【被适配类是在这里进行直接创建,还是通过客户端进行创建生成】
*/
private Powerplant powerplant;
public ObjectAdapterCharger(Powerplant powerplant) {
super();
this.powerplant = powerplant;
}
@Override
public void electricize() {
powerplant.discharge();
System.out.println("降压处理,给电动车充电60V");
}
}
类适配和对象适配器对比
- 类适配器的灵活性不如对象适配器,类适配器通过继承实现,对象适配器通过组合的方式实现,比较灵活。
- 类适配器通过继承实现,无法兼顾被适配器Adaptee的子类。对象适配器可以定义一个Adaptee对象,然后可以创建一个指向子类的实现。
- 类适配器可以通过重写父类方法进行改变Adaptee的实现。
适配器模式优缺点
优点
- 提高了类的复用性,解决了现存类和复用环境要求不一致的问题
- 将目标类和适配者类解耦,通过引入一个适配器类重用现有的适配者类,而无需修改原有代码,增强了类的扩展性。
- 通过适配器,客户端可以调用同一接口,因而对客户端来说是透明的。这样做更简单、更直接、更紧凑。
缺点
- 适配器过多,造成系统过于复杂,所以要有目的地性的使用适配器模式。
使用场景:有动机地修改一个正常运行的系统的接口,这时应该考虑使用适配器模式。
注意事项:适配器不是在详细设计时添加的,而是解决正在服役的项目的问题。