适配器在我们的现实生活中有许多应用,比如说电源适配器,网络适配器等等,接下来我们将会通
过一个例子来说说适配器的作用,看下图是一个电源的适配器
这个黑色的小盒子就是一个适配器,该适配器的作用就是将家用的220v电压转换为适合笔记本电脑使用的5v至20v左右的稳定电压,这个是我们现实中的例子。
在我们软件的世界中也有适配器的例子存在,比如说我们现在有一个类,该类是通过uniapp获取定位的经纬度,以及对这些经纬度进行一些操作,现在我们想要将该项目编译为APP,在APP中获取定位并且展示到高德地图中,但是你会发现在微信小程序获取的定位坐标系是WGS-84格式,放在APP的高德地图中定位不准确了,因为高德的坐标系是用GCJ-02的模式这时候就需要用到适配器将WGS-84格式的坐标转为GCJ-02格式的坐标。代码如下
type location = {
latitude: number,
longitude: number
}
// 微信小程序获取定位
class CustomLocation {
location?: location
getLocation(): location {
// 模拟调用wx获取定位接口
// uni.getLocation
return {
latitude: 100,
longitude: 50
}
}
otherOperate() {
console.log('进行一些其它的操作')
}
}
// 兼容其它终端的定位
export class Adaptee {
getOtherLocation(): location {
// 模拟调用wx获取定位接口
// uni.getLocation
return {
latitude: 100,
longitude: 50
}
}
}
// GCJ-02坐标的适配器
export class APPAdapter extends CustomLocation{
private adaptee: Adaptee
constructor(adaptee: Adaptee) {
super();
this.adaptee = adaptee
}
getLocation(): location {
return this.toGCJ02(this.adaptee.getOtherLocation())
}
// 模拟转为GCJ02格式的坐标
private toGCJ02(location: location): location {
location.latitude = location.latitude*0.2
location.longitude = location.longitude*1.2
return location
}
}
// Web坐标适配器
export class WebAdapter extends CustomLocation {
private adapter: Adaptee
constructor(adapter: Adaptee) {
super();
this.adapter = adapter
}
getLocation(): location{
return this.toBD09(this.adapter.getOtherLocation())
}
// 模拟转为BD09的坐标
private toBD09(location: location): location {
location.longitude = location.longitude * 0.08
location.latitude = location.latitude * 0.88
return location
}
otherOperate() {
console.log('对方法进行重写')
}
}
在这个例子中,CustomLocation 是原先微信小程序使用的类,因为坐标系不同,所以我们将需要适配的方法提取出来放在Adaptee这个类中,需要兼容APP端只需要定义一个类APPAdapter继承CustomLocation类,将Adaptee作为APPAdapter这个类的私有变量,对CustomLocation的类方法getLocaion进行重写返回适配后的坐标即可。客户端使用如下:
const adaptee = new Adaptee()
const appAdapter = new APPAdapter(adaptee)
console.log(appAdapter.getLocation())
const webAdapter = new WebAdapter(adaptee)
console.log(webAdapter.getLocation())
该模式的优点:
1. 符合开闭原则,新适配一种坐标系只需要新增一个类继承初始的类即可
2. 符合单一职责原则
该模式的缺点:
1. 代码容易复杂化,有时候你需要适配只需要在原类中新增一个适配方法即可