当前位置: 首页 > news >正文

一天一个设计模式之JS实现——适配器模式

本文参考于:
设计模式课程
设计模式之适配器模式

设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。项目中合理地运用设计模式可以完美地解决很多问题,每种模式在现实中都有相应的原理来与之对应,每种模式都描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是设计模式能被广泛应用的原因。

设计模式如此强大,从今天开始,抓住大学生活的尾巴,我要一天学习一个设计模式啦。

第一个设计模式是:适配器模式

使用场景:
1 系统需要使用现有的类,而这些类的接口不符合系统的需要。
2 想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。
3 需要一个统一的输出接口,而输入端的类型不可预知。
比如插座-充电器-电子设备的例子。插座输出的是220V的电压,而电子设备充电时只需5V,不然就note7了,这时充电器充当适配器,接受插座的220V,输出5V,从而作为连接器让电子设备顺利充电。
总的来说适配器就是src-adapter-dist的模式,与修饰模式直接无感使用src不同,适配器模式使用对象变为adapter。
适配器模式不是在系统设计时所预期的,是在需求改动、升级的时候动态添加的,如果一个系统使用过多的适配器,明明调用的是A接口,却在适配器内部实现的是调用B接口,导致系统混乱。

适配器模式分为三种:
一、类适配器模式;二、对象适配器模式;三、接口适配器模式(JS没有抽象类的概念,这里不详细讲述)

接下来举的例子就是上面插座-充电器-电子设备的例子。

类适配器

继承src,实现dist的接口。
先是插座

function Plug() {
    this.V = 220;
}
Plug.prototype.outputVoltage220 = function() {
    return this.V;
};

再是手机

function Phone() {
    this.V = 5;
}
Phone.prototype.charge = function(outputDevice) {
    if (outputDevice.outputVoltage5() === this.V) {
        console.log('充电中...');
    } else {
        console.log('充电异常');
    }
};

现在我们要实现的是outputVoltage5的接口,以对接手机的输入电压

function inherit(Sub, Sup) {
    Sub.prototype = Object.create(Sup.prototype);
    Object.defineProperty(Sub.prototype, 'constructor', {
        enumerable: false,
        value: Sub
    });
}

function Charger() {
    Plug.call(this);
}
inherit(Charger, Plug);
Charger.prototype.outputVoltage5 = function() {
    return this.outputVoltage220() / 44;
};

这样充电器就实现了连接插座和手机的功能。

var cg = new Charger();
var mobile = new Phone();
mobile.charge(cg);

小结:类适配器使用继承的方式实现,会暴露src的所有其他方法。

对象适配器

对象适配器和类适配器相差不大,使用组合的方式实现。
持有src,实现dist接口,完成src->dist的适配

function Charger2() {
    this.plug = null;
}
Charger2.prototype.initPlug = function(plug) {
    return this.plug = plug;
};
Charger2.prototype.outputVoltage5 = function() {
    if (!this.plug) {
        console.error('未插电');
        return -1;
    }
    return this.plug.outputVoltage220() / 44;
};

同样也能正常充电

var plug = new Plug();
var cg2 = new Charger2();
cg2.initPlug(plug);
mobile.charge(cg2);

小结:根据合成复用原则,组合优于继承,所以结构型模式一般都是对象结构型模式。

以上表述有什么问题,欢迎大家指出,一起学习。

相关文章:

  • QT之坐标系统(四)
  • 去中心化类微博应用 mastodon
  • mvn命令
  • 安全感
  • DCN(Deep Cross Network)模型在手淘分类地图CTR预估上的应用
  • 第一周第一天任务
  • js压缩图片的方法(手机端,兼容ios和android),返回值为base64的字符串,压缩率ratio可自定义...
  • DirectFB、Layer、Window、Surface之间关系
  • 复杂recyclerView封装库
  • js文件、图片上传(原生方法和jquery的ajax两种都有)
  • 浮点数网络传输
  • 第199天:js---扩充内置对象功能总结
  • 1.6-1.7 centos7-配置ip
  • Maven学习笔记四(坐标和依赖)
  • java 泛型中classT 和T的区别是什么?
  • “寒冬”下的金三银四跳槽季来了,帮你客观分析一下局面
  • 4个实用的微服务测试策略
  • CEF与代理
  • css选择器
  • echarts的各种常用效果展示
  • iOS高仿微信项目、阴影圆角渐变色效果、卡片动画、波浪动画、路由框架等源码...
  • SpringCloud集成分布式事务LCN (一)
  • 案例分享〡三拾众筹持续交付开发流程支撑创新业务
  • 极限编程 (Extreme Programming) - 发布计划 (Release Planning)
  • 前端每日实战:70# 视频演示如何用纯 CSS 创作一只徘徊的果冻怪兽
  • 小程序测试方案初探
  • mysql 慢查询分析工具:pt-query-digest 在mac 上的安装使用 ...
  • ​TypeScript都不会用,也敢说会前端?
  • # 20155222 2016-2017-2 《Java程序设计》第5周学习总结
  • #pragma预处理命令
  • $Django python中使用redis, django中使用(封装了),redis开启事务(管道)
  • (1)虚拟机的安装与使用,linux系统安装
  • (7)STL算法之交换赋值
  • (delphi11最新学习资料) Object Pascal 学习笔记---第2章第五节(日期和时间)
  • (Oracle)SQL优化技巧(一):分页查询
  • (九十四)函数和二维数组
  • (算法)前K大的和
  • .gitignore文件设置了忽略但不生效
  • .libPaths()设置包加载目录
  • .Net+SQL Server企业应用性能优化笔记4——精确查找瓶颈
  • .NET开发人员必知的八个网站
  • .php结尾的域名,【php】php正则截取url中域名后的内容
  • .vollhavhelp-V-XXXXXXXX勒索病毒的最新威胁:如何恢复您的数据?
  • @Data注解的作用
  • @JsonSerialize注解的使用
  • [04]Web前端进阶—JS伪数组
  • [ABP实战开源项目]---ABP实时服务-通知系统.发布模式
  • [ACM] hdu 1201 18岁生日
  • [acwing周赛复盘] 第 94 场周赛20230311
  • [Android Pro] android 混淆文件project.properties和proguard-project.txt
  • [bzoj1038][ZJOI2008]瞭望塔
  • [BZOJ3757] 苹果树
  • [DM复习]关联规则挖掘(下)
  • [HITCON 2017]SSRFme perl语言的 GET open file 造成rce
  • [I2C]I2C通信协议详解(二) --- I2C时序及规格指引