00:00
所以接下来我们其实就是要实现这个自定义的。实现。自定义的。Rich。Flat map function。Public static class。啊,那同样我们把这个。先过来,然后当前要extend方式。同样,后边需要有两个型,一个是当前的输入数据类型logging event,另外一个是当前输出的数据类型。把这个先定好,当然了,里边必须要实现的是一个方法。那在当前处理的过程当中,我们需要做什么样的操作呢?单来说的话,就是应该当前内部有一个当前的状态。然后基于当前的状态,然后再结合输入进来的一个数据,就可以进行一个状态的跳转。
01:07
然后接下来呢,我们就判断这个状态跳转是否跳到了match的这样一个状态,如果说。跳到了match的这个状态,那么就输出一个报警信息。如果说没有到达ma的状态,那又有其他的一些情况,如果到达了terminal状态的话,那这个时候我们就回退到初始的状态啊。那那如果说假如说这个都不是啊,什么什么都不是,那是中间的一些状态还没有结束的话,那就直接把当前的这个状态做一个更新,然后继续读取事件就可以了。所以整体我们的处理流程就是这样一个过程,要做一个状态编程。所以我们需要先去定义当前的状态。我们先说明出来。声明。当前的。
02:00
状态。状态机当前的状态。那当然了,既然只有一个状态,我们应该就只是一个state应该就可以了,所以直接用一个value state把它声明出来。当前的类型,我们单独定义一个叫做的类型吧,啊,那然后后边我们来一个。那后边既然有这样的状态声明,很显然我们就需要有open生命周期。然后。使用当前的get runtime context运行上下文,去get一个state,里边我们要去new一个value state script啊,在这里我们当前的。对应的类型啊,那应该也是这个state类型了。里边的话,那应该给一个比方说,这是当前的state,然后再加上对应的这个state state点。
03:04
当然了,现在这个state类型我们还没有实现。所以。当前我们还没有办法让它自动补全很多信息,我们先把对应的这个先定义出来,然后这个map方法里面就是各种状态跳转了,这个我们都已经想好了,现在先放在这里,先不管它,我们先要实现一个对应的状态机这样一个state的定义。所以接下来我们来看一看这个。状态机实现。所以接下来我们是public要实现一个对应的state这样一个类,那这里面我们的这个state呢,因为它里边有各种各样不同的具体的状态。所以很明显这个state应该是一。所以很明显这个state应该是一个枚举类型啊,所以接下来我们就是直接创建一个这样的枚举类。
04:02
State,然后接下来里边我们可能有一些基本的枚举类的定义,枚举类型的定义啊,首先我们定义一个。这是最终的结束状态。我们可以写一下,这是匹配失败。终止状态。然后接下来还会有一个match的状态。这个是匹配成功。要需要注意,匹配成功其实代表连续发现了,发现了连续的三个登陆失败事件。然后接下来呢,我们再来继续去定义,因为这里边我们可能会想到应该首先定义这个银尼兽状态,但是呢,这个银兽状态稍微有一点麻烦,就是当前这个以你手状态。如果来了一个非有数据之后,它应该是要跳转到S1状态的,诶,那所以这里边我们在定义这一个枚举类型状态的时候呢,应该要把他们每一个状态可以执行的跳转操作应该也同时定义出来,所以利用这样的一个思路,我们就干脆把剩余的这些状态,因为这个match和terminal不算严格意义上状态啊,因为到达这个状态我们直接做一个判断就可以把它直接跳转过去了,真正有用的状态其实就是以你手S1和S2他们之间是要来回跳转的。
05:38
那针对这三种状态呢,我们就应该去定义出它们可以执行的各种状态转移的方式,那状态转移的方式呢,就包含了当前输入的数据、事件的类型,以及当前状态要跳转到的下一个状态的类型。
06:02
哎,那所以这里边initial呢,它是要在输入fail事件的时候要跳转到S1状态,所以如果我们定义initial状态,那应该得先有S1状态才行,因为它是要跳转到S1状态的,我们应该把这个转移的规则要放在1INITIAL售状态的方法里面,那所以我们接下来的想法就是在。定义的过程当中,我们是反着来,首先我们有了match和TERMINAL2个状态,然后接下来呢,我们就可以先定义S2状态,因为S2状态。有了对应的输入数据之后,它能跳转到的状态就只有match和TERMINAL2种,所以接下来S2状态就可以定出来。有了S2状态,接下来就又可以定义S1状态了啊,那有了S1状态就返回来可以定义手状态,所以我们当前的一个定义的顺序是反向的,首先我们先来定义。
07:10
S2状态。那这里我们需要注意啊,在它的构造方法里边,我们可以传入。基于S2。状态。可以进行的一系列状态转移。所以这里边有一个问题,就是说我们还得专门定义一个状态转移的类,来表示当前的状态,怎么样去做转移的,哎,那这里面的状态转移呢,本质上其实就是其实就是一个二元组,有两个属性,一个是当前,就是要触发当前状态转移的一个输入的数据,当前的事件类型,然后呢,另外还有一个就是当前状态转移之后,转移到。
08:02
什么样的一个状态,或者说我们的转移的目标状态啊,所以接下来我们首先先把这个状态转移类先定义出来。我们定义一个。状态转移类。里面主要包含两个属性,主要就是当前。引起。状态转移的。事件类型。以及我们转移的。目标状态,也就是转移之后。转移到了什么样的一个状态,本质上其实就是一个二元组了,那么我们直接去定义public static class,我们定义一个叫做transition这样一个状态转移的类。里边主要的属性当然就是有这样的一个。
09:00
Private。String,那另外还应该有一个。Private state类型的一个target目标状态target state。哎,这就是里边主要的两个属性字段,当然了,因为我们肯定要创建对应的这样的一个状态转移啊,就是在我们定义某个状态的时候,把它能够执行的状态转移都要传进对应的构造方法里边,所以接下来我们肯定这里也是需要有对应的构造方法的,那我们这里可以直接把当前。包含了两个参数的构造方法,直接传进来。然后接下来。那就还涉及到我们应该有对应的。Gutter。我们可以把get even type和get target state这两个方法都直接定义出来。
10:01
有了这些之后,接下来我们就可以直接在状态机里边做对应的状态定义了,那首先这个S2状态的话,我们就直接把它定义成。S2,然后这里边呢,传入一系列的。Transition啊,也就是说这里面我们可以直接一个transition。里边的话,诶,那当然这里边就应该传入两个参数,如果说当前是feel一个数据来了的话,那我们知道基于S2状态的话,来了一个费,那应该它最终达到的是match,来了一个success,达到的是terminal目标状态嘛,所以接下来这里边前面是一个match。后边哎,那再一个transition。就是基于。Success。得到的。
11:00
目标状态是一个termin,诶,这就是我们基本的一个定义方式,那当然了,当前我们其实还没有定义state对应这个枚举类的构造方法的格式啊啊,那所以这里边我们可以直接把对应的这一个state枚举类型对应的参数要传进来。这里我们需要的参数其实就是一系列的transition。所以这里边我们可以多个,所以点点点二啊,用这种方式啊,传入一组的状态转移规则,利用这个来定义当前的状态啊,那当然了,当前我们可以定义一个this.transition。那么我们就让它等于当前的transition就可以了,所以上面我们需要把这个也声明出来啊,那当前我们可以定义private。Transition,它的一个数组叫做transition。就是。
12:01
当前状态的。转移规则,一系列转移规则,哎,就是通过这样来定义的。那除了S2状态之外。其实就还有对应的S1状态。因为我们知道S1状态它是可以转移到S2状态的,哎,那这样的话,我们有了S2状态之后,接下来就可以声明S1状态了,那整体的这个过程其实跟前面这里是差不多的。我们可以在这儿做一个对应的声明啊,那这里呢,应该是S1。首先在F的条件下,它跳转到的状态应该是S2。那么在success的条件下啊,来了一个登录成功的事件,他跳转到的依然是terminal,这个是一样。那最后我们还应该有一个。
13:02
初始状态隐匿手状态,那银手状态它是可以跳转到S1的,所以接下来有了S1我们就可以定义隐匿手状态啊。所以这个尽管看起来有点奇怪,但是是符合我们这里的定义规则的。到最后我们可以加一个分号,把当前的定义结束。当前这个叫做initial。那同样来了一个F之后,它跳转到的状态是S1,来了一个success之后,跳转到的是透明,这就是我们关于状态机的定义。那当然了,对于这个状态机而言,State这个媒体类而言,我们还应该定义一个状态转移的方法,也就是说当前啊,我有一个当前状态state,那接下来呢,我应该是传入一个对应的数据,数据类型就应该能够判断出来接下来当前的状态应该跳转到哪个状态啊,当然了,这个就是直接查它定义出来的这一组transitions就可以了啊,那transitions里边我们看匹配出来的到底是F还是success,那就可以确定当前状态跳转到对应的哪个状态。
14:19
所以接下来我们还应该有一个。状态的。转移方法。我们把它public啊,这个肯定是在外边可以调用的啊,最后得到的应该还是一个state状态的转移嘛,还是得到一个新的状态啊,我们把它叫做。里面传入的参数,我们这里边直接传一个。Event type就可以了,把当前的成功还是失败的类型进来就可了,所以接下来我们当然是要查询当前的。Transitions这个列表吧,那所以这里transition。
15:02
每一个都拿出来做一个比对。如果当前的。transition.get type,我们get它这里的第一个字段啊,当前的type如果拿出来之后,它和。当前传进来的如果是一样的话,那么这个时候。我们就直接可以return了,直接可以return当前transition的。Target state啊,这就是我们整个状态转移的过程,其实整体还是比较简单的啊,啊,那当然了,假如说我们在这个循环里面就是找到了的话,那就return对应的这个state,那如果没有找到怎么办呢?没有找到的话,那说明我们当前已经结束了啊,那所以就可以直接回到初始状态。为什么会出现没有找到的情况,因为这里边我们的状态有可能是terminal或者呃,Ma对应的这样的一些情形,那假如说我们已经找不到对应的呃,能够有的跳转的这个状态的话,那很显然就直接跳转到in手就可以了。
16:18
所以这里边直接return initial。我们的以你手前面定义的时候没有大写,把它改成大写。这就是完整的状态机的一个定义和生音。
我来说两句