粉丝2.3万获赞27.1万

大家好,今天我们来学习设计模式魔之状态模式。那么什么是状态模式呢?类的行为是基于他的状态改变的。 这种类型的设计模式属于行为型模式。在状态模式中,我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象。何时使用。代码中包含大量与对象状态有关的条件语句。 使用场景一、行为随状态改变而改变的场景。二、条件分支语句的代替者。优点一、封装了转换规则。二、媒体可能的状态。在媒体状态之前需要确定状态种类。 三、将所有与某个状态有关的行为放到一个类中,并且可以方便的增加新的 状态。只需要改变对象状态即可改变对象的行为。四、允许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件与巨快。五、可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数。 缺点一、状态模式的使用必然会增加系统类和对象的个数。二、状态模式的结构与实现都较为复杂,如果使用不当,将导致程序结构和代码的混乱。 三、状态模式对开闭原则的支持并不太好。对于可以切换状态的状态模式,增加新的状态类,需要修改那些负责状态转换的原代码,否则无法切换到新增状态。而且修改某个状态类的行为也需修改对应类的原 代码。下面我来看看实力代码创建一个接口,创建 context 类,创建实现接口的实体类。 这样我们的代码写好了。下面我们来看看测试类使用 context 来查看当状态 state 改变时的行为变化。执行代码我们可以看到控制台打印的状态变化。 那么我们今天状态模式的学习就到这里了,谢谢大家。

