欢迎来到DIVCSS5查找CSS资料与学习DIV CSS布局技术!
模式动机
 
适配器模式的作用就是解决两个软件实体间接口不兼容情况.
 
通常情况下,使用者可以通过目标类的接口访问它所提供的服务。开始时候没有什么问题, 但是一但后续别的接口(如第三方接口)有变动或者后续扩展需求, 此时使用原有接口已经不可以提供服务, 那么我们就需要把现有接口转化为使用者需要的接口.适配器模式就是用来完成这样的转化.
 
在适配器模式中可以定义一个包装类,包装不兼容接口的对象,这个包装类指的就是适配器(Adapter),它所包装的对象就是适配者(Adaptee),即被适配的类。
 
模式定义
 
适配器模式(Adapter Pattern) :将一个接口转换成使用者希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)。适配器模式既可以作为类结构型模式,也可以作为对象结构型模式。
 
模式结构
 
适配器模式包含如下角色:
 
Target:目标抽象类
 
Adapter:适配器类
 
Adaptee:适配者类
 
Client:客户类
 
现实世界举例论证
 
现在世界中的适配器模式使用如: 港式插头转换器, 电源适配器, USB转接口。
 
需求举例代码实现
 
我们需要完成一个集成多个第三方地图sdk进行地图渲染功能:
 
// 谷歌地图,百度地图sdk都有show方法进行调用。
 
const googleMap = {
 
    show () {
 
        // 具体谷歌sdk的实现
 
        console.log('开始使用谷歌地图渲染')
 
    }
 
};
 
const baiduMap = {
 
    show () {
 
        // 具体百度sdk的实现
 
        console.log('开始使用百度地图渲染')
 
    }
 
}
 
// renderMap方法是提供给使用者来调用
 
const renderMap = (map) => {
 
    if (map.show instanceof Function) {
 
        map.show();
 
    }
 
};
 
renderMap(googleMap);
 
renderMap(baiduMap);
 
这个时候产品需要我们集成高德地图sdk,但是高德地图渲染方法不是show方法,而是render方法.
 
这个时候我们不应该去改动之前的源代码违反开闭原则. 而应该想到适配器模式.
 
// 谷歌地图,百度地图sdk都有show方法进行调用。
 
const googleMap = {
 
    show () {
 
        // 具体谷歌sdk的实现
 
        console.log('开始使用谷歌地图渲染')
 
    }
 
};
 
const baiduMap = {
 
    show () {
 
        // 具体百度sdk的实现
 
        console.log('开始使用百度地图渲染')
 
    }
 
}
 
const gaodeMap = {
 
    render () {
 
        // 具体高德sdk的实现
 
        console.log('开始使用高德地图渲染')
 
    }
 
}
 
// 适配器
 
const gaodeMapAdapater = {
 
    show () {
 
        return gaodeMap.render();
 
    }
 
}
 
// renderMap方法是提供给使用者来调用
 
const renderMap = (map) => {
 
    if (map.show instanceof Function) {
 
        map.show();
 
    }
 
};
 
renderMap(googleMap);
 
renderMap(baiduMap);
 
renderMap(gaodeMapAdapater);
 
另外一个例子也是我们常见的场景---数据格式变更, 这个我在开发中经常遇到:
 
// 这是我们之前上传资源, 后台返回给我们的文件信息.
 
const responseUploadFile = {
 
    startTime: '',
 
    file: {
 
        size: '100kb',
 
        type: 'text',
 
        url: '',
 
        name: '',
 
        ...
 
    },
 
    id: ''
 
}
 
// 如果某天后台突然说因为某些原因后续上传文件返回格式有变动了。如下
 
const changeResUploadFile = {
 
    size: '100kb',
 
    type: 'text',
 
    url: '',
 
    name: '',
 
    startTime: '',
 
    id: ''
 
}
 
// 由于我们之前使用旧格式数据做了很多业务逻辑,这个时候不能其改动,容易导致bug而且需求进行回归测试.
 
// 采用适配器模式
 
const responseUploadFileAdapter = (uploadFile) => {
 
    // 在这里对新的数据进行拼接转化
 
}
 
模式分析
 
优点:
 
将目标类和适配者类解耦,通过引入一个适配器类来重用现有的适配者类,而无须修改原有代码。
 
增加了类的透明性和复用性,将具体的实现封装在适配者类中,对于客户端类来说是透明的
 
灵活性和扩展性都非常好,通过使用配置文件,可以很方便地更换适配器,也可以在不修改原有代码的基础上增加新的适配器类,完全符合“开闭原则”。
 
适用环境
 
系统需要使用现有的类,而这些类的接口不符合系统的需要。
 
想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。
 
参考资料

如需转载,请注明文章出处和来源网址:http://www.divcss5.com/html/h63333.shtml