00:00
Java设计模式之状态模式。我们先看一个需求,是APP抽奖活动的需求,具体的需求呢是这样子的。说我们每参加一次抽奖活动,需要扣除用户的50个积分,中奖的概率呢是10%,所以说用,所以说某一个用户呢,他刚进来的时候,这个状态初始化为不能抽奖。因为你还没有去扣积分嘛,肯定是不能抽奖的,如果说他扣除50积分成功了。就说这条线就代表扣除50个积分成功了,他就进入到一个可以抽奖的状态,对。那么可以抽奖呢?OK,他如果点击抽奖中奖了,中奖的概率呢,假如是10%啊,也就是说他进入到可以抽奖的状态,并且他已经中奖了,那这个时候呢,我们就给他发放奖品,发完奖品以后。
01:00
这个时候就要看。一个状态了,如果说发完这个奖品过后呢,我们奖品的剩余数量还大于零,他就可以继续进入到不能抽奖的状态,什么意思,就是说可以再次抽奖。然后发完奖品过后,我们判断你奖品的数量还大不大于零,如果大于零的话呢,就认为我们这个抽奖活动可以继续玩。如果你如果你的奖品的数在这次发完奖品以后就等于零了,那怎么办呢?我们就直接进入到奖品领完的状态,大家可以看到奖品领完到奖品领完,一旦进入到奖品领完的状,那么我们这个就不能再抽奖了,因为这中间没有连接线,大家看清楚没有,所以说这个图呢,他就把我们这个抽奖的四个状态描述清楚了。描述清楚了,好,嗯,这边具体来说就这样子的,奖品数量是固定的,抽完就不能再抽奖了,活动的状态呢,根据刚才的分析,有四个可以抽奖,不能抽奖,发放奖品和奖品领完。
02:05
活动的诗歌状态状转换的关系图如这如右图,大家看清楚了,那这种题呢,其实是大家发现它的状态在一个活动中是经常变化的,是不是因此呢?我们可以用什么呀?我们可以使用状态模式来解决这样的问题,那么下面呢,我们就来看看状态模式它的一个概念。状态模式呢叫state pattern,它主要是用来解决对象在多种状态转换的时候,需要对外输出不同的行为,也就是说随着一个对象的状态发生变化,他的行为呢也有发生变化。状态呢,跟行为是一一对应的,也就是说如果你处于A这个状态。那么你就具有在A状态下面可以拥有的行为,或者是操作,OK,操作。
03:01
那呃,这个是对应的关系。状态之间呢,可以相互转换,如果我把这个状态变改改变成了B状态,那么它对应的就是在B这个状态下面可以拥有的一个操作,OK,好,就这一个意思。那么当一个对象在内。呃,一个对象内在的状态发生变化的时候呢,我们允许改变其行为,就是刚才所说的这个意思,这样对象看起来好像是改变了其类,为什么呢?因为他的状态发生变化了,他的行为也就发生了,所以说从这个角度来看呢,就好像我们这个对象改变成另外一个类的实例一样,但其实还是他。主要是他状态发生变化了,就你可以这样理解成就就这样理解,就好像有一个,嗯,有一个小孩对吧?呃,他还是六岁的时候呢,他可以去干一些事情,等到他长大了,他成年了,他成年了过后呢,其实就是他的状态发生变化,他可以做一些成年人的一些工作,比如说去当记者呀,或者是当老师啊,对不对,然后呢,他年年纪变大了,老人了,他老人了过呢,他有可以可以过老人的一些生活。
04:11
但实际上还是这一个,只是因为他的状态发生变化了,所以所以说他的行为,或者说或者说他可以进行的操作也就发生了变化,这个就是我们状态模式的呃一个概念。好了,那明白这个东西以后呢,下面我们有必要给大家讲一下动态模式的原理类图明白,那现在呢,我们仍然按照以前的套路,先画出原理类图,然后呢,再对状态模式的角色和他的职责做一个简单的说明,然后我们我们再走案例,好吧,各位同学打开这里。那现在呢,我们把这些先关闭吧。好保存一下,关闭所有哈,关闭所有,那关闭所有过后呢,我们现在新建一个包包。我们新建一个包,这个包呢,我们取个名字叫STEM。
05:01
没问题吧,就是状态模式,那既然是状态模式呢,那下面呢,我们就建这个状态模式的一个原理类图,OK。那么我们来看看,首先呢,状态模式,它一般会有一个state的一个接口。那么这个呃,接口啊,我发错了,不好意思,这是一个接口,并不是一个类。这是一个借口,State。OK。那么这个接口里面呢,它会定义很多的操作,比如说OPERATOR1 operator2等等吧等等,呃,我就不写那么多,肯定很多啊,123都有,那下面呢,我们就有一个类。啊,来实现这个机构,比如说我有个concrete。Concrete什么呢?类的,比如说是A。他呢会去怎么样啊,他去实现我们这一个接口。既然有concrete state a,那当然我们也有可能有另外的类,是不是我把这个复制一把?
06:04
OK啊,那我们比如说还有concrete state b同样呢,他也去实现我们这个state接口。那也就是说,呃,针对这个状态接口呢,它有不同的类,或者叫其实这个就是具体的状态了。那呃一虽然你我们都是这个状态,但是呢,因为我子类不一样,所以说对这个操作的具体的体现也就不一样,对不对?好,那现在呢,我们还需要一个类,一般来说在状态模式里面还有一个类,大家看到叫context。这个呢叫做上下文,对,他叫上下文对象,那这里边呢,它往往会这样子做,OK,它肯定会有state。他这边肯定会聚合我们state。就是我们的这个状态对不对,那我这写个叫stay。这肯定是有的。
07:01
肯定是有的啊,同样它会还会有set state get state这样一些操作,我就不写那么多了,比如有get set,对不对,Get a get set。Get这个,那返回的就是state,当然也有可能有set,我就不写那么多了,显然这里呢,其实这个上下文对象呢,会聚合聚集聚合我们这个state。这是肯定的,OK,那所谓聚合state的接口,其实是指通过这个接口去聚合,具聚合下面具体的状态呢,这个能理解对不对,这个能理解好的。那有了这样一个基本概念过后呢,我们把他的角色再做一点小小的整理,来,我们整理一下他的思路。呃,同学们可以看到这个context,刚才我写context类呢,为什么呢,为这个环境角色,就是我们说的上下文。环境的一个角色,那它的作用是什么呢?OK啊,它用于维护,它用于维护什么呢?Concrete。
08:08
特是不是state?这这个子类,呃,这个concrete state的实力。这个没问题吧,我把这个往上提一下啊。哦,我们把这个类图也截过来,这样子呢,我对着跟大家讲,大家可能听起来更清清晰一些。OK啊,我把它给大家先放这来对外类图,它维护的是concrete state的实力,当然也可能有A,有可能是B,对不对,所以说这个呢,这个类还有一个啊,它呢这个实例,这个实例会干什么呢。会,我们这样写啊,这样子简单一点,维护state的实力。这个实例干什么呀,它定义定义当前的一个状态,就是它当前状态是什么样子的。那第二个呢,我们可以看到state。
09:01
大家看到state,它是什么呢?是一个抽象的。它是一个抽象的状态角色,其实就是一个接口,说白了它是接口干什么呢?它定义OK,它定义。记住了,它定义什么呢?定义一个接口,定义一个接口。封装,封装与什么呢?OK与这个context context的一个特定接口,OK特定接口相关的行为。这个呢,有点不好理解,对不对,待会我们再具体说,还有一个呢,就是同学们看到的concrete。Concer state,这个是具体的状态角色。干什么呢,每每一个啊,我们说每个子类,每个子类实现一个语。实现一,诶这样子啊,实现一个与什么呢?OK与这个context还是我们这个上下文对象的。
10:09
干什么呢的。一个状态相关行为。状态相关的行为。行为,那也就是说在这个整个这个操作过程中,我们的状态其实是在不停的变化的。啊,状态变变化的,因为我这里呢,大家可以看到我是通过这个接口来进行聚合的,那这个接口可以是A,也可以是B,甚至在这个运营,在这个操作过程中,它的状态会变化,在某个情况下,它可能变成了A,也可能变成B,甚至变成了其他,所以说我们说这个对象呢,状态变化了,它的行为也就变化,为什么?因为你A实现的OPERATOR1和B实现的OPERATOR1肯定不一样。对不对,好,这个呢,就是它的一个基本的概念,大家看看能否理解。
11:01
好,基本的概念我们就先聊到这儿,那下面呢,我们就来怎么样啊,给大家用状态模式解决APP抽奖的这么一个活动,加深对它的认识。好的,那案例呢,我们放在下一个视频为大家讲解。
我来说两句