科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道为Linux应用构造有限状态机方法(下) (3)

为Linux应用构造有限状态机方法(下) (3)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

为实用的软件系统编写状态机并不是一件十分轻松的事情,特别是当状态机本身比较复杂的时候尤其如此,许多有过类似经历的程序员往往将其形容为"毫无创意"的过程,因为他们需要将大量的时间与精力倾注在如何管理好状态机中的各种状态上,而不是程序本身的运行逻辑。

作者:shenhuo 来源:赛迪网技术社区 2007年10月20日

关键字: Linux 方法 状态机 操作系统

  • 评论
  • 分享微博
  • 分享邮件
 

3.3 定制状态机

目前得到的状态机已经能够响应来自外部的各种事件,并适当地调整自己当前所处的状态,也就是说已经实现了状态机引擎的功能,接下来要做的就是根据应用的具体需求来进行定制,为状态机加入与软件系统本身相关的那些处理逻辑。在FSME中,与具体应用相关的操作称为输出(Output),它们实际上就是一些需要用户给出具体实现的虚函数,自动生成的状态机引擎负责在进入或者退出某个状态时调用它们。

仍然以控制城门的那个状态机为例,假设我们希望在进入每个状态时都添加一部分处理逻辑。首在FSME界面左边的树形列表选择"Outputs"项,然后按下键盘上的Insert键来添加一个新的输出,接着在右下方的"Name"文本框中输入相应的名称,再单击"Apply"按钮,一个新的输出就创建好了,如图7所示。用同样的办法可以添加状态机所需要的所有输出。

图7 添加输出

当所有的输出都定义好之后,接下来就可以为状态机中的每个状态绑定相应的输出。首先在FSME界面左侧的"States"项中选择相应的状态,然后从右下角的"Available"列表框中选择与该状态对应的输出,再单击"<"按钮将其添加到"In"列表中。用同样的办法可以为状态机中的所有状态设置相应的输出,同一个状态可以对应有多个输出,其中In列表中的输出会在进入该状态时被调用,而Out列表中的输出则会在退出该状态时被调用,输出调用的顺序是与其在In或者Out列表中的顺序相一致的。

由于对状态机模型进行了修改,我们需要再次生成状态机的框架代码,不过这次不需要加上-d参数:

  
  [xiaowp@linuxgam" code]$ fsmc door.fsm -o DoorFSM.h
  [xiaowp@linuxgam code]$ fsmc door.fsm -d -impl DoorFSM.h -o DoorFSM.cpp
  

我们在新的状态机模型中添加了enterOpend、enterClosed、enterLocked和enterUnlocked四个输出,因此生成的类DoorFSM中会包含如下几个纯虚函数

  
     virtual void enterOpened() = 0;
    virtual void enterLocked() = 0;
    virtual void enterUnlocked() = 0;
    virtual void enterClosed() = 0;

显然,此时生成的状态机框架不能够再被直接编译了,我们必须从类DoorFSM派生出一个子类,并提供对这几个纯虚函数的具体实现:

  /* 
   * DoorFSMLogic.h
   * 状态机控制逻辑的头文件
   */
  #include "DoorFSM.h"
  
  class DoorFSMLogic : public DoorFSM 
  {
   
   protected:
   virtual void enterOpened(); 
   virtual void enterLocked(); 
   virtual void enterUnlocked(); 
   virtual void enterClosed(); 
  };
  

正如前面所提到过的,这几个函数实际上代表的正是应用系统的处理逻辑,作为例子我们只是简单地输出一些提示信息:

  /* 
   * DoorFSMLogic.cpp
   * 状态机控制逻辑的实现文件
   */
  #include "DoorFSMLogic.h"
  #include 
  
  void DoorFSMLogic::enterOpened()
  {
    std::cout << "Enter Opened state." << std::endl;
  }
  
  void DoorFSMLogic::enterClosed()
  {
    std::cout << "Enter Closed state." << std::endl;
  }
  
  void DoorFSMLogic::enterLocked()
  {
    std::cout << "Enter Locked state." << std::endl;
  }
  
  void DoorFSMLogic::enterUnlocked()
  {
    std::cout << "Enter Unlocked state." << std::endl;
  }

同样,为了对生成的状态机进行验证,我们还需要手工编写一段测试代码:

  /* 
   * TestFSM.cpp
   * 测试状态机逻辑
   */
  #include "DoorFSMLogic.h"
  
  int main() 
  {
   DoorFSMLogic door;
   door.A(DoorFSM::Close);
   door.A(DoorFSM::Lock);
   door.A(DoorFSM::Unlock);
   door.A(DoorFSM::Open);
  }
  

使用下面的命令能够将生成的状态机框架和测试代码编译成一个可执行文件:

  [xiaowp@linuxgam code]$ g++ DoorFSM.cpp DoorFSMLogic.cpp TestLogic.cpp -o logic
  

运行结果如下所示:

  [xiaowp@linuxgam code]$ ./logic
  Enter Closed state.
  Enter Locked state.
  Enter Unlocked state.
  Enter Opened state.
  

四、小结

在面向对象的软件系统中,有些对象具有非常复杂的生命周期模型,使用有限状态机是描述这类对象最好的方法。作为一种软件设计模式,有限状态机的概念虽然不算复杂,实现起来也并不困难,但它的问题是当状态机的模型复杂到一定的程度之后,会带来实现和维护上的困难。Linux下的FSME是一个可视化的有限状态机建模工具,而且支持状态机框架代码的自动生成,借助它可以更加轻松地构建基于有限状态机的应用系统。

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章