美文网首页
状态模式

状态模式

作者: zxhnext | 来源:发表于2019-09-22 19:02 被阅读0次

    ◆ 一个对象有状态变化
    ◆ 每次状态变化都会触发一个逻辑
    ◆ 不能总是用if..else来控制

    应用场景:
    ◆ 如交通信号灯
    ◆ 收藏,取消
    ◆ Promise

    状态模式符合的设计原则:
    ◆ 将状态对象和主题对象分离,状态的变化逻辑单独处理
    ◆ 符合开放封闭原则

    1. 状态模式demo

    image.png
    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
        }
        setState(state) {
            this.state = state
        }
        getState() {
            return this.state
        }
    }
    
    // 测试代码
    let context = new Context()
    
    let greed = new State('greed')
    let yellow = new State('yellow')
    let red = new State('red')
    
    // 绿灯亮了
    greed.handle(context)
    console.log(context.getState())
    // 黄灯亮了
    yellow.handle(context)
    console.log(context.getState())
    // 红灯亮了
    red.handle(context)
    console.log(context.getState())
    
    
    

    2. javascript-state-machine

    github地址:https://github.com/jakesgordon/javascript-state-machine

    2.1 收藏取消

    // 状态机模型
    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(1)
        } else {
            fsm.deleteStore()
        }
    })
    
    // 更新文案
    function updateText() {
        $btn.text(fsm.state)
    }
    
    // 初始化文案
    updateText()
    

    2.2 promise实现

    // 模型
    var fsm = new StateMachine({
        init: 'pending',
        transitions: [
            {
                name: 'resolve',
                from: 'pending',
                to: 'fullfilled'
            },
            {
                name: 'reject',
                from: 'pending',
                to: 'rejected'
            }
        ],
        methods: {
            // 成功
            onResolve: function (state, data) {
                // 参数:state - 当前状态示例; data - fsm.resolve(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 = []
    
            fn(() => {
                // resolve 函数
                fsm.resolve(this)
            }, () => {
                // reject 函数
                fsm.reject(this)
            })
        }
        then(successFn, failFn) {
            this.successList.push(successFn)
            this.failList.push(failFn)
        }
    }
    
    // 测试代码
    function loadImg(src) {
        const promise = new MyPromise(function (resolve, reject) {
            var img = document.createElement('img')
            img.onload = function () {
                resolve(img)
            }
            img.onerror = function () {
                reject()
            }
            img.src = src
        })
        return promise
    }
    var src = 'http://www.imooc.com/static/img/index/logo_new.png'
    var result = loadImg(src)
    console.log(result)
    
    result.then(function (img) {
        console.log('success 1')
    }, function () {    
        console.log('failed 1')
    })
    result.then(function (img) {
        console.log('success 2')
    }, function () {    
        console.log('failed 2')
    })
    

    相关文章

      网友评论

          本文标题:状态模式

          本文链接:https://www.haomeiwen.com/subject/jmueuctx.html