设计模式之状态机模式

设计模式状态机模式(State Machine Pattern) 状态机模式(State Machine Pattern)是一种用于描述对象的行为软件设计模式,属于行为型设计模式。在状态机模式中,对象的行为取决于其内部状态,并且在不同的状态下,对象可能会有不同的行为。 阅读详情


ZT From :http://www.jdon.com/designpatterns/designpattern_State.htm

State模式的定义: 不同的状态,不同的行为;或者说,每个状态有着相应的行为.

何时使用?
State模式在实际使用中比较多,适合"状态的切换".因为我们经常会使用If elseif else 进行状态切换, 如果针对状态的这样判断切换反复出现,我们就要联想到是否可以采取State模式了.

不只是根据状态,也有根据属性.如果某个对象的属性不同,对象的行为就不一样,这点在数据库系统中出现频率比较高,我们经常会在一个数据表的尾部,加上property属性含义的字段,用以标识记录中一些特殊性质的记录,这种属性的改变(切换)又是随时可能发生的,就有可能要使用State.

是否使用?
在实际使用,类似开关一样的状态切换是很多的,但有时并不是那么明显,取决于你的经验和对系统的理解深度.

这里要阐述的是"开关切换状态" 和" 一般的状态判断"是有一些区别的, " 一般的状态判断"也是有 if..elseif结构,例如:

    if (which==1) state="hello";
    else if (which==2) state="hi";
    else if (which==3) state="bye";

这是一个 " 一般的状态判断",state值的不同是根据which变量来决定的,which和state没有关系.如果改成:

    if (state.euqals("bye")) state="hello";
    else if (state.euqals("hello")) state="hi";
    else if (state.euqals("hi")) state="bye";

这就是 "开关切换状态",是将state的状态从"hello"切换到"hi",再切换到""bye";在切换到"hello",好象一个旋转开关,这种状态改变就可以使用State模式了.

如果单纯有上面一种将"hello"-->"hi"-->"bye"-->"hello"这一个方向切换,也不一定需要使用State模式,因为State模式会建立很多子类,复杂化,但是如果又发生另外一个行为:将上面的切换方向反过来切换,或者需要任意切换,就需要State了.

请看下例:

public class Context{

  private Color state=null;

  public void push(){

    //如果当前red状态 就切换到blue
    if (state==Color.red) state=Color.blue;

    //如果当前blue状态 就切换到green
    else if (state==Color.blue) state=Color.green;

    //如果当前black状态 就切换到red
    else if (state==Color.black) state=Color.red;

    //如果当前green状态 就切换到black
    else if (state==Color.green) state=Color.black;
    
    Sample sample=new Sample(state);
    sample.operate();
  }

  public void pull(){

    //与push状态切换正好相反

    if (state==Color.green) state=Color.blue;
    else if (state==Color.black) state=Color.green;
    else if (state==Color.blue) state=Color.red;
    else if (state==Color.red) state=Color.black;

    Sample2 sample2=new Sample2(state);
    sample2.operate(); 
  }

}

在上例中,我们有两个动作push推和pull拉,这两个开关动作,改变了Context颜色,至此,我们就需要使用State模式优化它.

另外注意:但就上例,state的变化,只是简单的颜色赋值,这个具体行为是很简单的,State适合巨大的具体行为,因此在,就本例,实际使用中也不一定非要使用State模式,这会增加子类的数目,简单的变复杂.

例如: 银行帐户, 经常会在Open 状态和Close状态间转换.

例如: 经典的TcpConnection, Tcp的状态有创建 侦听 关闭三个,并且反复转换,其创建 侦听 关闭的具体行为不是简单一两句就能完成的,适合使用State

例如:信箱POP帐号, 会有四种状态, start HaveUsername Authorized quit,每个状态对应的行为应该是比较大的.适合使用State

例如:在工具箱挑选不同工具,可以看成在不同工具中切换,适合使用State.如 具体绘图程序,用户可以选择不同工具绘制方框 直线 曲线,这种状态切换可以使用State.

如何使用
State需要两种类型实体参与:

1.state manager 状态管理器 ,就是开关 ,如上面例子的Context实际就是一个state manager, 在state manager中有对状态的切换动作.
2.用抽象类或接口实现的父类,,不同状态就是继承这个父类的不同子类.

以上面的Context为例.我们要修改它,建立两个类型的实体.
第一步: 首先建立一个父类:

