TS 设计模式04 - 适配器模式
1. 简介
笔记本实际上使用的是 12V 直流电,但是我们电源线是插在 220V 的交流电源上。我们不能把 220V 的交流电源直接改成符合要求的 12V 直流电源,因为不便于运输,也没法让笔记本直接使用 220V 的交流电,因为其元器件无法承担。 220V 交流电源和笔记本本质上是无法直接放到一起工作的,那么就需要电源适配器的辅助。它能够利用 220V 交流电源获取电能,并转换成 12V 直流电输出给笔记本。 这就是适配器模式,将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
2. 角色与分类
角色:
- Target(目标):客户的目标接口,可以是一个抽象类或接口,也可以是具体类。
- Adaptee(适配者):被适配的角色,是一个已有接口,但不符合客户要求。
- Adapter(适配器):将已有接口转换成目标接口
分类:
- 类适配器模式
- 对象适配器模式
- 缺省适配器模式,也叫接口适配器模式
3. 类适配器模式
Adapter 可以继承一个已有的 Adaptee,然后实现 Target。这种情况下只能有一个 Adaptee,且 Target 必须是接口。
image.png
interface PowerTarget {
output12V(): string;
}
class PowerAdaptee {
output220V() {
return '220V 交流电';
}
}
const adapt = (input) => {
// TODO 具体转换逻辑
console.log(`${input} 被转换成 12V 直流电`);
return '12V 直流电';
};
class PowerAdapter extends PowerAdaptee implements PowerTarget {
public output12V() {
const input = this.output220V();
console.log(`电源适配器开始工作,获取:${input}`);
const output = adapt(input);
console.log(`电源适配器工作完成,输出:${output}`);
return output;
}
}
const target: PowerTarget = new PowerAdapter();
target.output12V();
image.png
4. 对象适配器模式
Adapter 可以关联个已有的 Adaptee,然后实现 Target。这种情况下你要依赖多个 Adaptee 实现也是 okay 的,Target 可以是接口也可以是抽象类甚至是类。 不过这里因为是关联,所以改写关联对象的方法就很麻烦了,不像继承那么简单。
image.png
interface PowerTarget {
output12V(): string;
}
class PowerAdaptee {
output220V(): string {
return '220V 交流电';
}
}
const adapt = (input) => {
// TODO 具体转换逻辑
console.log(`${input} 被转换成 12V 直流电`);
return '12V 直流电';
};
class PowerAdapter implements PowerTarget {
private powerAdaptee: PowerAdaptee;
constructor() {
this.powerAdaptee = new PowerAdaptee();
}
public output12V(): string {
const input = this.powerAdaptee.output220V();
console.log(`电源适配器开始工作,获取:${input}`);
const output = adapt(input);
console.log(`电源适配器工作完成,输出:${output}`);
return output;
}
}
const target: PowerTarget = new PowerAdapter();
target.output12V();
5. 小结
其实还有一种缺省适配器模式,就是只想实现 target 接口定义的部分方法,那么在 adapter 和 target 之间加一层 defaultAdapter,用空方法实现 target 的所有接口,真正的 adapter 就可以选择性的重写 defaultAdapter 中需要去适配的方法了。本质上还是用的类适配器模式和对象适配器模式。 可以看到,适配器模式,也可以看做是对方法的一种抽象,客户依赖的接口不变,但是接口方法的实现可以用一个或多个现成的类来辅助实现。
- 【干货】基于TensorFlow卷积神经网络的短期股票预测
- [编程经验] 基于bs4的拉勾网AI相关工作爬虫实现
- [编程经验] 链家23个全国主要城市的现房数据分析
- [编程经验] Python中的modlue和packages的区别
- Day5上午解题报告
- [编程经验] Pandas中比较好用的几个方法
- [编程经验] Elasticsearch 初识
- 2017.10.26水题大作战部分题解
- 2017.10.27涩会题大乱斗部分题解
- 【 关关的刷题日记50】 Leetcode 345. Reverse Vowels of a String
- Day1上午解题报告
- 【 关关的刷题日记51】 Leetcode 67. Add Binary
- 【 关关的刷题日记53】 Leetcode 100. Same Tree
- Day1下午解题报告
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Mybatis系列第三讲 Mybatis使用详解(1)
- Maven系列第二讲 安装、配置、mvn运行过程详解
- Maven第六讲 生命周期详解 高手必备!
- 鸿蒙 Ability 讲解(页面生命周期、后台服务、数据访问)
- Maven 项目第七讲 Maven插件
- weblogic Schema validation schemaValidationEnabled=false 启动报错解决
- redis 反序列化deserialize异常问题解决
- redis 入门(二)——maven4.0 + Jedis2.9.0 + redis3.2.6 实战
- spring boot 启动报错Log4j2 could not find a logging implementation 解决
- spring boot 启动 NoClassDefFoundError: org/springframework/core/ErrorCoded 报错
- java.lang.NoSuchMethodError: org.springframework.core.ResolvableType.forInstance 错误解决
- spring boot启动 no method 'getPersistenceUtil'报错解决
- spring redis java.lang.IllegalStateException: Cannot load configuration class: redis.RedisTemplet报错
- Elasticsearch: Index template
- 基于rest风格对Neo4j进行调用访问之———httpClient