Javascript 设计模式系统讲解与应用——学习笔记10-状态模式

状态模式

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

示例
交通红绿灯

传统UML类图
在这里插入图片描述

JS版简单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
  }
}

// test
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()) // 打印状态
// 红灯亮了
red.handle(context)
console.log(context.getState()) // 打印状态
// 黄灯亮了
yellow.handle(context)
console.log(context.getState()) // 打印状态

输出:
turn to green light
State {
    
     color: 'green' }
turn to red light
State {
    
     color: 'red' }
turn to yellow light
State {
    
     color: 'yellow' }

场景

  • 有限状态机
  • 写一个简单的Promise
有限状态机

// 状态机模型
const fsm = new StateMachine({
    
    
  init: '收藏'// 初始状态,待收藏
  transitions: [
    {
    
    
      name: 'doState',
      from: '收藏',
      to: '取消收藏'
    },
    {
    
    
      name: 'deleteStore',
      from: '取消收藏',
      to: '收藏'
    }
  ],
  methods: {
    
    
    // 监听执行收藏
    onDoStore: function() {
    
    
      alert('收藏成功')  // 可以放post请求
      updateText()
    },
    // 监听取消收藏
    onDeleteStore: function() {
    
    
      alert('已取消收藏')  // 可以放post请求
      updateText()
    }
  }
})

const $btn = ${
    
    '#btn'}

// 点击事件
$btn.click(function () {
    
    
  if (fsm.is('收藏')) {
    
    
    fsm.doStore()
  } else {
    
    
    fsm.deleteStore()
  }
})

// 更新文案
funciton updateText() {
    
    
  $btn.text(fsm.state)
}

// 初始化文案
updateText()
写一个简单的Promise

Promise就是有限状态机

  • Promise三种状态: pending fullfilled rejected
  • pending -> fullfilled 或者 pending -> rejected
  • 不能逆向变化
// 模型
const 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)
  }
}

// test
function loadImg(src) {
    
    
  const promise = new MyPromise(function(resolve, reject) {
    
    
    let img = document.createElement('img')
    img.onload = function () {
    
    
      resolve(img)
    }
    img.onerror = function () {
    
    
      reject()
    }
    img.src = src
  })
  return promise
}

let src = "xxx.png"
let result = loadImg(src)
result.then(function () {
    
    
  console.log('ok1')
}, function () {
    
    
  console.log('fail1')
})

result.then(function () {
    
    
  console.log('ok2')
}, function () {
    
    
  console.log('fail2')
})

设计原则验证

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

猜你喜欢

转载自blog.csdn.net/weixin_40693643/article/details/108876719