定义:
将一个类的接口,转成客户期望的另一接口。适配器让原本接口不兼容的类可以合作无间。
作用:
解耦,用户调用时只调用匹配的接口,尽管调用的是另一接口提供的方法,但其中封装的信息及细节已在适配器中实现,实现了用户与适配器另一端接口的解耦。
如果我们想要改变接口,适配器可以将改变的部分封装起来,用户则不需要随着目标接口的更改而更改。
适用场景:
1 系统需要使用现有的类,但是现有的却不兼容
2 需要建立一个可以重复使用的类,易于扩展,用于彼此关系不大的类之间的解耦
3 需要一个统一的输出接口,输出类型不了预知
过程如图:
此图为适配器解析的过程,其中的客户和被适配器是解耦的,相互依靠适配器进行请求和返回,彼此并不知道各自的存在。
如下为适配器的类图
类适配器
类适配器模式下,适配器继承了被适配器和目标类,这种情况实现了多继承,而java不支持多继承,所以其他编程语言可以考虑这种情况。
对象适配器
使用对象适配器,使用组合的方式,用修改的接口包装被适配者:这样使得被适配器子类均可以搭配该适配器来使用。
以下为实现适配器的简单demo,利于理解
定义一个目标类,具体为一个客户获取食物:
public class Customer {
private Map<String,String> customerFood;
public Map<String, String> getCustomerFood() {
return customerFood;
}
public void setCustomerFood(Map<String, String> customerFood) {
this.customerFood = customerFood;
}
}
当客户有一天想换一种方式吃东西,则定义一种接口,为客户想要的方式:
public interface CustomerInterface {
public String getFish();
public String getMeat();
}
那么接下来,需要提供一种适配方法,从一种接口转为另一种,此适配器继承了目标接口,而java不支持多继承,不利于扩展,不推荐使用
public class CustomerAdapt extends Customer implements CustomerInterface {
@Override
public String getFish() {
return (String)super.getCustomerFood().get("fish");
}
@Override
public String getMeat() {
return (String)super.getCustomerFood().get("meat");
}
}
如代码所示,CustomerAdapt 实现CustomerInterface 接口,继承Customer 类经过CustomerInterface接口实现,嵌套Customer getCustomerFood()获得了所需的食物。
我们的角色划分为:
CustomerInterface :目标角色——目标接口,系统所期待实现的目标;
Customer :源角色——当前已经存在的原有的实现类,即将被适配的类;
CustomerAdapt :适配器角色——将原有实现装换为目标接口的实现。
如下图代码,为对象关系的适配器,此类型适配器,更容易搭配
public class CustomerAdaptTest implements CustomerInterface {
private Customer customer;
private CustomerAdaptTest(){}
public CustomerAdaptTest(Customer customer) {
this.customer=customer;
}
@Override
public String getFish() {
return customer.getCustomerFood().get("fish");
}
@Override
public String getMeat() {
return customer.getCustomerFood().get("meat");
}
}