写 GUI 的时候为了维护界面的状态一直用 OOP ,但是开发的很慢,也容易出 Bug ,然后就用状态机来实现,感觉还不错,有这么用的小伙伴吗?
const FSM = function () { this.states = []; this.current = undefined; this.enabled = true; }; FSM.prototype.add = function (name, enter, leave, ...event_foo_pairs) { let state = { __name__: name, enter: enter, leave: leave }; event_foo_pairs.forEach(pairs => state[pairs[0]] = pairs[1]); this.states.push(state); this.states.length === 1 && this.go(name); }; FSM.prototype.go = function (name, ...var_args) { const prev = this.states.filter(i => i.__name__ === this.current) const can_leave = prev.map(i => i.leave()).reduce((p, n) => p && n, true); if (can_leave) { const next = this.states.filter(i => i.__name__ === name); next.length === 0 && console.error('No such next jump: ', name); this.current = name; const ret = next.map(i => i.enter.apply(this, var_args)).reduce((p, n) => p && n, true); return ret; } else { console.warn('Can\'t leave state: ', this.current); console.warn(new Error().stack); return false; } }; FSM.prototype.fire = function (event, ...var_args) { return this.states.filter(i => i.__name__ === this.current && i.hasOwnProperty(event)).map(s => s[event]).map(i => i.apply(this, var_args)); };
1 shunia 2016-03-11 12:36:38 +08:00 把这个问题说的学渣能明白一点,其实就是一个 State 控件(可以支持视图,也可以虚拟的),根据提供的状态进行跳转. 是这个意思吗? |
![]() | 2 yksoft1 2016-03-11 12:44:10 +08:00 Windows 的消息循环里面一般不就是一个有限状态机么 |
3 twl007 2016-03-11 12:49:21 +08:00 OOP 只是编程范式吧 - - 状态机是数学模型吧? 用 OOP 也能实现状态机啊 - - |||| |
4 mko0okmko0 2016-03-11 13:48:22 +08:00 状态机不是基本吗 XD 好吧其实是一个门槛,恭喜你迈过去 |
![]() | 5 murmur 2016-03-11 14:02:23 +08:00 最基本的状态机不就是正则表达式么。。另外维护状态什么,好像新的 redux 就是搞这个的 |
6 jiongxiaobu 2016-03-11 14:55:58 +08:00 react ? |
![]() | 7 bdbai 2016-03-11 18:29:20 +08:00 via iPhone 给楼主的思想点个赞。推荐 React 和 Redux 。 |
![]() | 8 glogo 2016-03-11 19:33:22 +08:00 这个思路不错!不过其实维护对象的状态是不是就是在状态机里转哪..... |
9 quix 2016-03-11 20:26:19 +08:00 当年的 flex 不就是支持 state 么。 但有时候有多种状态, 一大堆 fsm 也不方便 |
11 march1993 OP @mko0okmko0 求高级玩法 |
17 mrsatangel 2016-03-11 23:13:14 +08:00 想当年在单片机上就有 qpc 状态机+emwin GUI 。用状态机表示目录层级没问题,框架一大复杂度急剧增加,维护状态机本身的开销比较大。另外呢 FSM 本身不足以作为一种 paradigm 和 OOP 比较 |
18 mko0okmko0 2016-03-12 01:01:30 +08:00 |
19 noli 2016-03-12 01:21:01 +08:00 JS 不是 GUI 的好工具。模拟 OOP 本身就挺费力的。 看看 OC 或者 C# 你才可以感受到为什么 OOP 在 GUI 领域是特别好的工具。 |
![]() | 20 zhuangzhuang1988 2016-03-12 19:52:50 +08:00 状态机? 可以看这个。。。 https://book.douban.com/subject/6886605/ 在最后有关于状态机 UI 编程。。 代码大概这样 let rec drawingLoop(clr, from) = async { let! move = Async.AwaitEvent(form.MouseMove) #1 if (move.Button &&& MouseButtons.Left) = MouseButtons.Left then drawRectangle(clr, from, (move.X, move.Y)) #2 return! drawingLoop(clr, from) #2 else return (move.X, move.Y) } #3 let waitingLoop() = async { while true do #4 let! down = Async.AwaitEvent(form.MouseDown) let downPos = (down.X, down.Y) if (down.Button &&& MouseButtons.Left) = MouseButtons.Left then let! upPos = drawingLoop(Color.IndianRed, downPos) #5 do printfn "Drawn rectanlge (%A, %A)" downPos upPos } #A Wait for the next mouse action #2 Refresh rectangle and continue in the 'Drawing' state #3 Return end location to the 'Waiting' state #4 Repeat after drawing finishes #5 Transition to the 'Drawing' state |
22 march1993 OP @zhuangzhuang1988 666666 |