专栏首页技术/开源TypeScript设计模式之门面、适配器

TypeScript设计模式之门面、适配器

看看用TypeScript怎样实现常见的设计模式,顺便复习一下。 学模式最重要的不是记UML,而是知道什么模式可以解决什么样的问题,在做项目时碰到问题可以想到用哪个模式可以解决,UML忘了可以查,思想记住就好。 这里尽量用原创的,实际中能碰到的例子来说明模式的特点和用处。

适配器模式 Adapter

特点:把类或接口转换成另一个接口以便系统调用。

用处:当系统需要引入多个功能类并且这些功能的接口不统一时可以考虑用适配器模式把它们转成统一的接口,现实中的例子很多,比如充电器接口适配器。

注意:分为对象适配器和类适配器。

适配器模式的目的主要在于解决接口兼容性。

下面用TypeScript简单实现一下适配器模式: 假定现在项目已经在用一个画图接口Graph以及它的实现Canvas2D:

interface Graph{
    drawLine();

    drawPie();
}

class Canvas2D implements Graph{
    drawLine(){
        console.log('draw 2d line');
    }

    drawPie(){
        console.log('draw 2d pie');
    }
}

项目升级需要提高UI美观,引入3D画图库Canvas3D,两者接口不一样:

class Canvas3D{
    draw3DLine(){
        console.log('draw 3d line');
    }

    draw3DPie(){
        console.log('draw 3d pie');
    }
}

项目是依赖接口Graph的,如果要直接加上3d功能就需要改接口,这个代价比较大,这时适配器派上用场:

class Canvas3DAdapter implements Graph{
    private canvas3D: Canvas3D = new Canvas3D();

    drawLine(){
        this.canvas3D.draw3DLine();
    }

    drawPie(){
        this.canvas3D.draw3DPie();
    }
}

let canvas2D: Graph = new Canvas2D();
canvas2D.drawLine();
canvas2D.drawPie();

let canvas3D: Graph = new Canvas3DAdapter();
canvas3D.drawLine();
canvas3D.drawPie();

//输出
draw 2d line
draw 2d pie

draw 3d line
draw 3d pie

这样,使用时用Canvas3DAdapter就可以了,项目还是只依赖Graph这个接口就可以画出3D图。 在Canvas3DAdapter里引入了Canvas3D对象,可以看出这是对象上的行为适配,所以叫对象适配器。 另外还有一种叫类适配器,使用多重继承来使新的适配类继承原来接口并且拥有两个类的功能,在TypeScript里虽然不能用多重继承,但是可以用mixins方式强行加起来,这里就不写例子了。

外观模式 Facade

特点:给子系统定义一个统一的接口来方便外面调用,并且可以减少对子系统的直接依赖。

用处:当系统实现一个功能需要调用其他库或第三方库的很多功能时,需要有个统一调用维护的地方,这时可以考虑外观模式。

注意:和适配器的区别。

外观模式的目的主要在于简化调用,只需要一个简单的接口就可以解除对其他类的依赖。

下面用TypeScript简单实现一下外观模式: 假定现在项目的需求是实现一个简单图表的功能来画出近年来收入曲线图和收入来源配比图,引入一个第三方绘图库。

//第三方绘图库
class Axis{
    draw(); // 画坐标轴
}

class Line{
    draw(); // 画曲线
}

class FanShape{
    draw(angle: number); // 画扇形
}

项目没必要和第三方的库紧耦合,所以按需求抽象出一个接口Graph:

// 项目接口
interface Graph{ // 只需要两种图表, 线图和饼图
    drawLineChart();

    drawPieChart();
}

再用第三方库里的画图功能实现这个接口:

class Chart implements Graph{ // 实现接口
    drawLineChart(){
        new Axis().draw();
        new Line().draw();
    }

    drawPieChart(){
        new FanShape().draw(90);
        new FanShape().draw(180);
        new FanShape().draw(90);
    }
}

这样项目只需要通过Graph接口来画图表就好了,而不用知道具体的细节。

与适配器相同的点是同样是一种封装处理,不同的是适配器已有一个接口,而用这个接口不能使用另外一个系统,这时需要把那个系统做个适配来匹配现有接口,重点在于兼容接口,解决冲突。 而外观则是封装现有系统来对外提供一种简单的使用方式,重点在于简化调用。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • TypeScript设计模式之组合、享元

    看看用TypeScript怎样实现常见的设计模式,顺便复习一下。 学模式最重要的不是记UML,而是知道什么模式可以解决什么样的问题,在做项目时碰到问题可以想到...

    用户1147588
  • 从C#到TypeScript - Generator

    从C#到TypeScript - Generator 上篇讲了Promise,Promise的执行需要不停的调用then,虽然比callback要好些,但也显得...

    用户1147588
  • 从C#到TypeScript - async await

    从C#到TypeScript - async await 上两篇分别说了Promise和Generator,基础已经打好,现在可以开始讲async await了...

    用户1147588
  • zookeeper源码分析(6)-数据和存储

    在Zookeeper中,数据存储分为两部分:内存数据存储和磁盘数据存储。本文主要分析服务器启动时内存数据库的初始化过程和主从服务器数据同步的过程。在此之前介绍一...

    Monica2333
  • ThreeJS 立方体贴图

    在上一篇《ThreeJS 掏洞术》中,利用ThreeBSP完成了在‘墙’上掏出‘门’或‘窗户’洞的效果。但那个所谓的‘墙’一点也不像,试想谁家的墙是绿色的呀,而...

    Melody132
  • Retrofit解析7之相关类解析

    上篇文章讲解了Call接口、CallAdapter接口、Callback接口、Converter接口、Platform类、ExecutorCallAdapter...

    隔壁老李头
  • iOS基于GPUImage的图像形变设计(复杂形变部分)

    在上一部分,我们介绍了两种简单形变的GPUImage实现方式,包括自定义FragmentShader,和自定义顶点数组。这一部分,我们将介绍更为复杂的一些图像形...

    天天P图攻城狮
  • QT charts 动态刷新曲线图

    用vs+QT开发应用程序时,当需要显示图表时,使用QtCharts是不错的选择。QtCharts是Qt提供的图表模块,在Qt5.7以前只有商业...

    zls365
  • 敏捷团队工作流

    站会中的内容是每天工作的开始,也是对昨天工作的回顾。一般会由团队的某位成员主持,这位主持人有责任让电子系统上的story卡片和看板上的保持一致。站会上,大家依看...

    lambeta
  • 新闻动态|AI抗“疫”,腾讯优图一直在行动

    全国疫情实时数据显示,截至2月11日13时,累计确诊新冠肺炎42714例,疑似病例21675例,死亡1017例,治愈4023例。从目前情况来看,新型冠状病毒肺炎...

    优图实验室

扫码关注云+社区

领取腾讯云代金券