说人话,中式站讲干货。你好,欢迎来到 it 老习的架构三百奖。我是你们的 it 私人顾问老齐。到今年呢,我从业已经十八年了,一直做扎瓦与架构的研发工作。目前呢,已经录制了十多门与编程架构相关的课程。 同时,我还会提供点对点的简历优化、模拟面试、 offer 选择、解决方案、加购指导等服务。总之呢,只要是我有经验的,能给兄弟们帮上忙的信息呢,我一定坦诚相待。有需要的小伙伴呢,可以看一下评论区或者我的个人描述,希望能用我的经验帮你少走弯路,找到更好的工作。 大家好,今天呢,我们来学习一个和之前讲过策略模式非常非常相似的模式,叫做状态模式。很多人呢,在使用的时候都产生幻觉,说这俩不是干一件事情的吗?为什么要 把它分开呢?那今天呢,我们就针对状态模式来进行答疑解惑。老规矩,咱们回到笔记来进行讲解。所谓的状态模式啊,英文单词叫 stat, 它属于行为型的设计模式, 让你可以在对象的内部状态变化时改变其行为,使其看上去就像改变了自身所属的泪一样。 这句话呢,其实说的大家云山雾绕的。其实啊,状态模式啊,非常简单,他是一个,就是 对象内部状态发生变化以后,那么我们得到的结果也完全不同的这么一个过程。比如说啊,现实生活中,我们一个作者呢,写了稿件, 这个稿件呢,它呢其实就分成了三种不同的状态。第一个就是草稿的状态,第二个是审阅中的状态,第三个是已发表的状态。 那么在不同的状态下,可以做的事情是不一样的。你比如说在草稿的情况下,我们是可以对稿件进行二次修改的。但是呢,针对于已发表状态的稿件呢,咱们就不能修改了, 可能人家已经印刷出版了,对不对?所以呢,在不同状态下,其实对应的行为呢,也是完全不同的。那在我们程序中,像这样的情况可以说比比皆是。 小道一个人员在公司中呢,他呢现在是试用期还是转正,还是准备退休? 这些不同的人员状态,其实也对应了不同的行为。或者说在我们进行图书借阅的时候,那当前这个图书是在七月七内超时了还是怎么样呢?那 也有着不同的行为和约束。所以呢,我们在实际开发的时候,要针对不同的状态,让他表现出不同的结果,或者不同的权限。那对于状态模式,就是解决这类问题的。不同的状态,我们产生不同的结果。 那么作为我们状态模式,它的结构呢?也包含了四个内容。第一个呢,叫做上下文,也就是我们操作的这个目标是什么? 你如果说你是借阅的图书,那这个上下文呢?应该就是这本图书。那除此以外,还有这个状态的抽象, 一本图书在揭阅过程中,是不是有放在图书馆里,是一种静止的状态,还有被借走以及归还这多种不同的状态呢。哎,不同的状态下,我们有着不同的行为,而 这些不同的行为,我们会将其剥离成一个一个具体的状态来进行处理。而最后呢,就是客户端,客户端是负责与上下文呢来进行交互,满足我们的业务的过程。 那么在我们业务处理过程中,状态呢,也可能会发生随时的变化,不同状态下有着不同的行为。这便是我们提到的状态模式。那放在代码中该怎么体现呢?又有哪些细节呢?我们通过代码的演示来一步一步进行说明。 好的,那我们回来。在之前呢,我创建了一个名为 stat 的工程。在这里呢,我们来构建一下这个状态模式。首先呢,咱们先来完成第一个,也就是咱们的上下文。这里呢,我模拟了一个场景假设 这呢我们开发了一个视频网站,这个视频网站中呢,他有着会员和很多个视频。那作为会员呢,他其实又分成了三级,普通的游客,也就是没有注册登记的情况下, 注册的会员,还有 vip 会员。那这三种不同的角色,其实呢,就对应了三种不同的状态。 那首先呢,我们要完成第一步,就是对这个不同的角色,也就是用户的状态呢,来进行一个抽象。这里我们直接把代码拿过来。首先第一步 创建一个名为 user state, 他的这么一个类。在 user state 中啊,你可以看到,在不同的用户状态下,他们在播放四 k 七二零 p 和一 零八零 p 这三类视频的时候,所处的行为是完全不同的。所以呢,我们将其进行了玻璃,形成了抽象的方法。 那除此以外呢,大家还要注意,在这个抽象类中,我们内部持有了一个优势对象。这个优势是什么呢?其实刚才我也提到了,他就是我们说到的上下文,也就是操作的目标啊。上下文里边包含了,就比如说当前用户的这个昵称是什么, 用户的其他的各项属性。因为在我们进行状态变化或者进行业务处理的时候,我们往往需要获取到这些用户的基本信息。 作为用户的上下文呢,直接拿过来他的代码呢,其实也是比较简单的。在这里啊,你会发现,作为抽象的用户的 状态,他呢内部持有的是优色对象,也就是状态对象里边持有我们的上下纹对象。那么反过来也是一样的, 我们的上下文对象也包含了用户的状态,这是一个彼此的双向引用。因为作为我们当前的用户,他也需要知道自己属于什么角色,也就是用户的状态。 而翻过来,在我们进行状态里面提供的啊,各种播放方法的时候,也需要得到一些用户的基本信息,对吧,所以是一个双向引用。然后呢,在这个优势的类里边呢,我们提供了一些方法,比如说 rejects 的方法, 代表用户注册的意思。当完成注册以后,我们这个用户就从游客呢,他的状态呢,提升为了 对应的会员。那么相应的我们还有的是这个 open vip, 也就是在普通会员的情况下,我们 open vip 开通了 vip 会员以后呢,他的状态呢,就被变成了 vip 的状态。 那么作为当前的这三个状态呢,咱们还没有创建。这三个状态分别对应了 guest state, 也就是游客状态, lamber state, 会员状态和 vip state, 它的 vip 的状态。那这些状态呢,其实本质上就是随着我们这个用户做的不断的操作,它的这个状态会发生改变。而发生改变以后的这些状态, 他们能对应的行为其实也是不一样的。比如说现在咱们先看一下游客的状态。游 克名为干 stat state, 在这里呢,它是继承自上级的优势 stat 去实现里边的 playsk play 七二零 p 和 play 一零八零 p。 在这里根据我们业务的需要,首先构造方法,从外侧呢去传入优势对象。 然后呢,针对于业务逻辑,普通的会员只能播放七二零 p 的视频。所以呢,这里我们打印出优 sir 点 getty name, 也就是从上下文对象中得到当前用户的昵称,然后 失忆性的说明他正在播放。但是呢,针对于 please k 和一零八零 p 呢,他则是不允许来进行播放的,直接抛出异常。那与之类似的,我们再来看下面的会员的状态。会员的状 状态呢,他和我们刚才游客状态几乎是一样的。只不过在实现这个不累方法的时候,作为 会员状态可以播放一零八零 p, 毕竟是免费的嘛,四 k 的成本太高了。那作为会员播放四 k 的时候也会抛出异常。普通会员禁止播放四 k 视频。 而最后的 vip vip 呢,当然是收费的会员了,他交了钱了,可以享受最好的服务。所以呢,所有分辨率的这个视频,他都是可以播放的。 那么针对当前的情况,你发现没有,我们其实不同的状态不就是我们在以前写代码过程中的衣服 l 四的这种判断吗?如果按照以前我们写代码,可能要 判断如果当前会员是游客,我们干什么?干什么干什么?如果当前会员是会员,我们干什么?干什么干什么?如果当前是 vip, 干什么?干什么?但是呢,现在呢?我们等于把每一个分支的情况呢,给他剥离了出来,形成了单独的状态这个类。 那不同的状态自然有不同的处理方式和处理的权限,对吧?所以呢,我们在每一个状态中来进行了判断。那针对于当前这个状态,我们回到刚才的上下文里边看一下它有什么变化呢? 作为当前的状态,刚才我强调的是双向的引用。那至于在每个状态中,我们如何让这个状态对象去持有当前的优势的上下文呢?哎,有两种方式, 我这里说明了一下。第一个呢,就是直接在咱们 getst 这个类里边,把当前优色对象再次传入进去以后,你可以发现他调用的是负类的这个优势。那在负类中, 他实际上就执行的是优势等于优势的这样的一个副职的工作,完成了内部持有上下文对象的工作。 那么针对咱们另外一种方式呢?如果说在构造方法中,现在我们不允许这么做的话, 你也可以在 stat 这个对象后面,额外的增加一个叫 satie user 的方式,把当前的对象给传入。这两种方式你二选其一就可以了。在我来说,我更倾向于选择构造方法传入,这样可以让代码变得更加的简洁。那 作为上下文,他写好了以后,下面关键的点来了。在不同的情况下,我们有着不同的处理权限。 而作为我们上下文对象来说,他作为优势用户吗?肯定是可以执行播放四 k, 播放七二零 p, 播放一零八零 p 这样的动作的。 所以在这里我们也增加了三个 play 方法。而不同的是,这些方法呢,实际上调用的是 user state 内部的 playsk。 play 七二零 p 和 play 一零八零 p 只是一个方法的传递吊用。 但是呢,在执行的这个过程中,当前 usstate 是什么?作为当前代码,他是不清楚的。这些呢,都是要在运行时,随着我们其他方法不断的变化呢,他呢以当 时的状态决定是否能够执行或者播放。这便是咱们优 sir 上下文要做的事情。总结一下,它有两个操作。第一个操作呢,就是作为 u sir 上下文对象,它内部呢提供了一系列的进行 状态变化的操作。哎,用这种 zs 点 usaceta 等于妞来完成对象的状态变化。 不同的状态拥有着不同的行为。那么第二个呢,就是我们去调用对应状态下的这些方法,完成不同状态下的业务处理。 而这个过程中, usa state 是在运行时才决定的,它呢拥有更好的灵活性。把这些整理好了以后。那么最后问题来了,现在我们真的有一 用户来了,该如何操作呢?比如说,此时此刻,我们新增一个客户端,作为客户端来说,大家请看。一个用户来了。这个用户呢,他呢?现在目前是一个游客默认情况下刚刚被实力画出来的对象呢?他的状态就是游客。 那么作为游客来说,他呢是可以播放七二零 p, 但是一零八零 p 和四 k 是不允许的,于是咱们现在运行一下看看结果。 与我们预期是相辅的。树先生现在正在播放七二零 p 没问题,但是呢, 遇到一零八零 p 直接爆出异常,禁止播放。那么为了让树先生能够看到一零八零 p 视频,树先生呢就进行了相应的注册的工作。注册以后,当 前用户的状态就转化为了会员。因为我们在注册方法中呢,可以看到使用的 new member state 来进行了实力化,并且将当前用户的状态呢进行了更新。 那所以在真正播放一零八零 p 的时候,就符合了会员的标准,可以进行播放。于是现在咱们再次运行看一下结果,是不是树先生可以播放一零八零 p 会员了, 但是四 k 视频他还是没办法播放的。最后呢,一看树先生确实很喜欢某一个电视剧,他呢开通了 vip, 最终呢, 树先生呢,他可以播放所有的视频。这些呢,就是完整的一个状态模式的业务逻辑。随着我们内部的状态变化,我们执行的方法的行为呢, 也在发生不断的变化。那把这个状态模式给大家梳理清楚以后,那下面的问题就来了。作为状态模式,他有哪些优缺点,以及应用场景,他和我们策略模式有什么不同呢? 好,来咱们总结一下状态模式。作为状态模式,他的优点呢,非常的明显,就是可以将 与某个对象的状态相关的行为呢,都放到单独的内中,封装成一个一个的状态。那此时呢,比如说咱们现在有新的状态,这个网站上增加了 ssvip 这个角色, 那么作为当前的这个新状态,如果要加入到现有的代码的逻辑当中,是一件比较简单的事情。我们只需要增加新状态,对原有 代码削微的修改一下就可以了。但是作为状态模式,他也有着一些不好的地方。状态模式首先你可以看到,针对于某一种可能出现的状态,我们都要封装成一个单独的状态类类的数量增加了。 那对于我们程序在 jvm 中的对象呢,他也会有明显的增加。那第二个呢,就是状态模式对开臂 原则支持不太友好。像刚才我们提到的,如果新增了一个状态以后,那么作为这个新的状态,是不是你要在上下文中,你总得提供一个方法,让他能够让普通用户 提升为这个 svip 吧,对不对?所以呢,我们或多或少的还是要修改代码的。但是呢,这却不符合我们开辟原则 的一个基本的理念,这是他的缺点。那么状态模式有什么样的使用场景呢?最明显的状态模式就是消除了大量的与对象状态有关的条件判断。 如果我们在实际工作中出现了大量的衣服, l 四大段大段的判断都是针对这种情况下我们干什么事,那种情况下我们干什么事,我们可以将其剥离为一个一个的状态。然后呢,通过状态的方式呢,来解决这种分支的情况, 这是一个非常好的处理策略。那最后的一个问题就是作为状态模式和策略模式有什么区别呢?如果我们从代码层面上来看,几乎没区别,但是也有一些明显的特征,我们也可以进行区分。比如说 作为状态模式,他强调的是不同情况下做的不同的事情,有的方法甚至不会执行。比如说一个普通的会员,他就不允许播放四 k 视频,他强调的是对于方法的控制。 而策略模式呢,算法都是平等的,可以平替。什么意思?我们虽然在做事情的方式方法不同,但是呢,我们输入的内容和输出的结果在不同的算法下都是相同的, 只不过你里边的处理逻辑不一样的。比如说,我就拿我们现实中的例子,你可以骑自行车到目的地,你可以坐出租车到目的地,但是呢,我们的结果都是为了到达相同的地点。所以呢,这些策略是可以平替的。而状态模式呢,是不一样,他 强调的是方法层面上的控制。而第二个呢,也是一个典型的特点,就是状态模式呢,它是不会对客户端暴露状态的。 你就像刚才我们使用的时候你看到没有,作为客户端,他执行的一个一个的方法,是不会涉及到任何状态对象的。这些状态的改变,都是被封装成了上下文中的一个一个的方法。 那么这些方法呢,驱动了我们不同状态下的不同行为。但是呢,策略模式就不一样了。策略模式是将所有的算法暴露给客户端,客户端你自己来选,选哪个我们就用哪个。 所以这是他们两者从表现形式上最大的不同。那如果按照我的理解来说,你可以认为这个 状态模式呢,是策略模式的一个升级版,他对于这个状态的封装程度呢,会更高,从用户的使用的角度来说呢,他呢使用起来也是相对更为简单一些的好。那么关于状态模式的讲解呢?就到这里,希望能对你有帮助。