public abstract class State{

  public abstract void handlepush(Context c);
  public abstract void handlepull(Context c);
  public abstract void getcolor();

}

父类中的方法要对应state manager中的开关行为,在state manager中 本例就是Context中,有两个开关动作push推和pull拉.那么在状态父类中就要有具体处理这两个动作:handlepush() handlepull(); 同时还需要一个获取push或pull结果的方法getcolor()

下面是具体子类的实现:

public class BlueState extends State{

  public void handlepush(Context c){
     //根据push方法"如果是blue状态的切换到green" ;
     c.setState(new GreenState());

  }
  public void handlepull(Context c){

     //根据pull方法"如果是blue状态的切换到red" ;
    c.setState(new RedState());

  }

  public abstract void getcolor(){ return (Color.blue)}

}

同样 其他状态的子类实现如blue一样.

第二步: 要重新改写State manager 也就是本例的Context:

public class Context{

  private Sate state=null; //我们将原来的 Color state 改成了新建的State state;

  //setState是用来改变state的状态 使用setState实现状态的切换
  pulic void setState(State state){

    this.state=state;

  }

  public void push(){

    //状态的切换的细节部分,在本例中是颜色的变化,已经封装在子类的handlepush中实现,这里无需关心
    state.handlepush(this);
    
    //因为sample要使用state中的一个切换结果,使用getColor()
    Sample sample=new Sample(state.getColor());
    sample.operate();

  }

  public void pull(){

    state.handlepull(this);
    
    Sample2 sample2=new Sample2(state.getColor());
    sample2.operate();

  }

}

至此,我们也就实现了State的refactorying过程.

以上只是相当简单的一个实例,在实际应用中,handlepush或handelpull的处理是复杂的.

状态模式优点:
(1) 封装转换过程,也就是转换规则
(2) 枚举可能的状态,因此,需要事先确定状态种类。

状态模式可以允许客户端改变状态的转换行为,而状态机则是能够自动改变状态,状态机是一个比较独立的而且复杂的机制,具体可参考一个状态机开源项目:http://sourceforge.net/projects/smframework/

状态模式在工作流或游戏等各种系统中有大量使用,甚至是这些系统的核心功能设计例如政府OA中,一个批文的状态有多种:未办;正在办理;正在批示;正在审核;已经完成等各种状态,使用状态机可以封装这个状态的变化规则,从而达到扩充状态时,不必涉及到状态的使用者。

在网络游戏中,一个游戏活动存在开始;开玩;正在玩;输赢等各种状态,使用状态模式就可以实现游戏状态的总控,而游戏状态决定了游戏的各个方面,使用状态模式可以对整个游戏架构功能实现起到决定的主导作用。

状态模式实质
使用状态模式前,客户端外界需要介入改变状态,而状态改变的实现是琐碎或复杂的。

使用状态模式后,客户端外界可以直接使用事件Event实现,根本不必关心该事件导致如何状态变化,这些是由状态机等内部实现。

这是一种Event-condition-State,状态模式封装了condition-State部分。

每个状态形成一个子类,每个状态只关心它的下一个可能状态,从而无形中形成了状态转换的规则。如果新的状态加入,只涉及它的前一个状态修改和定义。

状态转换有几个方法实现:一个在每个状态实现next(),指定下一个状态;还有一种方法,设定一个StateOwner,在StateOwner设定stateEnter状态进入和stateExit状态退出行为。

状态从一个方面说明了流程,流程是随时间而改变,状态是截取流程某个时间片。

关 于状态机的一个极度确切的描述是它是一个有向图形,由一组节点和一组相应的转移函数组成。状态机通过响应一系列事件而“运行”。每个事件都在属于“当前” 节点的转移函数的控制范围内,其中函数的范围是节点的一个子集。函数返回“下一个”(也许是同一个)节点。这些节点中至少有一个必须是终态。当到达终态, 状态机停止。 

包含一组状态集(states)、一个起始状态(start state)、一组输入符号集(alphabet)、一个映射输入符号和当前状态到下一状态的转换函数(transition function)的计算模型。当输入符号串,模型随即进入起始状态。它要改变到新的状态,依赖于转换函数。在有限状态机中,会有有许多变量,例如,状态 机有很多与动作(actions)转换(Mealy机)或状态(摩尔机)关联的动作,多重起始状态,基于没有输入符号的转换,或者指定符号和状态(非定有 限状态机)的多个转换,指派给接收状态(识别者)的一个或多个状态,等等。

