适配器模式
首发于:2022-03-26
基本概念
适配器模式(Adapter Pattern)又称包装器模式,将一个类(对象)的接口(方法、属性)转化为用户需要的另一个接口,解决类(对象)之间接口不兼容的问题。
主要功能是进行转换匹配,目的是复用已有的功能,而不是来实现新的接口。也就是说,访问者需要的功能应该是已经实现好了的,不需要适配器模式来实现,适配器模式主要是负责把不兼容的接口转换成访问者期望的格式而已。
现实生活中的例子
适配器模式在现实生活中很常见,比如我们每天都要用的各种手机、电脑、平板的充电头本质就是适配器,把咱们的220V交流电转换成设备能承受的各种电流和电压的直流电。
视频设备的各种转接头也是适配器。
翻译官的场景也是适配器。
应用场景
实战中的应用,例如:jQuery.ajax
适配 Axios
的接口;业务数据的适配;Vue 的计算属性等。适合适配器模式的应用场景一般具备以下特点:
- 如果你想要使用一个已经存在的对象,但是它的接口不满足需求,那么可以使用适配器模式,把已有的实现转换成你需要的接口;
- 如果你想创建一个可以复用的对象,而且确定需要和一些不兼容的对象一起工作,这种情况可以使用适配器模式,然后需要什么就适配什么。
优缺点
优点:
- 已有的功能如果只是接口不兼容,使用适配器适配已有功能,可以使原有逻辑得到更好的复用,有助于避免大规模改写现有代码;
- 可扩展性良好,在实现适配器功能的时候,可以调用自己开发的功能,从而方便地扩展系统的功能;
- 灵活性好,因为适配器并没有对原有对象的功能有所影响,如果不想使用适配器了,那么直接删掉即可,不会对使用原有对象的代码有影响;
缺点:
- 会让系统变得零乱,明明调用 A,却被适配到了 B,如果系统中这样的情况很多,那么对可阅读性不太友好。如果没必要使用适配器模式的话,可以考虑重构,如果使用的话,可以考虑尽量把文档完善。
实现
js
class Person {
speakTo(person, word) {
console.log(word);
return person.listen(word);
}
listen(word) {}
}
class Chinese extends Person {
listen(word) {
switch (word) {
case '你好':
case '谢谢':
console.log('听懂了');
return '听懂了';
default:
console.log('听不懂');
return '听不懂';
}
}
}
class British extends Person {
listen(word) {
switch (word) {
case 'hello':
case 'thank you':
console.log('understand');
return 'understand';
default:
console.log('don\'t understand');
return 'don\'t understand';
}
}
}
class Translator extends Person {
translate(word) {
switch (word) {
case 'hello':
return '你好';
case 'thank you':
return '谢谢';
case '你好':
return 'hello';
case '谢谢':
return 'thank you';
default:
return '我也不会。'
}
}
listen(word) {
const res = this.translate(word);
return res;
}
}
const c = new Chinese();
const b = new British();
const t = new Translator();
c.speakTo(b, '你好');
b.speakTo(c, 'hello');
const res = c.speakTo(t, '你好');
t.speakTo(b, res);
输出:
你好
don't understand
hello
听不懂
你好
hello
understand