好,那上节呢,我们就把这个创建对象哎给你看了啊,就是如何去实力化这个对象,这个呢我们就已经看完,看完之后我们接下来呢来再去给你定一个类,来,去把这个创建对象呢,再去给你加长一下啊,好,我们就开始去在这个地方呢来去创建一个类,那么 这个类我们的一个需求是什么呢?哎,要创建的这个类是什么类呢?来我们创建一个道个,这个类就是创建狗这个类, 那你想去创建这个道个类啊?你是来去描述啊?我们说一上来是不是做一个抽象,做一个描述的一个过程啊?对吧?好,来去描述这个道个他的一个状态行为啊,对吧?就是他的一个状态和行为啊。好,来去怎么样去描述啊?好,来去描述这个,那么 首先是不是他这个状态状态呢?哎?是不是道个他里边应该是有哪些信息啊?这个信息呢?由你自己来去定,你想让他有哪些信息, 把这些信息呢给他写到这里就行了。好,就比如啊,我在这里边呢,我来去给他写上啊,这个道哥呢?他有这个名字,然后呢这个道哥呢?他有这个年龄,然后呢 这个道个呢?然后他有这个颜色的吧?好,里面呢有这个颜色,然后道个呢?他有这个品种的吧?好,来写上一个太婆。 ok, 这是我们给这个道个来去定义的一些状态。明白 这个状态抽象的一个过程是你自己来去定义的,你可以去决定他里面有哪些这个状态。好,那么状态有了之后呢?然后底下呢是他的一个行为。好,那么行为里边呢我们就写上一个 party, 一个行为是不是用方法来去表示啊,对吧?好,帕布雷克一个 word 的 word 冲呢里面做一个 e t 让他来去吃。好, 他吃什么呢?由你来去决定。哎,你可以去给他传递个参数啊,来传递个这个副的给他。好,那么这个吃的时候呢?哎,他吃之前呢先去介绍 他自己,哎,他名字叫什么呀?在这个地方呢,哎,就是这个名字啊名字呢?哎,写上这个字符好,名字,哎,叫什么?什么耐木啊,对吧?好,然后再再去加上他的一个品种来在这里边呢写上一个品种。好,那么,哎,这个品种是这样的哈品种,然后加上是不是他这个太太啊,对吧? 好,然后呢再去加上这个颜色,好,里面呢再去写上这个颜色来写到这里啊写上个颜色,然后呢你等于等于写了加上你的这个咖了,那年龄呢我们就不要了 这个爱转呢我就不要了哈,把它去掉,那么年龄呢,你也可以去使用死菌类型的来去表示,哎,你使用什么类型来去表示?你到时候写的时候你就必须给他什么类型。明白。好,那你如果说年龄呢写的是死菌类型,到时候你给他是不是必须是这种形式啊,对吧?好,那这一式关于我们的这一块我们不要这个年龄了啊,哎,我们呢就看 定义这个内蒙你的一个卡了,你这个太婆,对吧?好,那么你吃之前呢,你先去把这个给我介绍一下啊。好,介绍完了之后呢,然后,哎在底下这个位置呢再去输出一句话输出水来输出,哎这个名称,哎,这个耐磨啊,耐磨,加上来写上一个吃吃之后呢,加上我们那个副的 来,那么这个呢,我们就给他写好,就是写了一个道格这个类,对吧?而且一个道格这个类之后呢,哎,里边有个行为,就让他吃的这个行为,他吃什么呢?由你来决定。好,他吃的时候呢,你必须让他来介绍一下名字叫什么品种什么样子的,颜色是什么样子的,来, 你是不是来去介绍一下,对吧?好,那么哎,在这里边呢,来,直接是给你写好,写好之后我们就可以去根据这个道格类来去创建具体的这个对象了。好,好,那同样呢,在底下这个位置呢,我们再去定一个这个太死的类啊, 就要你在这里边定义的这个泰斯莱里,就不能叫这个泰斯特了,为什么呢?因为在其他的这个文件里边哈,你看已经有一个叫泰斯特,你看人家在这里面是不是已经有一个泰斯特莱雅,对吧? 好,那么在这个中间你看是不是又有一个太似的,其实在这里边呢,他给你写了一个单词,看到没?这里面是不是有一个单词呀?对吧?这个单词什么意思?哎,这个单词呢,今后看到的时候要知道哈,他是代表重复的意思,对吧?好,你重复定义这个类名啊,那么 这里边呢,是不允许这个类名重复的,我们后面会给你详细介绍,现在呢,先去在底下啊,先去写一个一,好,好,这样是不是就不重复了,对吧? 就跟你这里面的这个太死了,不重复了啊,虽然讲他们不在一个文件里面呢,他里边也是不允许这个名称重复,我们后边呢会有这个解决方案。现在先别管他,我们来先去写个一,先去管好我们自己 如何去创建这个对象。好,那消耗之后呢?我们写上一个灭重序这个入口,对吧?好,消耗之后我们是不是就开始去创建对象了呀?对吧?好,创建对象,我们说说使用一个六观念字,后面跟上一个类名啊,对吧?好,跟上另一名呢?我们就跟上一个道格。 好,那现在来给你写。好,写好之后是不来去接触一下,来写上我们的这个道个一,哎,我们这个一二,哎,这条狗,那么这条狗一开始的时候呢,里边的这些属性,这些行为是不都没有啊?对不对?好, 那我们呢要去设置这个对象的状态啊,就是设置这个对象的这个状态,对吧?好,设置状态是不是就是你的这个名称到个一这个名 名称,你的一个内幕,你叫什么名字啊?哎,你在这个旁边来去给他设计个名称。好,那我们呢在另一边呢给你设计一个这个旺财一号啊,来,在这个里面呢写上一个旺财一号,就是你狗的一个名称叫旺财一号, 那么这个旺财一号,哎,你里边的这个倒个一啊,哎,你的这个品种是什么品种呢?来里边写一个太婆,对吧?好,那么这个品种呢?哎,我们呢就给你一个品种啊,哎,给一个二哈。好,那么这个是旺财一号,哎,他的这个品种是一个二哈的吧?好,那他这个颜色呢?来 这个倒个一啊,来倒个一呢?然后你这个卡了,卡了呢?你是不是来去给他设计一个颜色呀,对吧?好,那么他这个颜色呢?哎,我们呢就给他一个黑色啊。 ok, 写好,那 你看现在啊,你想去让这个道个,哎,就是我们的这个旺财一号啊,让他来去吃东西,对吧?好,那你看你掉这个方法的时候是不要求你传一个纸给他,你想让他吃什么呀?对不对? 好,你就在这一般呢来去给他哎吃一个这个食物,哎,那么这个食物什么类型的呢?你是不是来去定义的是滋补啥类型底下呢?要去给他一个滋补着太阳,对吧?好,那 在这里边呢,我们呢就让这个旺财一号呢,让他在里边呢来去吃鸡。好,那么让他吃鸡啊,好,那,哎,这里边运行的时候,你看啊,在这里边运行的时候,你看里边打印的应该是什么?是不是名称为这个旺财一号,品种是这个二哈,颜色是黑色的,哎, 他就开始去吃鸡去了呀,对吧?好,是不是他的这个旺财一号就开始去吃鸡了,对吧?好,那这中间呢,我给你加一个空格吧,好,这里面呢?这太挤了啊。 ok, 来这中间来,再去运行一下啊,来点击这个位置啊,点击运行,运行 的时候呢?哎,这样就好看一点了啊,就是没那么挤了。好,你看啊,哎,这个地方是名称是旺财一号,品种呢是这个二哈,颜色呢?是这个黑色,是不?旺财一号开始去吃鸡去了呀,对吧?好,那这个是第一个对象,那么我们有了这个类之后,我们是不是可以去创建很多的这个对象呀,对吧?来,我们又去 超你一个对象,来一个倒个,倒个冲奶,哎,在这个地方呢,是不是又一个对象呀?对吧?好,那写上一个倒个这个类型,好,就把这个类型的写到这里,这是,哎,第二条狗是不是倒个二啊?对吧?然后你的一个内幕呢?来,等于,等于说,哎, 这里边的这个纸呢?来,去给你写上一个 wc, 一个旺财二号。来这边给你写上一个旺财二号啊,然后你第一个旺财二号,你的一个品种是什么样子的?来,里面是一个太太啊,对吧?好,太太。来给你写上一个泰迪, ok, 那么这里边呢给你写好,写好之后呢来这个刀个二。第二条狗啊,哎,你的一个这个颜色呢?点上,哎,点上这个颜色啊,咔了咔了。之后呢来给你写上一个黄色,泰迪一般都很黄啊,好,给它写到这里边来, 写到这当中去写上一个黄色,好,那么这个呢我们就给你写好,写好之后呢,然后,哎,让第二条狗让你呢也开始去一躺,好, 然后你吃什么呢啊?上面是吃鸡,对吧?哎,你呢?你呢?只能吃鸡蛋啊,来,我们把这个鸡蛋呢给你写到这里边。好,那我们看一下啊,在中间呢,我们打一个分隔线。在这个地方呢打一个分隔线啊,好,打一个分隔线。之后呢,你看一下这两个狗两个对象啊,他是不是做的这个行为是不一样的呀?对吧? 啊,就是有一个累之后呢,我可以去生产出很多的这个对象,然后在里边的每一个对象是不是都有自己的这个特征行为啊?对吧?好,第一个呢名称旺财一号,他的品种呢?是二哈,颜色呢是黑色,是不?旺财一号,他是吃鸡啊,对吧?好,吃什么?是不是由你自己在具体这个业务场景里面来决定啊,对吧? 好,那底下旺财二号呢品种是这个泰迪,颜色呢?是黄色,他是不是只能吃鸡蛋啊?对不对?好,那就是。哎,关于我们的这个创建对象,我们呢根据一个需求,就是你先去描述一个例,那 它里面的状态,你是不是用这个成员变量,用这个成员变量来表示里边的行为,是不是使用这个方法来表示啊?对吧?好,你想去创建对象的来就可以去使用这个道格,这种 可以去使用这种形式。六,跟上一个类名来去创建个对象。哎,是不是可以去创建很多的这个对象呀?对吧?有了一个类之后呢,就可以去实力化出很多的对象啊,那这个呢,就是我们对象创建的一个过程啊,我们呢又去给你加强了一下啊,好,这一节呢。

