文章目录- I . 适配器模式 ( 类适配器 ) 代码模板
- II . 适配器模式 ( 对象适配器 ) 代码模板
- III . 适配器模式 代码示例
I . 适配器模式 ( 类适配器 ) 代码模板
1 . 明确被适配者 : 被适配者 是一个现有类 , 该类保持不变 ;
① 现有类 : 实际开发时, 该类并不需要定义 , 这里给出示例 ;
② 调用行为 : 最终的用户目标接口 , 是要调用 Adaptee 类对象的 adapteeFunction 方法 ;
代码语言:javascript复制package kim.hsl.design.adapter.classadapter;
/**
* 被适配者 : 现有的功能类
* 提供实际的功能, 及实现相关操作
*
* 这是被调用的现有类 , 但是不能使用 adapteeRequest 方法
* 要使用用户 TargetInterface 接口的 request 方法
*/
public class Adaptee {
public void adapteeFunction(){
System.out.println("类适配器测试 : 被适配者方法");
}
}
2 . 定义用户目标接口 : 用户通过调用该接口 , 实现实际的功能 , 该功能与适配者中的功能类似 , 但 接口不同 ;
① 用户调用 : 最终用户调用方法时 , 会创建 TargetInterface 接口子类类对象 , 并调用其中的 userCall 方法 ;
② 实现途径 : 在一个第三方类中 , 实现该 TargetInterface 接口 , 重写 userCall 方法 , 在该方法中调用 Adaptee 的 adapteeFunction 方法 ; ( 这个第三方类 , 就是适配器 )
代码语言:javascript复制package kim.hsl.design.adapter.classadapter;
/**
* 目标接口
* 用户调用的是该接口的 userCall 方法
*
* 注意 : 适配器需要实现目标接口
*/
public interface TargetInterface {
//用户调用的方法
void userCall();
}
3 . 声明适配器 ( 类适配器 ) :
① 适配器 实现 用户目标接口 : 适配器 需要实现 用户目标接口 , 在实现的接口方法中 , 需要将实际操作 委托给 被适配者 ;
② 适配器 实现 用户目标接口 代码实现说明 :此处 Adapter 适配器类 , 实现了 TargetInterface 接口 , 并实现了 userCall 方法 , 目的是为了让用户有可调用的接口 ;
③ 适配器 继承 被适配者 : 如何调用到 被适配者 的方法呢 , 这里 适配器 通过 继承 被适配者 , 获取调用 被适配者 方法的资格 ;
④ 适配器 继承 被适配者 代码实现说明 :Adapter 适配器继承了 Adaptee 被适配者 , 目的是为了获取调用 Adaptee 父类的 adapteeFunction 方法 ;
⑤ 委托操作 : 在实现的 用户目标接口中 , 通过 super 关键字 , 调用 被适配者 的方法实现具体功能 ;
⑥ 委托操作代码实现说明 : 在 TargetInterface 接口的 userCall 方法中 , 调用 Adaptee 父类的 adapteeFunction 方法 , 这样就可以在不用修改代码的情况下 , 让用户可以通过创建 TargetInterface 接口对象 , 调用 userCall 方法 , 从而间接调用到 Adaptee 类的 adapteeFunction 方法 ;
代码语言:javascript复制package kim.hsl.design.adapter.classadapter;
/**
* 适配器类
*
* 适配器类 继承了 被适配者 类, 目的是为了访问其 adapteeFunction 函数
* 同时其实现了 TargetInterface 接口 , 在 重写的 userCall 方法中 ,
* 调用 Adaptee 父类的 adapteeFunction 方法 , 将实际的操作委托给了父类方法
*/
public class Adapter extends Adaptee implements TargetInterface {
@Override
public void userCall() {
//将父类 Adaptee 的 request 方法适配给了 TargetInterface 接口
super.adapteeFunction();
}
}
类适配器 与 对象适配器 , 本质区别就是 适配器类访问 被适配者的途径 ; 类适配器 : 通过继承 被适配器 , 获取访问被适配器方法的资格 ; 对象适配器 : 通过在其内部维护一个 被适配者 成员变量 , 进而通过该成员变量访问 被适配者方法 ;
4 . 用户访问操作 :
① 定义目标接口变量 : 定义 用户目标接口 对象变量 ; 用户定义 TargetInterface 类型变量 , 为其赋值适配器对象 Adapter 类对象作为其变量值 ;
② 目标接口变量赋值 : 创建 适配器对象 赋值给上述 用户目标接口对象变量 , ( 适配器 是 用户目标接口 的子类 ) ;
③ 目标接口调用 : 调用用户目标接口 , 即可调用被适配者的实际功能方法 ; 用户直接调用 TargetInterface 接口的 userCall 方法 , 实际上被适配器委托给了 Adaptee 的 adapteeFunction 方法 ;
代码语言:javascript复制package kim.hsl.design.adapter.classadapter;
public class Main {
public static void main(String[] args) {
//用户创建的类时 目标接口 类型对象
//但创建对象时 , 创建的是适配器对象
//适配器对象 实现了 TargetInterface 接口 , Adapter 是 TargetInterface 子类
//适配器中重写的 userCall 方法实际上委托给了 Adaptee 被适配者对象 成员
TargetInterface targetInterface = new Adapter();
targetInterface.userCall();
}
}
执行结果 :
代码语言:javascript复制类适配器测试 : 被适配者方法
II . 适配器模式 ( 对象适配器 ) 代码模板
1 . 明确被适配者 : 被适配者 是一个现有类 , 该类保持不变 ;
① 现有类 : 实际开发时, 该类并不需要定义 , 这里给出示例 ;
② 调用行为 : 最终的用户目标接口 , 是要调用 Adaptee 类对象的 adapteeFunction 方法 ;
代码语言:javascript复制package kim.hsl.design.adapter.objectdapter;
/**
* 被适配者 : 现有的功能类
* 提供实际的功能, 及实现相关操作
*
* 这是被调用的现有类 , 但是不能使用 adapteeRequest 方法
* 要使用用户 TargetInterface 接口的 request 方法
*/
public class Adaptee {
public void adapteeFunction(){
System.out.println("对象适配器测试 : 被适配者方法");
}
}
2 . 定义用户目标接口 : 用户通过调用该接口 , 实现实际的功能 , 该功能与适配者中的功能类似 , 但 接口不同 ;
① 用户调用 : 最终用户调用方法时 , 会创建 TargetInterface 接口子类类对象 , 并调用其中的 userCall 方法 ;
② 实现途径 : 在一个第三方类中 , 实现该 TargetInterface 接口 , 重写 userCall 方法 , 在该方法中调用 Adaptee 的 adapteeFunction 方法 ; ( 这个第三方类 , 就是适配器 )
代码语言:javascript复制package kim.hsl.design.adapter.objectdapter;
/**
* 目标接口
* 用户调用的是该接口的 userCall 方法
*
* 注意 : 适配器需要实现目标接口
*/
public interface TargetInterface {
//用户调用的方法
void userCall();
}
3 . 声明适配器 ( 类适配器 ) :
① 适配器 实现 用户目标接口 : 适配器 需要实现 用户目标接口 , 在实现的接口方法中 , 需要将实际操作 委托给 被适配者 ;
② 适配器 实现 用户目标接口 代码实现说明 :此处 Adapter 适配器类 , 实现了 TargetInterface 接口 , 并实现了 userCall 方法 , 目的是为了让用户有可调用的接口 ;
③ 适配器 维护 被适配者 类型成员变量 : 如何调用到 被适配者 的方法呢 , 这里 适配器 通过 定义 被适配者 类型的成员变量 , 通过该 被适配者 类型成员变量 , 调用 被适配者 public 方法 ;
④ 适配器 维护 被适配者 类型成员变量 代码实现说明 :Adapter 适配器中定义了一个 Adaptee 被适配者成员变量 , 目的是为了通过该成员变量 , 调用 Adaptee 的 adapteeFunction 方法 ;
⑤ 委托操作 : 在实现的 用户目标接口中 , 通过 super 关键字 , 调用 被适配者 的方法实现具体功能 ;
⑥ 委托操作代码实现说明 : 在 TargetInterface 接口的 userCall 方法中 , 调用 Adaptee 父类的 adapteeFunction 方法 , 这样就可以在不用修改代码的情况下 , 让用户可以通过创建 TargetInterface 接口对象 , 调用 userCall 方法 , 从而间接调用到 Adaptee 类的 adapteeFunction 方法 ;
代码语言:javascript复制package kim.hsl.design.adapter.objectdapter;
/**
* 适配器类
*
* 适配器类 维护了一个 被适配者的对象 Adaptee 成员变量
* 同时又实现了目标接口 TargetInterface
* 当用户调用 TargetInterface 接口的 userCall 方法时
* 将实际的操作委托给 Adaptee 接口的 adapteeFunction 方法
*/
public class Adapter implements TargetInterface {
//通过维护成员变量的方式 , 将 TargetInterface 接口的 request 方法
// 委托给 Adaptee 接口的 adapteeRequest 方法
private Adaptee adaptee = new Adaptee();
@Override
public void userCall() {
//将父类 Adaptee 的 request 方法适配给了 TargetInterface 接口
adaptee.adapteeFunction();
}
}
类适配器 与 对象适配器 , 本质区别就是 适配器类访问 被适配者的途径 ; 类适配器 : 通过继承 被适配器 , 获取访问被适配器方法的资格 ; 对象适配器 : 通过在其内部维护一个 被适配者 成员变量 , 进而通过该成员变量访问 被适配者方法 ;
4 . 用户访问操作 :
① 定义目标接口变量 : 定义 用户目标接口 对象变量 ; 用户定义 TargetInterface 类型变量 , 为其赋值适配器对象 Adapter 类对象作为其变量值 ;
② 目标接口变量赋值 : 创建 适配器对象 赋值给上述 用户目标接口对象变量 , ( 适配器 是 用户目标接口 的子类 ) ;
③ 目标接口调用 : 调用用户目标接口 , 即可调用被适配者的实际功能方法 ; 用户直接调用 TargetInterface 接口的 userCall 方法 , 实际上被适配器委托给了 Adaptee 的 adapteeFunction 方法 ;
代码语言:javascript复制package kim.hsl.design.adapter.objectdapter;
public class Main {
public static void main(String[] args) {
//用户创建的类时 目标接口 类型对象
//但创建对象时 , 创建的是适配器对象
//适配器对象 实现了 TargetInterface 接口 , Adapter 是 Target 子类
//适配器中重写的 userCall 方法实际上委托给了 Adaptee 被适配者对象 成员
TargetInterface target = new Adapter();
target.userCall();
}
}
执行结果 :
代码语言:javascript复制对象适配器测试 : 被适配者方法
III . 适配器模式 代码示例
1 . 需求描述 : 家庭中的插座提供 220 V 电压 , 手机需要使用 5V 电压进行充电 ;
2 . 适配器模式建模 :
① 被适配者 : 家庭中提供的 220 V 电压 ;
② 用户调用接口 : 手机使用 5 V 电压充电 ;
③ 适配器 : 将家庭的 220 V 电压转为手机充电的 5 V 电压 ;
3 . 被适配者 : 家庭电压 220 V ; HomePower220V 类提供原本的功能 ; 最终用户的目标接口调用的是该类的 power220V 方法 ;
代码语言:javascript复制package kim.hsl.design.adapter.demo;
/**
* 被适配者
* 代表 220V 电压
*/
public class HomePower220V {
public int power220V(){
System.out.println("输出 220V 电压");
return 220;
}
}
4 . 用户接口 : 手机使用 5 V 电压充电 , 最终使用的电压是 5V ; 调用 HomePower220V 的 power220V 方法 , 接口不同 , 需要使用适配器转换 ;
代码语言:javascript复制package kim.hsl.design.adapter.demo;
/**
* 目标接口 : 手机充电器
* 输出 5V 电压
*/
public interface PhoneCharge {
int power5V();
}
5 . 适配器 : 将家庭的 220 V 输出电压 , 转为输出 5 V 电压 ;
① 实现接口 : 适配器 Adapter 实现 PhoneCharge 接口 , 实现 power5V 方法 ;
② 维护成员变量 : 在适配器中维护 HomePower220V 成员变量 , 在 power5V 方法中调用 HomePower220V 类的 power220V 方法 ;
③ 目的 : 达到了适配 被适配者 HomePower220V 和 用户目标接口 PhoneCharge 的接口适配 ;
代码语言:javascript复制package kim.hsl.design.adapter.demo;
/**
* 适配器
* 输入 220V 电压, 输出 5V 电压
*/
public class Adapter implements PhoneCharge {
private HomePower220V ac220V = new HomePower220V();
@Override
public int power5V() {
int input = ac220V.power220V();
//将 220 V 处理成 5V
System.out.println("220V 转为 5V 电压");
return 5;
}
}
6 . 用户接口调用 :
① 用户行为 : 用户方创建 PhoneCharge 接口对象 , 将适配器对象赋值给该 PhoneCharge 接口变量 , 调用时调用 PhoneCharge 接口的 power5V 方法 ,
② 委托操作 : 适配器中实现的 power5V 方法 , 实际被委托给了 HomePower220V 被适配者的 power220V 方法 ;
代码语言:javascript复制package kim.hsl.design.adapter.demo;
public class Main {
public static void main(String[] args) {
PhoneCharge phoneCharge = new Adapter();
phoneCharge.power5V();
}
}
执行结果 :
代码语言:javascript复制输出 220V 电压
220V 转为 5V 电压