意图:将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
主要解决:主要解决在软件系统中,常常要将一些"现存的对象"放到新的环境中,而新环境要求的接口是现对象不能满足的。
举例:
我们有一个 MediaPlayer 接口和一个实现了 MediaPlayer 接口的实体类 AudioPlayer。默认情况下,AudioPlayer 可以播放 mp3 格式的音频文件。
我们还有另一个接口 AdvancedMediaPlayer 和实现了 AdvancedMediaPlayer 接口的实体类。该类可以播放 vlc 和 mp4 格式的文件。
我们想要让 AudioPlayer 播放其他格式的音频文件。为了实现这个功能,我们需要创建一个实现了 MediaPlayer 接口的适配器类MediaAdapter,并使用 AdvancedMediaPlayer 对象来播放所需的格式。
AudioPlayer 使用适配器类 MediaAdapter 传递所需的音频类型,不需要知道能播放所需格式音频的实际类。AdapterPatternDemo,我们的演示类使用 AudioPlayer 类来播放各种格式。
引申:生活中的适配器
我们国家的电器使用普通的扁平两项或三项插头,而去外国的话,使用的标准就不一样了,比如德国,使用的是德国标准,是两项圆头的插头。如果去德国旅游,那么我们使用的手机充电器插头无法插到德国的插排中去,那就意味着我们无法给手机充电。怎样解决这个问题呢?只要使用一个电源转化器就行了
/**
* 德标接口
*/
public interface DBSocketInterface {
/**
*使用两项圆头的插口供电
*/
void powerWithTwoRound();
}
/**
* 德国插座
*/
public class DBSocket implements DBSocketInterface{
public void powerWithTwoRound(){
System.out.println("使用两项圆头的插孔供电");
}
}
/**
* 德国宾馆
*/
public class Hotel {
//旅馆中有一个德标的插口
private DBSocketInterface dbSocket;
public Hotel(){}
public Hotel(DBSocketInterface dbSocket) {
this.dbSocket = dbSocket;
}
public void setSocket (DBSocketInterface dbSocket){
this.dbSocket = dbSocket;
}
//旅馆中有一个充电的功能
public void charge(){
//使用德标插口充电
dbSocket.powerWithTwoRound();
}
}
/**
* 国标接口
*/
public interface GBSocketInterface {
/**
* 使用三项扁头的插口供电
*/
void powerWithThreeFlat();
}
/**
* 中国插座
*/
public class GBSocket implements GBSocketInterface{
@Override
public void powerWithThreeFlat() {
System.out.println("使用三项扁头插孔供电");
}
}
public class SocketAdapter
implements DBSocketInterface{ //实现旧接口
//组合新接口
private GBSocketInterface gbSocket;
/**
* 在创建适配器对象时,必须传入一个新街口的实现类
* @param gbSocket
*/
public SocketAdapter(GBSocketInterface gbSocket) {
this.gbSocket = gbSocket;
}
/**
* 将对就接口的调用适配到新接口
*/
@Override
public void powerWithTwoRound() {
gbSocket.powerWithThreeFlat();
}
}
测试代码:
public class TestAdapter {
public static void main(String[] args) {
GBSocketInterface gbSocket = new GBSocket();
Hotel hotel = new Hotel();
SocketAdapter socketAdapter = new SocketAdapter(gbSocket);
hotel.setSocket(socketAdapter);
hotel.charge();
}
}