今天给大家分享用状态模式优化代码,解决代码中的 if。 那比如说我这边有一个订单的一个状态, 我们假设他是一个三个状态,并且是一个单项的流程,我们先不考虑他未支付到取消的一个过程。但是在业务代码中,我们如果要修改订单状态,我们都会先判断一下订单的现有状态,然后再修改。比如说我们从未支付到已支付, 我们会先判断一下订单的状态是不是未支付,然后再给大家修改剩余支付,对吧?那这样呢,我们代码中就可能会写很多个一菲二四。那这边呢,我们就用状态模式来优化一下,比如说我们这边有一个订单类啊,然后呢我们先只考虑他一个字段,比如说这是状态,然后呢这边有一个状态的媒体类, 我们在媒体类里面呢定了几个媒体字段,比如说未支付、已支付,再到完成。然后呢我们在媒 类里面有外定义的一个 next stead 的一个方法,那这个方法就是贱民之意,就是这个订单的他的下一个状态是什么?然后呢我们在这个媒体类里面就依次的去实现这个方法。比如说我们当未支付的时候呢,我们实现这个方法,他的一个逻辑就是把这个订单状态设置成已支付, 就设置成他的下一个状态。同理啊,就是当已支付的时候呢,我们会把这个订单状态呢设置成已完成, 然后我们在订单这个方法里面呢,构造函数,我们会初始化成未支付,对吧?然后呢提供了一个 next c 的方法,在这个方法里面呢,我们调用状态媒体类的 next c 的方法,并且我们把当前订单对象传进去, 那这样呢我们就能够拿到当前订单对象的下一个状态。然后在这个测试方法里面呢,我们就不需要写这种判断的逻辑了,我们可以直接拿到订单当前的状态,然后 要用订单的 next set 方法,然后拿到他的下一个状态,并且呢进行打印好,那这边呢就显示了啊,未支付,已支付,并且呢已完成拿到了订单所有的状态。如果说大家想要这样的一个 demo 以及之前的 demo 的话呢,可以到这来 这,然后给他去发一个消息,像这样就可以拿到我们的 demo。 好,今天的一个分享呢,就到这。

