概念:适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。
1. 已经存在的类,它的方法和需求不匹配的情况。
2. 适配器模式不是在设计阶段考虑的设计模式,而是随着软件的维护出现不同情况下的解决方案。
3. 主要用在不兼容的情况下,如SpringMVC使用适配器进行拦截请求和分发。
优点:
1. 更好的复用性,系统需要使用现有的类,而此类的接口不符合系统的需要。那么通过适配器模式就可以让这些功能得到更好的复用。
2. 更好的扩展性,在实现适配器功能的时候,可以调用自己开发的功能,从而自然地扩展系统的功能。
3. 符合开闭原则
缺点:
过多的使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是A接口,其实内部被适配成了B接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。
技术要点:
适配器模式可以砸符合OCP原则(开闭原则)的基础上,为新类增加新的功能。该模式设计的角色主要有以下3个。
1.目标角色:就是期待得到的接口。
2.源角色:需要被增加功能的类或接口。
3.适配器角色:新创建的类,在源角色的基础上实现了目标角色。
示例代码:
// 220V接口
public interface CN220VInterface {
public void connect();
}
public class CN220VInterfaceImpl implements CN220VInterface {
@Override
public void connect() {
System.out.println("中国220V,接通电源,开始工作");
}
}
//日本110V 电源接口
public interface JP110VInterface {
public void connect();
}
public class JP110VInterfaceImpl implements JP110VInterface {
@Override
public void connect() {
System.out.println("日本110V,接通电源,开始工作..");
}
}
//日本电饭煲
public class ElectricCooker {
private JP110VInterface jp110VInterface;//日本电饭煲
ElectricCooker(JP110VInterface jp110VInterface){
this.jp110VInterface=jp110VInterface;
}
public void cook(){
jp110VInterface.connect();
System.out.println("开始做饭了..");
}
}
public class PowerAdaptor implements JP110VInterface {
private CN220VInterface cn220VInterface;
public PowerAdaptor(CN220VInterface cn220VInterface) {
this.cn220VInterface = cn220VInterface;
}
@Override
public void connect() {
cn220VInterface.connect();
}
}
public class AdaptorTest {
public static void main(String[] args) {
CN220VInterface cn220VInterface = new CN220VInterfaceImpl();
//适配器接口
PowerAdaptor powerAdaptor = new PowerAdaptor();
// 电饭煲
ElectricCooker cooker = new ElectricCooker(powerAdaptor);
cooker.cook();//使用了适配器,在220V的环境可以工作了。
}
}
上述示例,是以日本电饭煲为例,日本的额定电压为110V,而中国的额定电压为220V,那么如何在中国使用日本的电饭煲呢?我们日常生活一般就是那一个变压器,这样就可以使用了。那么代码上如何实现的呢。我们首先定义两个电压接口,一个110V一个220V分别代表日本额定电压和中国的额定电压,然后分别实现这两个接口。接着再定义一个电饭煲类,作为我们的源角色,电饭煲有一个煮饭的功能,正常来说,这个日本电饭煲在中国是不能使用的,因为额定电压的原因,这个时候我们就需要定义一个适配器类来支持这个电饭煲的使用,也就是PowerAdaptor这个类,帮我们适配一下,就可以在220V的环境下工作了,因为电饭煲必须接受110V的电压才行,传220V就会出问题,其实就是中间做了个转换。PowerAdaptor类我们也可以改成:
public class PowerAdaptor extends CN220VInterface implements JP110VInterface {
@Override
public void connect() {
super.connect();
}
}
这种事通过继承来实现,前一种是通过构造方法传入来实现,两种都可以。