适配器模式:将一个类的接口,转换为客户期望的另一个接口。让原本接口不兼容的类可以合作无间。
可以通过创建适配器进行接口转换,让不兼容的接口变成兼容的。
调用适配器方法,适配器使用被适配者,把调用转换成被适配者的一个或多个调用接口。
适配器组合被适配者,实现目标接口。
老气象站的天气预报接口:getWendu();
新气象站的天气预报接口:getTemperature();
TencentQQ之前一直使用老的气象站,获取气温。
由于老的气象站设备落后数据不精确,想调用新气象局的天气预报接口。
但是新气象站的接口和老气象站的接口不兼容,必须改代码。
TencentQQ调用老气象站接口的代码已经在线上运行了很久,证明代码很稳定,可靠,不想修改代码。
能不能不修改代码的前提下,就能实现新气象局的接口调用呢?
用适配器模式可以实现。
只要新气象局能做一个适配器,实现目标接口(老气象站接口),并且组合被适配者(新气象站)。
调用适配器的方法,适配器会使用被适配者,把调用转换成被适配者的一个或多个调用接口。
package com.ez.biz;
import com.ez.NewWeatherService;
import com.ez.OldWeatherService;
import com.ez.impl.NewWeatherServiceAdapter;
import com.ez.impl.NewWeatherServiceImpl;
import com.ez.impl.OldWeatherServiceImpl;
/**
* TencentQQ不需要改一行代码,就可以实现新气象站的气温获取。
* 新气象站就是被适配者(实现目标接口),用老气象站接口就是目标接口。
* @author 窗外赏雪(EZ编程网)
*/
public class Test {
public static void main(String[] args) {
TencentQQ qq=new TencentQQ();
OldWeatherService ows=new OldWeatherServiceImpl();
qq.setWeatherService(ows);
qq.showTemperature();
System.out.println("==============================");
NewWeatherService newWeatherService=new NewWeatherServiceImpl();
//新气象站适配器用来适配新气象站
ows=new NewWeatherServiceAdapter(newWeatherService);
qq.setWeatherService(ows);
qq.showTemperature();
}
}
package com.ez.biz;
import com.ez.OldWeatherService;
/**
* 客户方代码,就算出了新的气象台,也无需要改任何代码。
* 只要把新气象台适配器注入进来,不改代码就可以通过新气象台适配器获取气温。
* @author 窗外赏雪(EZ编程网)
*/
public class TencentQQ {
private OldWeatherService weatherService;
//可以注入老气象站接口或子类的对象,如:新气象站适配器,老气象站
public void setWeatherService(OldWeatherService weatherService) {
this.weatherService = weatherService;
}
public void showTemperature(){
weatherService.getWendu();
System.out.println("TencentQQ show Temperature");
}
}
package com.ez;
/**
* 老气象站服务接口
* @author 窗外赏雪(EZ编程网)
*/
public interface OldWeatherService {
/**
* 获取气温
*/
void getWendu();
}
package com.ez;
/**
* 新气象站服务接口
* 想要客户不改代码就可以调用新气象站服务,必须适配新气象站服务。
* @author 窗外赏雪(EZ编程网)
*/
public interface NewWeatherService {
void getTemperature();
}
package com.ez.impl;
import com.ez.OldWeatherService;
/**
* @author 窗外赏雪(EZ编程网)
*/
public class OldWeatherServiceImpl implements OldWeatherService{
@Override
public void getWendu() {
System.out.println("通过老气象站,获取气温");
}
}
package com.ez.impl;
import com.ez.NewWeatherService;
/**
* @author 窗外赏雪(EZ编程网)
*/
public class NewWeatherServiceImpl implements NewWeatherService{
@Override
public void getTemperature() {
System.out.println("通过新气象站,获取气温");
}
}
package com.ez.impl;
import com.ez.NewWeatherService;
import com.ez.OldWeatherService;
/**
* 新气象站适配器,需要实现想转换的类型接口(目标接口:老气象站接口),就是客户所期望看到的接口。
* 适配器实现了目标接口,并持有被适配者的实例(新气象站)
* 1、客户通过目标接口调用适配器的方法。
* 2、适配器使用被适配者接口,把请求转换成被适配者的一个或多个调用接口。
* 3、客户接收到调用的结果,但并未察觉这一切是适配器在起转换作用。
* @author 窗外赏雪(EZ编程网)
*/
public class NewWeatherServiceAdapter implements OldWeatherService {
//适配的对象
private NewWeatherService newWeatherService;
public NewWeatherServiceAdapter(NewWeatherService newWeatherService) {
this.newWeatherService = newWeatherService;
}
//新气象站需要适配的接口
@Override
public void getWendu() {
newWeatherService.getTemperature();
}
}