前言
由于项目工程中,常常会出现现存的类与所需求的类之间类型不兼容,但是现存的类又具有所需求类的功能,所以为了能够重用现存的类,解决项目
中的需求,适配器模式就应运而生了。
简而言之,适配器模式就是在目标类与现存类之间搭起一道桥梁(适配器类),使得可以使用现存的类来适应目标接口,这样就不要再为目标类的
不存在,而专门去设计一个目标类,或者修改已有的接口(类)以适应现存的类,从而遵循了开闭原则(对扩展开放,对修改关闭)!
下面通过一个实际生活中遇到的情景,来讲解适配器模式的原理及应用。当一个人手机没电时,周围只有一个220V的电源,但是手机的充电接口是
5V的,所以220V的电源不能直接用来给手机充电,所以这时需要一个适配器来将220V电源适配给手机接口进行充电。在这个例子中,220V的电源的功
能是充电,5V的电源也能充电,所以可以采用适配器模式,解决这个类型不兼容问题。
在这个情境中,你不能因为没有5V的电源,就将手机的充电接口改为220V的吧!如果这样做的话,遇到其他情况,你岂不是还得把接口改掉?
所以这时需要一个适配器,将不是5V的电源转换为5V的电源不就可以解决问题了!而且以后如果遇到只有100V电源的情况,你也可以通过电源
适配器将100V的电源转换为5V电源,这样,保证了充电接口不被改变,可以一直使用,同时又利用了现存的电源!
以下代码分别对应220V的电源类(ExistedUtil类)、5V的充电接口( Target接口)、手机类( Client)以及电源适配器类(Adapter类);
/**
*目标接口,本例中为手机的5V充电接口
*/
public interface Target
{
void functionTarget();//充电的功能
}
/**
*现有的类,本例中为220V电源类
*/
public class ExistedUtil
{
public void function()
{
System.out.println("完成functionTarget方法中的所有功能");
}
}
/**
*客户端,本例中为手机类
*/
public class Client
{
private Target target;
public Client(Target t)
{
target = t;
}
}
/**
*适配器类,本例中为电源适配器类
*/
public class Adapter implements Target
{
private ExistedUtil eu;
public Adapter(ExistedUtil existedUtil)
{
eu = existedUtil;
}
@Override
public void functionTarget()
{
this.function();
}
}
/**
*main方法,用于测试使用
*/
public static void main(String[] args)
{
//使用适配器之前
ExistedUtil eu = new ExistedUtil();//220V电源
Client c = new Client(eu);//只能放5V的电源,eu为220V电源,此处编译不通过
//使用适配器之后
ExistedUtil eu = new ExistedUtil();//220V电源
Target t = new Adapter(eu);//5V的电源
Client c = new Client(t);
}
上述代码采用的是采用组合方式的适配器,该适配器为对象适配器,原因在于该适配器是将现存类的一个对象放入适配器类中作为数据域;还有另外一种适配器,叫做类适配器,类适配器采用适配器类继承于现存类的方式进行设计;
这里只需将适配器类做一定的修改,如下所示:
/**
*适配器类,本例中为电源适配器类
*/
public class Adapter extends ExistedUtil implements Target
{
@Override
public void functionTarget()
{
super.function();
}
}
/**
*main方法,用于测试使用
*/
public static void main(String[] args)
{
Target t = new Adapter();//5V的电源
Client c = new Client(t);
}
两种方式的区别:
对象适配器:将被适配者作为一个对象组合到适配器类中,将被适配者包装到适配器中,提供给目标接口使用;可以提供给多个被适配者进行适配;
类适配器:通过继承被适配者类,实现对目标接口的匹配,只能为某一特定的类实现适配;