JavaScript设计模式(九)状态模式 适配器模式

一、状态模式

允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类

1.基本实现

//下面以一个开灯程序演示状态模式
//灯共用三种状态,分别是‘关闭’,‘弱光‘和’强光‘。每次按下开关按钮都会换挡。
let OfflightState = function (light) {
    this.light = light;
}
OfflightState.prototype.buttonPressed = function () {
    console.light('弱光');
    this.light.setState(this.light.weakLightState);
}

let WeakLightState = function (light) {
    this.light = light;
}
WeakLightState.prototype.buttonPressed = function () {
    console.log('强光')
    this.light.setState(this.light.strongLightState);
}

let StrongLightState = function (light) {
    this.light = light;
}
StrongLightState.prototype.buttonPressed = function () {
    console.log('关闭');
    this.light.setState(this.light.offlightState)
}

let Light = function () {
    this.offlightState = new OfflightState(this); 
    this.weakLightState = new WeakLightState(this);
    this.strongLightState = new StrongLightState(this);
    this.button = null;
}
Light.prototype.init = function () { 
    let button = document.createElement('button');
    self = this;
    this.button = document.body.appendChild(button);
    this.button.innerHTML = '开关';
    this.button.currState = this.offlightState;
    this.button.onclick = function () { 
        self.currState.buttonPressed;
    }
}
Light.prototype.setState = function (newState) {
    this.currState = newState;
}

let light = new Light();
light.init();

以上代码实现了一个基本的状态模式,状态的切换规律事先被定义好在各个状态类中,主体上无需关心切换的细节。如果日后又新增了一个状态,那我们只要编写好新的状态类,加入到原有代码中就可以了。

2.状态模式的优缺点

(1)状态模式定义了状态与行为之间的关系,并将它们封装在一个类里。通过增加新的状态类,很容易增加新的状态和转换
(2)避免Context无限膨胀,状态切换的逻辑被分布在状态类中,也去掉了Context中原本过多的分支。
(3)用对象代替字符串来记录当前状态,使得状态的切换更加一目了然。
(4)Context中的请求动作和状态类中封装的行为可以非常容易地独立变化而互不影响。

3.状态模式中的性能优化点

(1)状态可以等待需要的时候再创建,也可以一开始就创建好,具体依据实际场景、
(2)state对象可以在多个类之间共享。

二、适配器模式

解决两个软件实体间接口不兼容问题

1.适配器模式的应用

let googleMap = {
    show: function () {
        console.log('开始渲染谷歌地图');
    }
}

let baiduMap = {
    show: function () {
        console.log('开始渲染百度地图');
    }

}

let renderMap = function (map) {
    map.show();
}

/**
 * 以上代码段实现了渲染不同地图的功能。现在假设BaiduMap的api改成了display,修改源代码势必不太符合开闭原则,这时候我们可以通过新建一个适配器来达到目的
 */

let baiduMapAdapter = {
    show: function () {
        return baiduMap.display();
    }
}

renderMap(baiduMapAdapter);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

volit_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值