• 前端设计模式 状态模式


    状态模式:一个对象有状态变化,每次状态变化都会触发一个逻辑,不能总是用if...else来控制
    比如红绿灯
    uml类图

    代码
    // 状态(红灯,绿灯 黄灯)
    class State {
        constructor(color) {
            this.color = color;
        }
        // 设置状态
        handle(context) {
            console.log(`turn to ${this.color} light`);
            context.setState(this)
        }
    }
    
    // 主体
    class Context {
        constructor() {
            this.state = null;
        }
        // 获取状态
        getState() {
            return this.state;
        }
        setState(state) {
            this.state = state;
        }
    }
    
    // 测试
    let context = new Context();
    let green = new State('green');
    let yellow = new State('yellow');
    let red = new State('red');
    
    // 绿灯亮了
    green.handle(context);
    console.log(context.getState())
    
    // 黄灯亮了
    yellow.handle(context);
    console.log(context.getState())
    
    // 红灯亮了
    red.handle(context);
    console.log(context.getState())



    场景1:有限状态机
    有限的状态、以及在这些状态之间的变化。如交通信号灯
    使用开源lib: javascript-state-machine
    https://github.com/jakesgordon/javascript-state-machine
    // 状态机模型
    var fsm = new StateMachine({
        init: '收藏', // 初始状态,待收藏
        transitions: [{
            name: 'doStore',
            from: '收藏',
            to: '取消收藏'
        },{
            name: 'deleteStore',
            from: '取消收藏',
            to: '收藏'
        }],
        methods: {
            // 执行收藏
            onDoStore: function() {
                alert('收藏成功');
                updateText();
            },
            // 取消收藏
            onDeleteStore: function() {
                alert('已取消收藏');
                updateText();
            }
        }
    })
    
    var $btn = $('#btn');
    // 点击事件
    $btn.click(function() {
        if (fsm.is('收藏')) {
            fsm.doStore()
        } else {
            fsm.deleteStore()
        }
    })
    // 更新文案
    function updateText() {
        $btn.text(fsm.state);
    }
    // 初始化文案
    updateText();



    场景2:写一个简单的Promise
    Promis是个有限状态机,三种状态,pending fullfilled rejected。
    状态变化可以由 pending -> fullfilled 或者 pending -> rejected
    不能逆向变化
    import StateMachine from 'javascript-state-machine';
    
    // 状态机模型
    var fsm = new StateMachine({
        init: 'pending', // 初始化状态
        transitions:[{
            name: 'resolve',
            from: 'pending',
            to: 'fullfilled'
        }, {
            name: 'reject',
            from: 'pending',
            to: 'rejected'
        }],
        method: {
            // 成功
            onResolve: function(state, data) {
                // 参数:state - 当前状态实例; data - fsm.resove(xxx) 执行时传递过来的参数
                data.successList.forEach(fn=>fn());
            },
            // 失败
            onReject: function(state, data) {
                // 参数:state - 当前状态实例; data - fsm.reject(xxx) 执行时传递过来的参数
                data.failList.forEach(fn => fn());
            }
        }
    })
    
    // 定义 Promise
    class MyPromise {
        constructor(fn) {
            this.successList = [];
            this.failList = [];
            
            // promise传入的是一个函数,两个参数,一个resolve,一个reject
            fn(() => {
                // resove 函数
                fsm.resolve(this); // 触发状态机模型方法,传递当前这个promise对象
            }, () => {
                // reject 函数
                fsm.reject(this);
            })
        }
        // promise实现一个.then的方法
        then(successFn, failFn) {
            this.successList.push(successFn);
            this.failList.push(failFn);
        }
    }
    
    
    // 测试
    function loadImg(src){
        const promise = new MyPromise((resolve, reject)=>{
            let img = document.createElement('img');
            img.onload = function() {
                resolve(img);
            }
            img.onerror = function(err) {
                reject(err)
            }
            img.src = src
        })
        return promise;
    }
    
    let src = 'https://www.baidu.com/img/bd_logo1.png'
    let result = loadImg(src);
    result.then(res => {
        console.log('ok1');
    }, err => {
        console.log('fail1');
    })
    设计原则验证
    将状态对象和主体对象分离,状态的变化逻辑单独处理
    符合开放封闭原则
  • 相关阅读:
    forward和redirect的区别
    转 jsp中 session的简单用法
    20_学生选课数据库SQL语句练习题1
    _学生选课数据库SQL语句练习题
    输入输出2
    接口提
    输入输出流3
    获取当前时间并显示在网页上
    简单的权限管理
    java关于时间
  • 原文地址:https://www.cnblogs.com/wzndkj/p/11846519.html
Copyright © 2020-2023  润新知