适配器模式的出现是为了满足各种不同的需求,我们在做开发的时候,经常会用到一个中间层来进行适配,这个中间层就起到了适配器模式的作用。
学习的时候,有一个很好的例子就是笔记本对电压的要求和家庭电压的矛盾,总是笔记本需要一个变压器来解决这个问题,变压器便是一个适配器。
给一个相关的伪代码:
//Target
public interface ComputerVolt {
public int computerVolt();
}
//Adaptee
public class HomeVolt {
public int homeVolt() {
return 220;
}
}
//adapter
public class ClassAdapter extends HomeVolt implements ComputerVolt {
@Override
public int computerVolt() {
return 12;
}
}
通过这个方式我们就成功的解决了电源适配的问题,ClassAdapter就是适配器,这就是一个简单的适配器模式。
适配器模式可分为两种:
一种是类适配器模式(继承方式)
一种是对象适配器模式(委托方式)
类适配器模式
一个简单的需求场景:
一段文字需要翻译为中文和英文,根据这个场景我们来一步一步完成继承方式的适配器模式。
首先我们有一个类专门为显示中文和英文的功能:
public class Display {
private String word;
public Display(String word) {
this.word = word;
}
//显示中文
public void displayChinese() {
............chinese..........
}
public void displayEnglish() {
...........English............
}
}
而我们需要的翻译功能的接口为:
public interface Translation {
void chinese2English();
void english2Chinese();
}
为了实现我们的翻译需求,此时便需要一个适配器的角色:
public class TranslationImpl extends DisPlay implements Translation {
public TranslationImpl(String word) {
super(word);
}
@Override
public void chinese2English() {
displayEnglish();
}
@Override
public void english2Chinese() {
displayChinese();
}
}
接下来看看测试函数:
public class Main {
public static void main(String[] args) {
Translation trans = new TranslationImpl("test");
trans.english2Chinese();
trans.chinese2English();
}
}
通过测试代码,我们发现暴露在外面的只是Translation接口,Display类对于使用者来说是完全处于不存在状态的,而且也不知道TranslationImpl是如何实现翻译功能的,就好比我们在使用笔记本的时候并不知道电源适配器是怎么将家庭电压转化为笔记本的适用电压。如果我们需要修改实现方式,我们直接修改其实现方式,完全不影响其他端。
对象适配器模式
对象适配器模式,委托方式,简单来说就是交给其他实例来完成需要实现的功能。
我们依然采用刚才的例子来解释对象适配器,不过在这里我把之前的Translation接口改成一个类,由于在Java中是单继承模式,因此我们TranslationImpl不能同时作为Translation和Display的子类存在,但是根据对象适配器模式的委托思想,我们应该能够猜到怎么去实现这个需求了。
首先是Translation类:
public abstract class Translation {
public abstract void chinese2English();
public abstract void english2Chinese();
}
Display类则保持不变、最后是TranslationImpl的实现方式:
public class TranslationImpl extends Translation {
private Display display;
public TranslationImpl(String word) {
display = new Display(word);
}
@Override
public void chinese2English() {
display.displayEnglish();
}
@Override
public void english2Chinese() {
display.displayChinese();
}
}
实现思想就是:
将Display的实例以TranslationImpl的变量的形式保存,且在TranslationImpl构造函数类生成,其展示方法我们通过变量的形式来调用,这就相当于我们将要执行的任务委托给了Display的实例去实现。
什么时候适用
做开发的时候,并不是都是从零开始,很多时候都是在已有的项目基础上进行扩展,因此很多东西可能都是已有的,而且是经过很多次检验的代码,因此我们更愿意复用这类代码,而不是重新去编写。而且该模式是适配现有的类产生新类,因此产生问题后,我们能够快速定位问题到新产生的类进行分析,而不会出现在现有的类中,能够节约很大的开发成本。
网友评论