导言:前5篇文章主要将的创建型设计模式(创建对象、实例),这里开始讲解结构型设计模式。结构型设计模式主要关注的是类和对象的组合
,简化设计。
适配器模式是
将两个不兼容的接口连接到一起
,所以属于结构型
。比如:家用电器使用的是直流电,那么220V的交流电如何使用呢?这时就需要电源适配器来解决接口不兼容的问题;除此之外,如果一个不会英语的人想和外国人交流,就需要一个翻译官,而翻译官就将两个无法交流的人联系到了一起。
适配器模式可以分为4种类型:类适配器模式
、对象适配器模式
、单接口适配器模式(缺省适配器模式)和双向适配器模式。由于后两种复杂且不常用,这里省略对其的介绍。
taget
:想要的目标结果
/**
* @description:
* 作为Traget,适配的结果
* 即:将中文转为英文,英文作为中文转换的最终结果
*/
public interface EnglishLanguage {
String talk();
}
写一个他的实现方法(可以省略,这里用于对比测试结果)
public class EnglishPeople implements EnglishLanguage {
@Override
public String talk() {
return "English People Said Something! 普通类";
}
}
Adaptee
老的接口(要被适配的类或方法)
/**
* @description:
* Adaptee 被适配的对象
* 即:老的接口,需要被转换的类或方法
*/
public class ChineseLanguage {
public String talk() {
return "Chinese People Said Something! 被适配的类";
}
}
Adapter
(翻译官) 提供转换功能。
类适配模式: 继承老的接口
(被转换的接口Adaptee),实现目标接口
(Target)
/**
* @description:
* Adapter 转换方法
* 类适配模式: 继承老的接口(被转换的接口Adaptee),实现目标接口(Target)
*/
public class TranslationAdapter extends ChineseLanguage implements EnglishLanguage {
@Override
public String talk() {
System.out.println("翻译官登场!闲人避让! ");
System.out.println("TranslationAdapter 开始调用父类的talk方法:");
// 由于继承ChineseLanguage, 所以super.talk()会调用ChineseLanguage的talk()方法
return super.talk();
}
}
当写完翻译官(Adapter【适配器】)之后回头看老接口(Adaptee【被适配的】),截图展示(注意画横线的小标识)
【这里的 I 指的是接口,并且指向目标接口
(target)】
并且目标接口
(target)有了两个
实现方法(因为有两个类实现了它)
测试代码:
public static void main(String[] args) {
// 注意:由于实现了一个接口,所以都使用EnglishLanguage接收
// 调用普通方法
EnglishLanguage englishLanguage = new EnglishPeople();
System.out.println(englishLanguage.talk());
// 调用被适配的老接口
EnglishLanguage chineseLanguage = new TranslationAdapter();
System.out.println(chineseLanguage.talk());
// 以后想用老接口,直接找Adatper(翻译官)就行了
}
结果展示:
English People Said Something! 普通类
翻译官登场!闲人避让!
TranslationAdapter 开始调用父类的talk方法:
Chinese People Said Something! 被适配的类
总结一下类适配器模式: 适配类【翻译官】需要继承老接口,实现目标接口
老接口(Adaptee【ChineseLanguage】)、目标接口(Target【EnglishLanguage】)都与上面一致,就翻译官(Adapter)发生了改变。
Adapter
(翻译官)代码:
对象适配模式: 关联老的接口
(被转换的接口Adaptee)【将老接口作为属性】,实现目标接口
(Target)
/**
* @description:
* Adapter 转换方法
* 对象适配模式:
* 关联老的接口(被转换的接口Adaptee)【将老接口作为属性】
* 实现目标接口(Target)
*/
public class TranslationAdapter implements EnglishLanguage {
private ChineseLanguage chineseLanguage;
// TranslationAdapter的有参构造函数,将老接口作为参数传入方法获取实例
public TranslationAdapter(ChineseLanguage chineseLanguage) {
this.chineseLanguage = chineseLanguage;
}
@Override
public String talk() {
System.out.println("翻译官登场!闲人避让! ");
System.out.println("TranslationAdapter 开始调用父类的talk方法:");
// 由于关联ChineseLanguage
// 所以this.chineseLanguage.talk()会调用ChineseLanguage的talk()方法
return this.chineseLanguage.talk();
}
}
当写完翻译官(Adapter【适配器】)之后回头看老接口(Adaptee【被适配的】)
发现没有任何标识了(因为作为了翻译官的属性)
并且目标接口
(target)还是两个
实现方法(因为有两个类实现了它)
测试代码:
public static void main(String[] args) {
// 注意:由于实现了一个接口,所以都使用EnglishLanguage接收
// 调用普通方法
EnglishLanguage englishLanguage = new EnglishPeople();
System.out.println(englishLanguage.talk());
// 调用被适配的老接口,需要传入参数
EnglishLanguage chineseLanguage =
new TranslationAdapter(new ChineseLanguage());
System.out.println(chineseLanguage.talk());
// 以后想用老接口,直接找Adatper(翻译官)就行了
}
结果展示:
English People Said Something! 普通类
翻译官登场!闲人避让!
TranslationAdapter 开始调用父类的talk方法:
Chinese People Said Something! 被适配的类
总结一下对象适配器模式: 老接口成为适配类【翻译官】的属性,并且适配类【翻译官】需要实现目标接口
适配器模式原理很简单,但是使用方式千变万化,通常会结合其他模式一同使用。
代码已经上传到Git:请点击访问
如果大家对于适配器模式还有更多的使用技巧和使用心得,欢迎评论并在评论中分享自己的链接!