1. 当一个对象的内部状态发生改变时,会导致其行为的改变;

  2. 适用场景:

    • 一个对象,存在多个状态,状态可以相互转换;
    • 不同状态下,行为不同,用来减少 if…else 子句;
  3. 优点:

    • 可以将 不同的状态 隔离,每个状态都是一个 单独的类
    • 可以将 各种状态转换逻辑,分布到 状态 的子类中,减少相互依赖;
    • 增加 新状态,操作简单;
  4. 缺点:

    • 如果 状态数量 比较多,状态类的数量会增加,业务场景系统变得很复杂; 如果业务中某个对象由几十上百个状态,就会很复杂,这时就需要对状态进行拆分处理;

类图

bad

class Battery {
    constructor() {
        this.amount = 'high'; // 电量很高
    }
    show() {
        if (this.amount == 'high') {
            console.log('绿色');
            this.amount = 'middle';
        } else if (this.amount == 'middle') {
            console.log('黄色');
            this.amount = 'low';
        } else {
            console.log('红色');
        }
    }
}
let battery = new Battery();
battery.show();
battery.show();
battery.show();
/*
问题:
- show 违反开放-封闭原则
- show 方法逻辑太多太复杂
- 颜色状态切换不明显
- 过多的 if/else 让代码不可维护
*/

good

class Battery {
    constructor(state) {
        this.amount = 'high'; // 电量很高
        this.state = new SuccessState();
    }
    show() {
        this.state.show();
        if (this.amount == 'high') {
            this.amount = 'middle';
            this.setState(new WarningState());
        } else if (this.amount == 'middle') {
            this.amount = 'low';
            this.setState(new DangerState());
        }
    }
    setState(state) {
        this.state = state;
    }
}
class SuccessState {
    constructor(battery) {
        this.battery = battery;
    }
    show() {
        console.log(`绿色 ${battery.amount}`);

    }
}
class WarningState {
    constructor(battery) {
        this.battery = battery;
    }
    show() {
        console.log(`黄色 ${battery.amount}`);
    }
}
class DangerState {
    constructor(battery) {
        this.battery = battery;
    }
    show() {
        console.log(`红色 ${battery.amount}`);
    }
}

let battery = new Battery();
battery.show();
battery.show();
battery.show();

经典场景

点赞

let likeState = {
    render(element) {
        element.innerHTML = '赞👍';
    }
}
let likedState = {
    render(element) {
        element.innerHTML = '取消';
    }
}

class Button {
    constructor(container) {
        this.liked = false;
        this.state = likeState; // 初始状态
        this.element = document.createElement('button');
        container.appendChild(this.element);
        this.render();
    }
    setState(state) {
        this.state = state;
        this.render();
    }
    render() {
        this.state.render(this.element);
    }
}

// 测试
let button = new Button(document.body);
button.element.addEventListener('click', () => {
    button.setState(button.liked ? likeState : likedState);
    button.liked = !button.liked;
});

promise

class Promise {
    constructor(fn) {
        this.state = 'initial'; // 初始状态
        this.successes = [];
        this.fails = [];
        let resolve = (data) => {
            this.state = 'fulfilled';
            this.successes.forEach(item => item(data));
        }
        let reject = (error) => {
            this.state = 'failed';
            this.fails.forEach(item => item(error));
        }
        fn(resolve, reject);
    }
    then(success, fail) {
        this.successes.push(success);
        this.fails.push(fail);
    }
}

let p = new Promise(function (resolve, reject) {
    setTimeout(function () {
        resolve(1);
    }, 1000);
});
p.then((data) => console.log('成功'), error => console.error('失败'));

有限状态机

  1. 什么是有限状态机?

    • 事物拥有多种状态,任一时间只会处于一种状态不会处于多种状态;
    • 动作可以改变事物状态,一个动作可以通过条件判断,改变事物到不同的状态,但是不能同时指向多个状态,一个时间,就一个状态;
    • 状态总数是有限的;
  2. javascript-state-machine

    • form:当前行为从哪个状态来;
    • to:当前行为执行完会过渡到哪个状态;
    • name:当前行为的名字;
// var StateMachine = require('javascript-state-machine'); // 有限状态机

class StateMachine {
    constructor(options) {
        let { initState, transitions, methods } = options;
        this.state = initState;

        transitions.forEach(transition => {
            let { from, to, name } = transition;

            this[name] = function () {
                if (this.state == from) {
                    this.state = to;
                    let onMethod = 'on' + name.slice(0, 1).toUpperCase() + name.slice(1);
                    methods[onMethod] && methods[onMethod]();
                }
            }
        });
    }
}

var fsm = new StateMachine({
    initState: 'solid', // 初始状态
    transitions: [
    {
        name: 'melt',
        from: 'solid',
        to: 'liquid'
    },
    {
        name: 'freeze',
        from: 'liquid',
        to: 'solid'
    },
    {
        name: 'vaporize',
        from: 'liquid',
        to: 'gas'
    },
    {
        name: 'condense',
        from: 'gas',
        to: 'liquid'
    }
    ],
    methods: {
        // 融化
        onMelt: function () {
            console.log('I melted')
        },
        // 冷冻
        onFreeze: function () {
            console.log('I froze')
        },
        // 蒸发
        onVaporize: function () {
            console.log('I vaporized')
        },
        // 凝结
        onCondense: function () {
            console.log('I condensed')
        }
    }
});
fsm.melt();
fsm.vaporize();
打赏作者
您的打赏是我前进的动力
微信
支付宝
评论

中午好👏🏻,我是 ✍🏻   疯狂 codding 中...

粽子

这有关于前端开发的技术文档和你分享。

相信你可以在这里找到对你有用的知识和教程。

了解更多

目录

  1. 1. 类图
  2. 2. bad
  3. 3. good
  4. 4. 经典场景
    1. 4.1. 点赞
    2. 4.2. promise
    3. 4.3. 有限状态机