有 限状态机是一种概念性机器,它能采取某种操作来响应一个外部事件。具体采取的操作不仅能取决于接收到的事件,还能取决于各个事件的相对发生顺序。之所以能 做到这一点,是因为机器能跟踪一个内部状态,它会在收到事件后进行更新。为一个事件而响应的行动不仅取决于事件本身,还取决于机器的内部状态。另外,采取 的行动还会决定并更新机器的状态。这样一来,任何逻辑都可建模成一系列事件/状态组合。

unity 扣扣群

深圳unity3d 电影分享
Java架构-状态机如何实现 先来解释什么是“状态”( State )。现实事物是有不同状态的,例如一个自动门,就有 open 和 closed 两种状态。我们通常所说的状态机是有限状态机,也就是被描述的事物的状态的数量是有限个,例如自动门的状态就是两个 open 和 closed。状态机,也就是 State Machine ,不是指一台实际机器,而是指一个数学模型。说白了,一般就是指一张状态转换图。例如,根据自动门的运行规则,我们可以抽象出下面这么一个图。 阅读详情

相关推荐

状态机(State Machine)设计模式 C语言实现

设计模式是一种行为设计模式,它允许一个对象在其内部状态改变时改变它的行为。状态模式把所与某个特定的状态相关的行为都放入一个对象中,并且将请求委托给当前状态对象来处理。在更复杂的应用中,你可能需要更复杂的逻辑来处理状态转换、事件队列、错误处理等。我们为每个状态定义了一个处理函数,这些函数描述了在该状态下应该执行的操作。如果你正在构建大型或复杂的系统,并希望利用面向对象编程的优势,那么使用支持面向对象编程的语言(如。语言中实现状态机模式需要手动管理状态转换和每个状态下的行为。// 定义每个状态的行为函数。

兰俊 1050

状态设计模式

状态模式状态机的一种实现方式即可。状态机又叫有限状态机,它有3个部分组成:状态、事件、动作。其中,事件也称为转移条件。事件触发状态的转移及动作的执行。不过,动作不是必须的,也可能只转移状态,不执行任何动作。状态机的三种实现方式第一种实现方式叫分支逻辑法。利用if-else或者分支逻辑,参照状态转移图,将每一个状态转移原模原样地直译成代码。对于简单的状态机来说,这种实现方式最简单、最直接,是首选。第二种实现方式叫查表法。对于状态很多、状态转移比较复杂的状态机来说,查表法比较合适。

weixin_44399827的博客 5002

探索设计模式状态机在软件开发中的应用

本文深入探讨了设计模式状态机的概念、类型及其在软件开发中的重要性。通过分析各种设计模式,如单例模式、观察者模式等,以及状态机的实现方式,包括有限状态机(FSM)和层次状态机(HSM),我们理解了如何利用这些工具来解决实际问题,并提高软件的可维护性和扩展性。

weixin_42571280的博客 791

详解设计模式:状态模式

状态模式(State Pattern)也被称为状态机模式(State Machine Pattern),是在 GoF 23 种设计模式中定义了的行为型模式。 在状态模式 类的行为是基于它的状态改变的。在状态模式中,我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象。状态模式 对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。 本篇文章内容包括:关于状态模式、状态模式 Demo

栗筝i的博客 7183

java状态机设计模式_状态机设计模式

初识我第一次知道状态机,是在大学学习《数字电子技术基础》的时候。一块控制芯片有若干输入数据总线Data_in,一个CLK时钟震荡输入,还有一定数量的以高低电平组合来控制状态的输入。不同的状态,芯片会对输入的数据进行不同的处理。再之后是读研时跟着导师做课题,用Verilog HDL写FPGA程序,仿真一些数字信号的处理算法,其中也大量使用了状态机编程。FPGA还记得有一次和导师沟通科研时,他提及说状...

weixin_28842367的博客 1735

嵌入式C语言设计模式 - 状态机模式

超详细讲解嵌入式C语言设计模式 - 状态机模式

qq_35337506的博客 3953

嵌入式C编程中的设计模式之二——状态机模式

一、介绍 二、状态机模式 三、结论

超级喵窝窝的博客 6341

状态机设计模式

状态机就是对状态进行统一管理的数学模型,应用在软件领域是状态机设计模式,有了状态机就可以避免在业务代码中对状态进行硬编码,增加系统的可扩展性。状态机设计模式包括四个要素:现态、事件、动作、次态。1、现态:是指当前所处的状态。2、事件:当一个条件被满足,状态会由现态变为新的状态,事件发生可能会触发一个动作,或者执行一次状态的迁移。3、动作:发生事件执行的动作,动作执行完毕后,可以迁移到新的状态,也可以仍旧保持原状态。动作不是必需的。4、次态:条件满足后要迁往的新状态。

cyt涛的博客 1131

java状态机设计模式_设计模式总结-State模式

不同的状态,不同的行为;或者说,每个状态有着相应的行为.二、State模式的适用场合:State模式在实际使用中比较多,适合"状态的切换".因为我们经常会使用If elseif else 进行状态切换, 如果针对状态的这样判断切换反复出现,我们就要联想到是否可以采取State模式了.三、State模式与Command模式的比较:前者从调用者和被调用者的角度出发,目的是封装被调用者的行为,让调用者只...

weixin_39980893的博客 351

状态机设计模式 Java

我整理的一些关于【设计模式】的项目学习资料(附讲解~~)和大家一起分享、学习一下:https://d.51cto.com/bLN8S1Java中的状态机设计模式 状态机设计模式是一种行为设计模式,它通过将对象的状态与其行为分离,使得对象在不同状态下可以表现出不同的行为。该模式在处理复杂的状态变化时显得尤为重要,例如游戏开...

weixin_41800632的博客 427

从 C++ 优化状态机实现:结合设计模式的实用指南

在编程世界中,状态机(State Machines)是一种强大的工具,用于管理复杂系统中的状态转换。然而,在实际应用中,状态机经常面临着代码重复、维护困难和可扩展性差等问题。这些挑战不仅从技术角度考验着开发者的能力,也触及到我们思考和解决问题的深层动机和需求。

探索C++编程的奥秘,分享深入的技术见解和实践,旨在激发读者创造力与解决问题的思维。 1403

设计模式状态机模式

这个就是状态机模式的精髓,因为处理的问题就是一个类的方法处理信息的模式和类的状态有关,那么换句话说技术类中的每个状态都要处理相同的信息,那么我们为什么不把这种状态抽离出来呢,然后单独考虑呢?但是,这个模式也有坏处,那就是没当添加新的状态,如果这个状态有和其他状态有转换,那么我们就不得不修改源代码,这里,本菜想,可以通过中介者模式来解决这个问题,具体方法是将。可以看到,典型的bad smell,这里我们可以将每个状态抽象出来,设计好接口,然后用多态来替代if_else。

weixin_62953519的博客 7474

设计模式-状态机模式

设计模式-状态机

zbbzb的博客 2990

设计模式之【状态模式】,如何设计一个“状态管理大师”

状态模式(State Pattern)也称为状态机模式(State Machine Pattern),是允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类,属于行为型模式。状态模式中类的行为是由状态决定的,不同的状态下有不同的行为。其意图是让一个对象在其内部改变的时候,其行为也随之改变。状态模式核心是状态与行为绑定,不同的状态对应不同的行为。

秃了也弱了 3627

状态机模型详细介绍:概念、原理、使用方法及源码解析

状态机模型详细介绍:概念、原理、使用方法及源码解析

深耕嵌入式领用多年, 致力于分享嵌入式领域技术! 3305

设计模式——状态设计模式(行为型)

状态设计模式是一种行为型设计模式,核心在于允许对象在内部状态改变时改变行为。它通过状态对象封装不同行为,使状态切换灵活清晰。该模式包含环境类、抽象状态类和具体状态类等角色,具有避免大量分支判断、符合单一职责和开闭原则等特点。适用于订单状态管理、流程审批等场景,其结构清晰,实现方式多样,能有效解决状态切换问题。

庄小焱 2331

设计模式 状态机

本文梳理状态机概念,在实操中状态机和类似,只是被封装起来,可以很方便的实现状态初始化和状态转换。

baiiu 1911
上一篇: Unity3D的Delegate和SendMessage的性能差测试,以及Delegate在多线程使用要注意的小问题
下一篇: Unity3d + NGUI 的多分辨率适配
mfc11
博客等级 码龄17年 65粉丝 39原创
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值