模式说明
当前有一工具(一个已存在的类),能实现若干功能(方法),需要在某平台(目标)上使用,但与平台的接口不同(已存在的类的方法与接口方法名不同),需提供一个适配器(适配器类)转换为平台接口。这种场景可以使用适配器模式实现。与代理模式比较类似,但代理类中的RealSubject
和Proxy
都需要实现Subject
抽象类。而适配器模式中的Adaptee
类是原本就已存在的类,内部的方法与接口中定义的抽象方法不同(行为一致,方法名不同)。
本示例中,以Typec
为抽象目标类,其内有标准充电方法typecChange
和标准数据传输方typecDataTran
。现有Typeb
类和Lightning
类,均有自己的充电方法和数据传输方法。演示如何为他们设置适配器类,使得客户端能够通过调用适配器中的符合Typec
的标准方法来间接使用Typeb
和Lightning
的充电和数据传输功能(方法)。
结构
抽象目标类
定义抽象标准方法。
被适配类
有与目标类相同功能的方法,但接口(方法名)不符合标准接口(与目标类内定义的方法的方法名不同)。
适配器类
继承目标抽象类,内部持有一个被适配类实例,实现目标抽象类的抽象方法,在方法内部调用其持有的被适配类的原有方法。
代码演示
package com.yukiyama.pattern.structure;
/**
* 适配器模式
*/
public class AdapterDemo {
public static void main(String[] args) {
// 使用非标准物件时,声明其适配器
Typec t1 = new AdapterB2C();
Typec t2 = new AdapterL2C();
// 通过调用对应适配器的标准方法,间接使用
// 输出“使用TypeB接口充电”
t1.typecCharge();
// 输出“使用TypeB接口传输数据”
t1.typecDataTrans();
// 输出“使用TypeB接口充电”
t2.typecCharge();
// 输出“使用TypeB接口传输数据”
t2.typecDataTrans();
}
}
/**
* 抽象目标类
* 定义抽象标准方法。
* 下例是Typec方式的充电方法和数据传输方法。
*/
abstract class Typec{
public abstract void typecCharge();
public abstract void typecDataTrans();
}
/**
* 抽象目标类的继承类
* 在本模式中不是必须的,只是为了展示无需适配的情况。
*/
class HuaweiTypeC extends Typec{
@Override
public void typecCharge() {
System.out.println("使用TypeC接口充电");
}
@Override
public void typecDataTrans() {
System.out.println("使用TypeC接口传输数据");
}
}
/**
* 被适配类(需要适配的类)
* 有与目标类相同功能的方法,但接口(方法名)不符合标准接口(与目标类内定义
* 的方法的方法名不同)。
* 下例是Typeb类,使用Typeb方式的充电和数据传输方法。
*/
class Typeb{
public void typebCharge() {
System.out.println("使用TypeB接口充电");
}
public void typebDataTrans() {
System.out.println("使用TypeB接口传输数据");
}
}
/**
* 适配器类
* 继承目标抽象类,内部持有一个被适配类实例,实现目标抽象类的抽象方法,在
* 方法内部调用其持有的被适配类的原有方法。
* 下例是Typeb转Typec的适配器。
*/
class AdapterB2C extends Typec{
Typeb typeb = new Typeb();
@Override
public void typecCharge() {
typeb.typebCharge();
}
@Override
public void typecDataTrans() {
typeb.typebDataTrans();
}
}
/**
* 被适配类(需要适配的类)
* 下例是Lightning类,使用Lightning方式的充电和数据传输方法。
*/
class Lightning{
public void lightningCharge() {
System.out.println("使用Lightning接口充电");
}
public void lightningDataTrans() {
System.out.println("使用Lightning接口传输数据");
}
}
/**
* 适配器类
* 下例是Lightning转Typec的适配器。
*/
class AdapterL2C extends Typec{
Lightning ln = new Lightning();
@Override
public void typecCharge() {
ln.lightningCharge();;
}
@Override
public void typecDataTrans() {
ln.lightningDataTrans();
}
}