一分钟教会你责任列模式 later 欢迎来到新一期的小欧说编程,今天来给大家分享一下责任列模式。首先我们先来举一下日常生活中比较常见的例子,比如你是一位学生,你现在要请假,学校有规定请不同的天数要由不同的负责人来审批。 你请假的天数小于或等于两天的时候,班主任就可以直接进行审批。如果是大于两天且小于或等于五天的时候, 则要由院系的主任来进行审批。如果你的请假天数大于五天且小于或等于十天的时候,就要由校长来审批。如果大于十天的话,这里面就会抛出一个错误,现在我们先来演示看一下效果,我们现在来执行一下。 现在比如我们请了五天假,这里面就会输出主任替我们审批了假条,但眼睛比较尖的同学可以发现这样的代码比较繁琐,还有就是 偶和度比较高,我们的客户端代码分别依赖了班主任、院系主任还有校长。如果后面再加一个审批的负责人的话,我们这里面还要进行修改,而且这里面有很多 e fl 时的判断,那我们要怎么对这个代码进行改造呢?这个时候就可以用上我们今天要讲的 责任链模式。责任链模式指的是有一系列的处理器,当请求的发送者将请求发给第一个处理器的时候,处理器会将这个请求一层层的传输下去,直到有一个处理者进行处理,这样就达到请求的发送者和请求的处理者择偶的作用。 现在我们直接用代码来进行一下演示,我们这里面先定义一个抽象的请假处理者,这里面他有一个成员变量,这个成员变量就是下一个处理者,他有一个方法用于设置这个成员变量,这个抽象类还有一个处理请假请求的方法,我们现在来看一下他的实现类,他的第一个实现类就是我们的班主任,如果这个请假天数小于或等于两天 的话,我们班主任可以直接进行审批,如果大于这个天数,我们就要判断他的下一个处理者是否存在,如果存在的话,咱们就将这个请求直接转发给下一个处理者,班主任的下一个处理者就是咱们的院系主任,院系主任可以审批小于或等于五天的假期,如果大于这个假期,我们就判断这个院系主任是否有下一个处理者, 如果有下一个处理者,我们就将请求转发到下一个处理者进行处理,如果没有的话,咱们就直接抛出一层,下一个处理者当然就是我们的最高级别的校长,校长可以审批小于或等于十天的假期,如果大于这个假期,我们也是直接抛出不能处理。我们现在直接在代码里面做一下演示, 这里面为了更直观的做代码的演示,我们这里面就直接创建了班主任、院系主任还有校长。在实际的开发中,我们这个创建的代码其实是可以封装的,我们的客户端只需要依赖咱们的班主任这个类就可以了。这里面咱们设置班主任的下一个处理者为院系主任,而院系主任的下一 处理者则设置为我们的校长,这里面咱们就模拟学生请假的请求,现在来具体执行,看一下效果。我们先清一下。首先我们先输入两天, 这里面我们可以看到班主任已经进行了审批,如果这个时候我请假请为四天呢?这个时候院系主任就会进行请假的审批,如果我的请假是八天,那就会由校长来进行审批。 通过责任链模式的改造,去掉了之前的衣服 s, 在后面我们就算再增加下一个级别的审批者,也不需要修改我们的业务代码, 我们的不同处理者只处理我们责任范围内的工作,超过这个范围的工作我们就抛给下一个处理者进行处理,也就是抛给我们的上级。通过这样的改造就实现了咱们的代码的结构。现在你们弄清楚责任列模式了吗?这个就是本期的分享视频,我们下期再见! nice。

