了解OTP基本设计原则需看看官方文档:http://www.erlang.org/doc/design_principles/
如gen_fsm的经典例子code lock door:-module(code_lock).
-behaviour(gen_fsm). -export([start_link/1]). -export([button/1]). -export([init/1, locked/2, open/2]). start_link(Code) -> gen_fsm:start_link({local, code_lock}, code_lock, Code, []). button(Digit) -> gen_fsm:send_event(code_lock, {button, Digit}). init(Code) -> {ok, locked, {[], Code}}. locked({button, Digit}, {SoFar, Code}) -> case [Digit|SoFar] of Code -> do_unlock(), {next_state, open, {[], Code}, 3000}; Incomplete when length(Incomplete)<length(Code) -> {next_state, locked, {Incomplete, Code}}; _Wrong -> {next_state, locked, {[], Code}} end. open(timeout, State) -> do_lock(), {next_state, locked, State}.
看到了这个gen_fsm,我想起了古老的SDL语言,其实erlang的gen_fsm形式与SDL非常相似,唯一不同的是gen_fsm中state的跳转可以带有state date,这个在SDL语言中则不可以(只能使用全局变量保存状态数据)。
真没想到古老SDL语言引以为傲的STATE跳转描述就这样被erlang的gen_fsm轻而易举的实现了。
再看看C或C++中的普遍fsm实现,C/C++的fsm实现通常基于fsm的全局数组,数组里定义了每种state和event的组合关系,以及相应的跳转函数,很明显你需要定义每种state和event的enum枚举定义,而且通常状态定义和跳转函数分离导致可读性和维护性不是太好,相比之下,erlang的gen_fsm实现很好的规避了这些问题,state用atom和fun表示了,event也是atom,在state下收到event然后执行动作都一目了然。
再说说Java中比较普遍的fsm实现,Java是OO语言,所有的都是对象Object,fsm中的state和event也是对象,这就意味着你需要为每个state和event写个class类,代码量比C/C++多得多,更无法与简洁的erlang gen_fsm相比。
就说到这里,Have fun!