适配器(adapter)模式,把一个类的接口变成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。
适配器模式有两种形式,类的适配器模式和对象的适配器模式。我们先看类的适配器模式,类的适配器模式有以下角色:
目标(Target)角色:是期待得到的接口类型。这里谈类的适配器模式所以这个不能是类,原因是java单继承。
源(adaptee)角色:现有待适配的接口类型。
适配器(adapter)角色:适配器类模式的核心,这个角色负责把源接口转换成目标角色的接口。
类的适配器模式类图:
通过上图可以看出,组合对象Adapter持有源Adaptee的对象,利用聚合代替了继承,在Adapter里面的代码如下编写:
package adapter;
/**
*
*作者:alaric
*时间:2013-7-21下午6:44:53
*描述:目标类
*/
public interface Target {
public void operate1();
public void operate2();
}
package adapter;
/**
*
*作者:alaric
*时间:2013-7-21下午6:44:29
*描述:源
*/
public class Adaptee {
public void operate1(){
//业务逻辑
}
}
package adapter;
/**
*
*作者:alaric
*时间:2013-7-21下午6:44:05
*描述:适配器类
*/
public class Adapter extends Adaptee implements Target{
@Override
public void operate2() {
// 业务逻辑
}
}
适配器类继承了源类,实现了目标类在源里没有的接口,达到了适配转换作用。java是单继承的语言,这种类的适配模式往往受到使用环境的限制,在面向对象设计原则中,有一条叫做组合/聚合复用原则,讲的是尽可能使用组合和聚合达到复用的目的而不是继承,所以一般推荐用对象适配器模式达到目的,对象适配器的角色和类的适配器模式的角色没什么具体的区别,只是类图不同,对象适配器模式的类图如下:
通过上图可以看出,组合对象Adapter持有源Adaptee的对象,利用聚合代替了继承,在Adapter里面的代码如下编写:
package adapter;
/**
*
*作者:alaric
*时间:2013-7-21下午6:44:05
*描述:适配器类
*/
public class Adapter2 implements Target{
private Adaptee adaptee;
public Adapter2(Adaptee adaptee) {
super();
this.adaptee = adaptee;
}
@Override
public void operate2() {
// 业务逻辑
}
@Override
public void operate1() {
//调用源的方法
adaptee.operate1();
}
}
为了不改变原有系统的实现而对目标接口需求的满足而做适配,利用具体的类的适配器模式还是对象的适配器模式,要根据具体的业务场景,如果两种都可以的话最好选择对象的适配器模式,适配器模式使得原本不能在一起工作的类在一起工作成为可能。但是对于变化很大的系统对每个接口都写一个适配器类变的很难维护,这时候应该考虑对原有代码的重构,而不是系统中存在大量的适配器类。
ps:最近重新学习设计模式,所写相关笔记纯属个人对书本和资料的理解,如有不到之处请大家指出,共同探讨学习设计模式。
设计模式系列目录: