一句话
适配器(pattern- Adapter)定义:将两个不兼容的类或接口组合在一起使用
例子一:在一次学术会议上,来自美国的A只会说英语,来自中国的B只会讲汉语。现在A想和B交流,怎么办?
解决办法:求助于好友C(同时会说英文和中文)。
例子二:美国的生活用电是110V,国的生活用电是220V。现在把美国的电器拿到中国来用,用户就面临电压不同的问题,怎么办?
解决办法:用一个能把220V电压变为110V电压的变压器(adpter)。
例子三:假设有一个软件系统,你希望它能和一个新的厂商类库搭配使用,但是这个新厂商所设计出来的接口,不同于旧厂商的接口,而且你不能改变系统现有代码,同时也不能改变厂商的代码,怎么办?
解决办法:新建一个类(适配器),该类继承系统现有的类,并实现厂商的接口。
我们经常碰到要将两个没有关系的类组合在一起使用,第一解决方案是:修改各自类的接口,但是如果我们没有源代码,或者,我们不愿意为了一个应用而修改各自的接口。怎么办?使用Adapter,在这两种接口之间创建一个混合接口(混血儿)。
上面例子中的解决办法都用到了适配器(Adapter)设计模式。那么究竟上面是适配器呢?它都用到哪些场景下呢?
适配器定义:将两个不兼容的类或接口纠合在一起使用,属于结构型模式,需要有Adaptee(被适配者)和Adaptor(适配器)两个身份。适配器的目的是综合使用几个不同的东西,比如A里面有功能a,B里面有功能B,现在想使用B,但是同时想让B有功能a,就可以用一个适配器实现,使适配器既有功能a又有功能b。
在以下情况可以考虑用适配器:
系统需要使用现有的类,而此类的接口不符合系统的需要。就可以用适配器:把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口原因不匹配而无法一起工作的两个类能够一起工作。
使用适配器有两种方式:组合(composition)和继承(inheritance)。先在以例子一说明。A会说英语
public class A {
public void language() {
System.out.println("english");
} //end language()
}//end class A
B会说汉语
public class B {
public void language() {
System.out.println("chinese");
} //end language()
}//end class B
现在需要一个C(适配器)即会说英语又会说汉语
public class C extends A {
private B b;
public C() {
this.b=new B();
}
public void chineseLanguage() {
b.language();
} //end chineseLanguage()
} //end class C
这样通过继承A和在C中使用B,就使C同时符合了A和B的需求,现在A和B通过C可以正常的交流了。
但是在面向接口编程中通常是这样一种情况:旧接口实现类Adaptee有方法a,现在因为厂商变动产生了新接口ITarget,而客户端希望用方法b,为使客户端能够使用Aaptee类,并兼容厂商的接口ITarget,需要一个中间环节Aapter(适配器:Adpter类继承Adaptee类并实现接口ITarget,并实现接口中的b方法),从而使Adapter在没有给变旧代码的基础上兼容了新的接口。
JDBC驱动软件与适配器模式(来源于《Java与模式》的例子)
JDBC给出一个客户端通用的界面。每个数据库引擎的JDBC驱动软件都是一个介于JDBC接口和数据库引擎接口之间的适配器软件。
抽象的JDBC接口和各个数据库引擎的API之间都需要相应的适配器软件,即为各个数据库引擎准备的驱动软件。