大家好,这节课会讲解到我们是如何运行加瓦的第一个程序的,上节课讲到 gdk 的下载与安装,那么 gdk 安装之后就可以运行加瓦程序了吗?在这里我们留下一个伏笔,我们首先通过记事本来编写加瓦的第一个程序,我们来打开记事本, 首先我们来建立一个类 内名,就叫做 helloward 内,建立起来之后呢,我们需要来编写程序的入口, 程序的入口就叫妹方法。 接下来我们来打印一条输出语句, 说出的语句就叫做 hollowward。 注意我们这里打出来一个双引号,这个双引号是需要在英文状态下输出的, 这个语句的结尾需要用封号去结尾,封号同样也是在英文状态下输入的。接下来我们就要去保存文件, 我们给这个文件起一个名字,就叫做 hollywood, 这个文件的后缀名必须为点加瓦, 选择所有文件,点击保存。 接下来我们就来打开命令行工具, 我们找到刚才保存 hello word 的文件位置, 然后通过加瓦 c 去编译文件, 我们发现报错了,他说我们的加万 c 找不到, 这是由于我们没有配置 gdk 的环境变量,接下来我们就需要去配置 gdk 的环境变量。我们首先来打开高 高级设置, 打开环境变量, 双击怕死路径点开新建,在这里我们需要把并 gdk 的并路径拷贝到这里来,那么我们先要打开 gdk 的安装路径, 我们来到了 gdk 的安装路径,打开并这个文件,将这个并这个路径拷贝下来, 我们看到加瓦 c 的指定和加瓦的指令, 点击确定,点击确定,点击确定,然后我们呢再通过命令行工具重新编译, 发现还是报错了,这是为什么呢?在这里有一个细节,我们需要重新打开命令行工具, 找到刚才的目录, 通过加瓦 c 去编译文件, 我们发现没有报错,这个时候呢,我们发现我们去看一下这个路径发生了什么问题, 我们发现啊,他多出了一个后缀名为点克拉斯的自检码文件,这个时候我们都就需要用加瓦这个指令去运行我们的 加号程序, 注意这个地方不需要说出他的后缀名, 这样他就成功打印出了我们的哈喽沃尔德,谢谢大家观看。

