适配器模式
将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作
想要使用一个已经存在的对象,但是其方法或属性接口不符合我们的要求,所以需要对其进行适配。
例如:usb接口转换器
适配器模式中主要角色
目标(Target)角色:定义客户端使用的与特定领域相关的接口,这也就是我们所期待得到的。
源(Adaptee)角色:需要进行适配的接口。
适配器(Adapter)角色:对Adaptee的接口与Target接口进行适配;适配器是本模式的核心,适配器把源接口转换成目标接口,此角色为具体类。
适配器模式适用场景
1、你想使用一个已经存在的类,而它的接口不符合你的需求。
2、你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类协同工作。
3、你想使用一个已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口(仅限于对象适配器)。
适配器的小例子
假设有一个香港版的插头,由于其插头样式怪异,无法插入内地的插座中,如果我们想要使用这个香港版插头,就需要一个适配器来进行适配。代码如下:
// 香港版插头
class Plug{
fn(){
return "香港的插头"
}
}
// 适配插头
class Target{
constructor() { // 旧的接口不能丢也不能修改
this.plug = new Plug() // 这里是旧的接口:香港版插头
}
adaptePlug(){ // 这里就是进行适配,将旧的接口与新的接口进行适配
return this.plug.fn() + "使用适配器,适配成为中国内地版插头" // 这里面写如何适配,适配的内容
}
}
let gn = new Target() // new一个适配器
gn.adaptePlug() // 适配器调用适配后的接口
适配器的原则及优缺点
不能影响原来的功能,也就是不能修改原来旧接口的代码
原来的功能要拿过来,在原来的基础上再去进行相关的适配和调整
优点:简单,复用性比较高
缺点:系统的层级复杂,会包装许多函数
适配器的具体用途
1.用适配器保证传入参数的完整性与顺序性:
// 用适配器保证传入参数的完整性与顺序性:
function doThing(name,title,age,color,size,flag){ //这个参数很多,万一传漏了或者传错位置就不好
// 假设这是具体执行的操作
return `${name}今年${age}岁,喜欢的颜色是${color},长度是${size},梦想是${flag},${title}`
}
// 上面的doThing函数,参数很多,如果我们要使用它,需要将参数一一对应,还不能漏传,极其不友好。
// 我们要的结果是,哪怕我们的数据位置不一样或者漏传,用适配器也能保证参数不出问题
var message = { // 这是我们需要接收的数据
name:"remi",
title:"小目标",
age:18,
color:"yellow",
size:180,
flag:"一个亿"
}
// 适配器
function adaptDoThing(obj){
// 默认的数据,如果没传或者漏传就用默认的参数数据
var _adapt = {
name:"张三",
title:"不想努力了",
age:99,
color:"green",
size:18,
flag:"富婆,软饭,饿饿"
}
// 这一步才是真正的适配
for(var i in _adapt){
obj[i] = obj[i] || _adapt[i] // 用一个for in循环,实参要么等于形参(传了),要么等于默认的参数(没传)
}
return doThing(obj.name,obj.title,obj.age,obj.color,obj.size,obj.flag) // 此时我们对传入的参数进行适配,使其位置与原来的一一对应
}
console.log(adaptDoThing(message)) // 全部都传对了的情况
var a = {name:"a"}
console.log(adaptDoThing(a)) // 对象参数不齐的情况
2.适配器用于参数类型转换:
// 适配器用于参数类型转换
// 例如现在我们得到的一个数据是数组形式
var arr = []
arr.age = 18
arr.name = "remi"
arr.feature = "精壮"
function arrToObj(arr){ // 适配器函数,数组转对象形式
var newObj = {}
for(var i in arr){
newObj[i] = arr[i]
}
return newObj
}
var obj = arrToObj(arr)
console.log(obj) // 这时候我们就能得到对象形式的数据
3.适配器用于代码兼容:
// 适配器用于代码兼容
// 有些浏览器是用new XMLHttpRequest()创建ajax对象,有些浏览器是用ActiveXObject("Microsoft.XMLHTTP")创建ajax对象
function XMLHTTP(){
if(window.ActiveXObject){ // 如果兼容这个则返回这个创建ajax
return ActiveXObject("Microsoft.XMLHTTP")
}else{ // 否则返回这个创建ajax
return new XMLHttpRequest()
}
}
XMLHTTP() // 创建ajax对象