• javascript设计模式之适配器模式


    定义

    适配器模式可用来在现有接口和不兼容的类之间进行适配。它被添加到现有代码中来协调两个不同的接口。就类似于苹果电脑的 type-c 接口和U盘之间的接口转换器,解决兼容性问题。

    场景

    1、该模式适用于期待接口与现在接口不兼容。

    2、适配器所适配的两个方法执行需是类似的任务。

    3、接口最好是成形的。如果新接口或者现有的老接口没有成型,那么适配器不会一直管用,就失去了它的意义。

    解决

    当我们需要用原有代码,但需要有一定的改动。
    最好不直接去改动,因为可能大规模改写现有代码,也可能会因此导致原有代码出现问题。所以建议封装一个方法。

    例子

    1、适配器模式在 vue 中的应用

    Original message: "{{ message }}"

    Computed reversed message: "{{ reversedMessage }}"

    var vm = new Vue({ el: '#example', data: { message: 'hello' }, computed: { // 计算属性的 getter reversedMessage: function () { // `this` 指向 vm 实例 return this.message.split('').reverse().join('') } } })
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    message 这个属性的值是 ‘Hello’,但我想要的是一个倒转的 ‘Hello’, 通过computed 中的 reversedMessage 方法, 我们得到了目标 ‘olleh’,且没有改变原有的数值。这里的 reversedMessage 就相当于一个适配器。

    2、适配器模式在 ts 中的应用

    type Person = {
      name: string,
      age: number
    }
     
    const jack: Person = {
      name: 'Jack',
      age: 11
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    如果这个时候,我只想定义name或者age要怎么做?可以把上面的Person改成:

    type Person = {
      name?: string,
      age?: number
    }
    
    • 1
    • 2
    • 3
    • 4

    加上‘?’,表示这个属性可选。但这样真的好吗?如果我们引用的是第三方的库,或者我们改动了代码不够严谨了,那怎么办?考虑到这些,我们建议不直接修改。这个时候 ts 的 utility type 帮我们解决了这个问题。

    const jack: Partial = {} // 直接这样写就行了
    
    • 1

    我们来看 ts 关于 Partial 的源码,遍历 Person 里面的 key,给每个 key 加上‘?’

    type Partial = {
      [P in keyof T]?: T[P];
    };
    
    • 1
    • 2
    • 3

    这个 Partial 的使用就是适配器的思想。

    3、后端数据适配

    我们都知道很多UI组件或者工具库会按指定的数据格式进行渲染,但是这个时候后端是不知道的;所以可能接口出来的数据我们是不能直接正常的在页面上渲染的,而此时老板催促我们赶紧上线,而后端坚持认为数据格式没问题,坚决不修改;这个时候我们可以通过适配器模式来前端格式化数据;

    后端返回的json数据格式:

    [
      {
        "day": "周一",
        "uv": 6300
      },
      {
        "day": "周二",
        "uv": 7100
      },  {
        "day": "周三",
        "uv": 4300
      },  {
        "day": "周四",
        "uv": 3300
      },  {
        "day": "周五",
        "uv": 8300
      },  {
        "day": "周六",
        "uv": 9300
      }, {
        "day": "周日",
        "uv": 11300
      }
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    Echarts图表图形需要的数据格式:

    ["周二", "周二", "周三", "周四", "周五", "周六", "周日"] //x轴的数据
    
    [6300. 7100, 4300, 3300, 8300, 9300, 11300] //坐标点的数据
    
    • 1
    • 2
    • 3

    虽然心里苦,但还是要解决问题!使用适配器来解决:

    //x轴适配器
    function echartXAxisAdapter(res) {
      return res.map(item => item.day);
    }
    
    //坐标点适配器
    function echartDataAdapter(res) {
      return res.map(item => item.uv);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    创建两个函数分别对数据按照echarts所需要的数据格式进行格式化处理即可解决问题;这两个方法其实就是一个适配器,把指定的数据丢进去即可按照指定规则输出我们期待得到的数据格式;

    总结

    个人认为适配器模式其实是一种亡羊补牢式的设计模式,如果在项目开发的开始阶段我们就知道我们期待的数据格式或者方法名等,我们就可能永远都用不到适配器模式;但是项目的迭代往往是不可预期的,当项目迭代之后数据格式或者方法名发生变化之后,我们通常可以使用适配器模式来进行适配解决;当然了,最好的解决办法就是项目开发过程中前后端协商讨论数据格式、文件名等代码规范,这样是对项目的开发效率是会有很大的提升的;

  • 相关阅读:
    2022.8.16 模拟赛
    特刊|离子阱量子计算简史
    【异步VS多线程】异步VS多线程区别
    【OpenStack云平台】网络控制节点 HA 集群配置
    【项目】基于TCP的聊天系统
    物联网硬件设计开发全攻略:十大关键阶段深度解析
    GZ038 物联网应用开发赛题第9套
    【云原生】Kubernetes----Metrics-Server组件与HPA资源
    java-对数据结构的简单认识
    Springboot毕设项目儿童医院问诊导诊系统aqy75(java+VUE+Mybatis+Maven+Mysql)
  • 原文地址:https://blog.csdn.net/weixin_44730897/article/details/125991134