hello, 各位同学,在刚刚我们已经学习了加瓦中的第一个入门案例, hello, word。 那咱们作为初学者,在刚开始学习的时候,肯定会出现各种各样的问题, 当你的代码出现问题了,此时你不能慌,不能怂,心态一定要稳住,慢慢解决就可以了,因为这是每一个人选的必经之路。 那你也可以添加我们评论区的联系方式,在群里面呢,会有很多小伙伴一起学习,你可以把你的问题发出来,看一看能不能一起解决。接下来呢,咱们就把一些常见的问题来汇总一下,方便大家以后学习。那说到 bug 呀,我们首先要来说一个单词,叫做 bug, 当以后代码出现了问题,我们一般不会说出问题了,我们会说出了一个 bug, 那么这个 bug 翻译过来就是小甲虫的意思。但是说到这个地方,我就奇了个怪了,为什么小甲虫跟程序出现问题会混为一谈呢?其实在这里他还有一个小故事, 话说计算机刚开始出现的时候,因为体积比较大,所以啊,一些小虫子很容易就能钻进去了,那么有一天有一个小虫子啊,说不定呢是一只蟑螂啊,他钻到了计算机当中,从而导致了计算机不能正常运行。 那此时呢,就有两个工作人员去排查了,就是这两个小姐姐。那有人问他们了, what's wrong 出现了什么问题,工作人员就回答, oh, bug。 所以呢,从这个时候开始, bug 就表示程序中出现了问题。但是呢,我们能不能发 搭讪思维想一想呀,如果当年计算机不是外国人发明的,而是我天朝大国,是我中国人发明的,代码出现问题,你觉得还叫 bug 吗?肯定就不叫了呀,你回忆一下,当你看到了一只蟑螂,你的第一反应是什么?是说 bug 吗? 肯定不是的,你肯定会大声喊出这四个非常经典的话,所以说,如果说计算机当年是中国人发明的,那么很有可能现在全世界所有的程序员出现问题之后,都会大声喊出这四个字啊,开个小玩笑哈, 那么当我们的代码出现 bug 之后,你不要怂,不要慌,我们要渐渐的具备具有识别 bug 的能力,那么培养这个能力呢,就需要多看多看老师 的代码,而且还要多看自己写的代码。第二,我们还需要具备分析 bug 的能力,这个就需要我们多思考,多查阅一些学习资料。 第三,我们还需要具备独立解决 bug 的能力,当一个 bug 出现之后,我们要多总结,这样呢,以后再次出现同样的 bug 的时候,你是不是就可以快速解决了呀? 但是这些能力不要着急,慢慢来,一点一点的去培养,这个呢是需要时间的沉淀的, 所以说大家以后呢,在课后写代码的时候出现问题了,可以先自己试着去解决一下,那如果说解决不了,可以添加评论区的联系方式,在群里面有很多小伙伴一起学习,你也可以联系黑马陈轩的老师啊,我们这边呢也会有专门的老师帮助大家 去解决问题的。好,那么接下来呢,咱们就一起来看一下 hello word 当中的一些常见问题。第一,标点符号的问题,在代码当中啊,所有的标点符号必须注意了,必须是英文状态下的, 那如果说你写成了中文状态的,那么他就报错了,比如说在这个地方,我已经列出来了,报了一个非法制服。 ok, 还有第二个单词拼写出现了问题, 在代码当中,该大写的地方一定要大写,该小写的地方一定要小写,这个呢也是我们经常犯的。好,打开一下今天的资料,找到代码文件夹,在这里呢,我们找到 hello word, 点加万,右键编起。 ok, 那 首先呢,我把这个分号去把它改成中文状态下的。好,那现在你来看中文状态的跟英文状态的有什么区别呢? 你来看,前面的是中文的,后面的是英文的。哎,你觉得是不是因为我天朝大国的伙食好,标点符号也胖一点啊? ok, 那如果说出现了这样的一个问题,我们在运行的时候会出什么样的问题呢?我们一起来爽一下,按无音加 r cmd。 ok, 在这个地方呢,首先我们要去找到这里的路径,先去切换一下 f 盘,哎呦,多打了一个斜杠,我们来写 f 冒号,再来 cd 加 ose, 再到里面的带零一,再到里面的代码。 ok, 回车。 好,那么此时来加瓦 c, hello, word 点加瓦, ok, 回车,你来看。哇哦,他说了是不是有问题了呀?是这样的,哪有问题? 第三行出现了问题,他在这个地方是不是有一个说需要分号,而且巴拉巴拉巴拉爆了一堆错啊?是的,在这个下面呢,他有一个箭头,他就指向了小括号的后面,他说这个符号呢,我不认识了,是不是一个总稳呀? ok, 所以说呢,在这个地方我们就要把它来修改一下,把它修改成英文状态下的就可以了,但是我们在写代码的时候,有的时候注意不到,怎么办呢?我给你分享一个小技巧,在我们的输入法当中啊,其实是可以设置的,来看左下角, 在这个地方,我用的是搜狗输入法,右键点击它,在这里有一个属性设置,在常用的这个下面会有一个中文时使用英文标点,咱们把它勾上就可以了,再把它关闭, 那么以后你输入的标点符号全部都是英文状态下的了,比如说呢,现在我们试一下,你看现在在这个地方,我是不是中文的输入状态啊?是这样的。好,然后呢,在这个后面我们要来输一个分号, 哎,你发现是不是那个比较细一点的英文状态下的呀? ok, 大家呢,只要做一个设置,就可以避免中文标点符号的问题了。好,那么这是第一个问题, 还有第二个问题,那如果说我前面的单词写错了,这个 system 的 s 要大写,但是呢,我一不小心写成小写了, 是不是也会爆错呀?是的,再来打开 cmd, 我们重新再来编一下。在这个地方呢,因为每次呢我都要去输入,感觉非常麻烦,有没有什么快捷的方式呢?告诉你,其实有的,给你扩展一个小点, 我们可以点击上面,然后呢再来输入 cmd。 看好了哈,我是点了一下上面的路径,输入 cmd, 然后回车, 哎,你看是不是直接就已经到了这个路径了呀,非常的省事,非常漂亮。好,那么接下来呢,再来加瓦 c, hello, word 点加瓦回车, 他又有一个提示说第三行出现问题,那出现问题了,在这个地方呢,会有一个小箭头指向了这个地方呢,其实呢,在这个地方,他说了是在这里 的前后,也就是在他的附近会有一个小问题。好,那所以说我们来找一找,你看是不是看到了呀? system 的 s 要大写,所以我们回到代码当中,把这个 s 变成大写,再来保存就可以了。 好了,那么以上呢,就是关于我们常见的两个小问题,关于这个知识点,咱们就先学习到这个地方。

史上最全抓板环境电量设置,首先我们安装 jdk, 在这里选择 jdk 的安装路径,然后下一步安装,选择 grry 的安装路径,安装完成后关闭 鼠标右键此电脑选择属性,选择高级系统设置, 在高级下选择环境电量,在系统电量这里选择新建电量。明白,抓个下滑线通电量只是我们刚刚安装 gpk 的目录, 复制出来粘贴在这里,然后确定 找到看,然后双击新建一个, 输入百分号,抓个下滑线通百分号变,在新建一个,输入百分号,抓个下滑线通百分号 grap, 然后一路确定,按下文加二,打开运行窗口,输入 cmd, 在这里输入 vivo, 出现这些环境电量就配置好了。