00:00
看一下备忘录模式的基本介绍。三点备忘录模式呢?它叫momentmental pattern,它是在指不破坏封装性的前提下,捕获一个对象的内部状态。并且将该对象并且注意到啊,并在该对象之外保存这个状态,也就是说他把这个最对象的状态呢,保存在另外一个对象的不混在一起,那这样呢,以后就可以将该对象恢复到原先的状态。这样子的。哦,我们也可以这样去理解备忘录模式,在现实生活中,备忘录是用来记录某些要去做的事情。或者是记录已经达成的共同意见的事,一防忘了。那么在软件层面呢?备忘录模式具有相同的含义。那备忘备忘录对象主要是用来记录一个对象的某个状态或者是某些数据,当要做这个回推的时候呢,注意他在记录这个对象状态的时候呢,可能是不同时期的。
01:02
比如说他在某个时期点记录最新的也是可以的,对不对?那么他需要回去的话,可以从备忘录对象里面获取到原来的数据进行恢复。从他的这个基本介绍来看,我们可以判断备忘录模式它是属于行为模式的。因为他是跟他的行为相关,对吧,那这样子光靠文字来描述呢,大家可能理解的不是很深入,现在呢,我们画出备忘录模式对应的原理类图,加深对它的认识。好,现在呢,我们来建一下这个包包好,这个包呢,我这已经建好了,这有一个ment类,每ment包好,这里面我们画它的类图。我们画这个类图呢,有这么几个重要的角色,我们分析一下,首先同学们,我们有一个origin。这样写啊,Origin,这个origin呢,就是我们的原始对象,也就是说准备要把这个对象的状态保存起来的。
02:05
OK,那么这个对象它保它的状态会保存到哪里呢?各位,它会保存到这个地方,有个它的状,就是它的状态,我们会保存一个叫mement。Mental的一个这样对象里面,当然这里面呢,会有他的一些状态信息,比如说我说比如哈,比如有一个statement记录他的状态。大音,比如说这个状态呢,是一个菌。理解啊,那它实际在实际概发中,到底这个origin它的状态需要有哪些属性来来保存,这个呢是不同的,比如说你如果要保存的是它的一个一个攻击力和它的一个防御能力,那这这个地方就应该有两个,有两个属性对不对?用int或者是用float来表示,我这用一个示意,比如用菌来表表示它的一个状态。那大家想一想,那既然如此的话呢,肯定我们这个origin nature呢,要用到这个min是吧,肯定要用到我创建一个给他们,那问题来了,这个min。
03:07
这个是用来保存我们这个origin的一个状态,那我们在保存的时候,是不是有时候也是需要有一个管理者的,因此呢,往往会有这么一个对象啊,这么一个类叫开尔。Caretaker。Takeer kaer,那这个是用来干什么呢?看啊,我们会这样做,我们会把这个ment。每这个对象呢,聚合到我们这个car take里面去,那大家想你这个状一个一个用户的状态可能有多个。或者说我有多个,我有多个originator,它有多个ment,那怎样怎样呢,我们这边肯定会有一一个集合来管理,这样是不是更方便一点,因此一般来讲呢,这个地方会有一个集合来管理它,也就是说这个M馒头。M tos加个S,那它的类型一般是什么呢?各位,比如是r list里面放的就是我们这个min。
04:08
OK,大概是这样一个形式哈,就也就是说这个里面呢,包含了很多的这个M的对象。哎,我不是一个个存的,我是放在一个极客里面管理,那最后同学们我们客户端对我们客户端用哪个呢?我们的客户端。我们的客户端只要去用这个origin就行了,比如说我们得到一个origin,然后呢,把这个origin创建起来过后把状态。呃,装建好放到这里面,也就是说大概是这样一个流程哈,当然也也有可能会用到我们这个地方。那也就是说我们这个client,呃,Client呃,会创建一个origin,然后呢,Origin里面呢,会创建它的一个状态,也就是momentmental的对象是例,然后放在这个car letter里面去进行管理,大致就是这样一个关系,好那有了这个图过后呢,我们这样子啊,我们就针对这个图呢,给大家把代码给实现一下,加深对我们这一个的认识,好吧,加深对它一个认识,这样理解起来会更到位一点,来我们写一个包,针对这个类图我们来写一遍。
05:14
那这个因为是理论的一个东西,所以说我写见包sir。好吧,那现在呢,我们先写哪一个呢?同学们,显然我们先这先写这个originator会比较方便一点,来走一个。好,A r or r。Orange对吧。这是我们的原始对象。那原始对象里面我就快速写一下,比如说它这里面呢,有一个状态就是state。OK,这是他的状态的一个信息。状态信息用时准表示,嗯,那么有这个状态信息的话,那显然我们这边会有set get方法。这个是跑不了的,对不对。下载方法,那大家都知道,当我们这个origin它的一个状态要保存的时候呢,我们提供一个方法,就是编写一个方法,编写一个方法。
06:09
可以可以保存,保存什么呢?一个状态对象。这个状态对象其实就是刚才我们说的明明。每对象到哪里去呢?诶到我们的这个信息里面去,也就是说这个地方我们会返回得到一个嘛。保存一个状态,因此我们需要返回一个对象,因此这里写一个方法,因此编写一个方法。返回什么呢?返回没对象。所我如果想保存了,我先把你这个每面对象拿到,好,我写一个方法public返回。OK。呃,没mi头,大家单词别写错了啊,没mi OK,那我们这写个save save状态。没头。OK,那这里面我们重要的核心点就是让他返回一个这样的就行了,那当然这个没头,现在我没没有写对不对,到时间我会写这么一个东西,把它放进去状态值,那你这个状态有了过后,把这个状态是。
07:12
返回就可以了,那现在我们开始来写哪个呢?同学们,我们顺带就把这个也写了,每面写出来。来,同学们写一遍。这应该是个类。May。OK。那这个类里面有哪些信息呢?我们可以来猜测一下对不对,显然是这样子的,它这里面呢,应该也有一个状态。因为大家都会保存一个状态信息嘛,所以在这里面我们写个构造器。写个构造器,你呢,把这个state给我,我就把state放到这个state里面啊,放到我们这个属性里面去,然后这里面呢,我们写一个方法叫get。是不是R这边我们有一个set和get,我们要一个get就可以了,不要那个set了。
08:00
也就是说我呢?呃,我可以干什么呢?我可以就是如果我有一个对象,我可以通过get statement把这个信息拿到2STATEMENT state的信息什么创建起来,在构造器里面放进去的构造器。好,那回到这边来,回到这边大家大家知道什么意思了吧,当我们要把这个origin的一个状态保存的时候,我们就save STEM啊,Statement,然后呢,这个地方就把当前这个原始对象的state state放呃,传到这个momentment里面去,得到一个manment头对象,好,这是它的一段代码,那那当同学们想一想哈。那既然我这里面有保存。把这个状态保存到美眉图里面,那显然同学们是不是我们还有一个得到。这是肯定的。OK。那么我们是一个得到。啊,这样子啊,我们先是不是得到我们这样写。嗯,怎么写呢,怎么这样写public void啊,我们不用返回。
09:03
得到一个状态的。From从哪里呢?从这个绵绵头,比如说我们只只想得到一个状态好,这样子就OK。这样就OK,那这个状态呢,我不返回,我直接付给我这个origin的,因为我我想恢复的话,我想恢复的话,主要是不是从这个momentmento恢复就可以了,大家明白我什么意思吧,就我不需要返回我。我我如果想恢复,就是通过这个备忘录,备备忘录对象恢复。恢复什么,恢复状态的话,我们只需要恢复到这个属性就可以了。那这个地方怎么恢复呢?非常的简单,是不是从这个明明透。呃,我们这地方应该有个min,我看看这个地方,那就写这样子啊,我们写个min。M,那你把这个给我MMOK,那这边呢,我们用刚才那个方法get这个就恢复了。
10:07
也就是说你你需要把这个origin进行一个恢复的时候呢,你把一个备忘录对象给我,然后我把这个我从这个备忘录对象里面拿到的状态,再恢复到我们这个origin里面的statement这个属性。好,这这就恢复是不是好恢复,不需要返回恢复就行了,那这个写完了以后,是不是这块写完了,这个这个也写完了,那大家想我们这个备忘录对象呢,是不是,呃最好是有一个呃集合来管理,所以说我这写个care taker。用这个呢来进行统一的管理会比较方便一点,来走一个。好,我们写一个类叫凯尔。Take。没问题吧,Kaer看。那这个类里面呢,它肯定是有一个集合的,对不对,我们直接写private list里面放了很多的对象。
11:05
OK,那这边呢,我们就写个list。等于六一个r list里面放的就是绵绵头。这样的对象实例是不是?我们一个包。我们一个包好拿到。那拿到以后大家想一想你。你有一个M头,是不是要抓进加进去啊,因此我写一个方法叫贸易的ADD。艾,那艾特的时候怎么艾特呢?你给我一个M名头,我就装进去就行了,对不对,M的OK。那怎么写呢,叫。每啊这个单词啊。然后怎么加呢,就是list。Then at my list。点爱。把我们传进来的这个对象加进去,那也就是说在这个集合里面会有很多的备忘录对象写到这里来,在哪里呢?在这个历史的集合中,OK,集合中会有很多很多的什么呢?备忘录对象。
12:10
明白,那既然有添加,是不是我就有得到,诶,我可以想得到第几个的呀,第几个原始原始对象的状态啊,是不是我也可以这样写,你给我返回一个M头。那我怎么写呢,Get。Get的话,我按这个索引来得。呃,我想得到第几个的in index,那这个就简单了,Return,从这个list的集合里面get,把这个index放进去,我写下这个方法的含义干什么呢?呃,获取到D。D index go什么呢?Or?Or?Later的什么备忘录对象,或者他的这个保存的状态被。备忘录对象即即什么呢?即原先保存保存的那个状态,因为大家刚才知道我们把对象origin和他的这个备忘录其实是分开的,对不对?
13:09
啊,这个大家应该一目而了然,现在我们就差最后一个,哪一个呢,就是C,我们来用一把。来试一下,看看能否使用成功。主要是看让大家看是怎么用的,好吧,我们勾上这个主方法。勾上主方法,那现在呢,我们来玩一把。嗯,首先我们创建一个原生的对象。Origin。这个没问题吧,好。拿到这个对象以后,OK,我们再创建一个卡。OK caretaker,那这个caretake里面大家刚才已经讲了,这边会保存很多的备忘录对象,这两个都有了。现在呢,我们。给这个R设置状态。比如这个是我们的一个状态,比如说啊,比如现在是,呃,对这个状态是啊状态是什么呢?是。
14:02
嗯,状态一吧,就状态状态一好不好,这个我我也不去编了,就状态一。那么这个时候我们设了一个状态,一过后呢,同学们,现在我们就可以把它加进去了。是不是现在我们可以开点ADD?At特怎么样?点get save。没错,诶,大家看这句话什么意思啊,同学们。是不是originator,它save一个state state这地方是怎么写的?还有印象吗?他是不是把你当前这个状态的值用作去创建一个Ming?那么它返回的这个M,返回来以后,各位同学是不是返回来以后,我直接加到了这个car taker里面的那一个历史的集合里面去,是不是这又保存了一个状态?是吧,这就保存了,保存了当前的状态。OK,比比如说吧,这是我们第一个状态,就是状态一状态一,嗯,我们认为是正在睡觉啊,这个怎么说呢。
15:08
状态一,这个时候他的攻击力吧,这样写攻。攻击力是100分。啊,100分好吧。那现在呢,随着他的游戏的这个这个玩法,诶,他又状态又发生变化了,来走original。他在玩的时候呢,他的状态又发生变化了,现在到了他的一个状态二。状态,那这个攻击力下降了,比如说下降到多少了呢?诶下降到。80了。OK,这是我们的状态二,那状态二它保存起来是不是我们又可以开take?点艾,诶这个时候又把这个这个orange这个时候的状态是不是又可以保存起来save一下。我问大家这个是不是又保存了一个M,只是这个时候状态二的状态,呃,状态二的那个情况。
16:01
是不是好,我们再保存一个同学们就可以了,我就不多了啊,我就保存三个就行,这个时候就set我们这是我们的状态三。比如说现在我们随着玩游戏呢,这个origin的状态呢,又发生变化了,他的血又攻击力又减少了,减少到50。截止到50呢,我又把它保存起来。好同学们,现在我想假如我想恢复到某个状态,大家能让我恢复吗?现在我我想恢复了,我希望恢复到状态几呢?我需要恢复到状态二。OK啊。我需要恢复到状态一吧,我需要恢复恢复到状态一,大家想我怎么恢复。我怎么恢复?其实非常的简单,非常的简单,我只需要这样做就可以了,诶我现在我要回复二,我这样是得到啊,我这样写。我先写一下当前的状态。啊,当前的状态是打一个空格,等于加上,那当前的状态呢,肯定是用这个origin。
17:07
Orange。later.get它的状态是不是就拿到了这个状态应该是攻击力是40,呃,是50。大家,但是我想恢复了,哎,我想我想得到什么呢,同学们,我现在呢,希望诶这个地方电影有点不足了,现在我想做这样一件事情,同学们。诶,怎么做呢。我我来得到我们第一个状态。啊,现在是当前状态,我希望我希望得到啊,希望这个我不要了。希望得到。得到状态一。得到状态一,那得到状态一呢,你看我这个代码就可以这样去写,同学们看我的代码怎么写啊。Get。Statement。Fromment,就是我要得到一个状态,从哪个呢?从这个mement对象得,但是我要得是从呃,第几个呢?是状态一的状态好,状态一那就origin。
18:08
呃,应该是caretaker吧。现在我们是不是要得到一个应该是care taker caretaker里面呢,我们get一个那状态一,其实它的下标应该是零,这个大家能理解吗?也就是说现在我们得到得到状态一并恢复到,将什么呢?将这个origin的状态恢复到一的状态。啊,恢复到。恢复。恢复到状态,一是不是这样就已经恢复了,这是得到,这是恢复好,我们现在再来输出当前的状态,它又发生变化了。我提示一下恢复后。OK,我提示一下恢复到恢复到状态以后,恢复到状态一。后的状态四啊,恢复到状态一,当前的状态是。
19:02
当前的状。状态是什么呢?OK,一样的,把这个再输一下,显然因为我这地方就恢复到状态一了,那这种应该输出它的攻击力变成了多少,变成了100来执行一把。同学们可以看到,同学们可以看到,你看。他呃,玩了一把,一把过后状态到三了,攻击变变50,然后我们恢复到状态一,当前状态又变成了什么100好,这就是一个非常经典的非常非常之经典的一个什么呀。就是我们说的状呃,备忘录模式,那么我们可以去记录一个origin的,呃,各种不同形式的状态,你什么时候都可以保存,那你想恢复到哪里呢?没问题,你只需要知道你想恢复到第几个就行。那你就调这个方法,Origin get statement from me就可以了,当然我这写的比较简单啊,同学们,因为我这里面保存的状态就一个string,其实呢,可以写的更复杂。
20:02
因为可能我们恢复的状态是有有多个属性对不对?那同学们看,这是针对一个对象而言的,这是针对一个对象,那么如果我们要针对多个对象,是不是做成一个数组就可以了,非常的简单,非常简单,也就是说你可以在这个take里面加个东西,什么呢?用哈希map来做,用一个K表示是第几个origin,然后再用一个另外一个集合来来表示它里面的到底是这个。呃,Origin第几个origin的第几个状态。啊,其实这个地方可以再组合一下,明白我的意思吧。好,同学们,这个案例呢,我就先给大家聊到这里,最后我们把备忘录模式他的一个角色的整理,再给大家说一下,他们是一个什么样的关系,捋一下这个之间的思路,好吧。我们捋捋这这个地方思路来走一下。备忘录模式的图先拿到这边来。是这个图吧?对,我们对这一个备忘录模设计模式的原理图呢,咱们做一些简单的说明,来回到这边来。
21:10
这些图聊一下。第一个,第一个我们首先可以看到是卡。啊,我们先这样写吧,哦。Are?Reator。这个是我们的对象,就是这个原始对象吧,对象。要要要保存什么呢?需要保存,需要保存状态的这样写,需要保存。某呃,保存那个状态的。状态的对象。这就是or,那下面我们可以看到哪一个呢?同学们看到我们这个mal。Mean。名这个类它是什么呢?同学们,他在这里面就冲的是备忘录对象。备忘录对象。OK,那么见识备忘录对象他是干什么呢?他负责追星,他负责啊。
22:04
他负责,诶就写错了。他写负责。他负责干什么呢?他负责应该怎么说这句话啊,负责保存好记录。保存好记录。哎,保存好记录。这样写就可以了,复责保存记录,即集什么集对象的,即我们这个originator origin originator的内部状态。是不是它的内部状态啊。内部状态,他干这个事情的。OK,那么我们再来看第三个,刚才origin这个已经说了,还开,还有一个care。Take。这个开taker是一个什么东西呢?它是一个守护者对象。守护者对象,它的作用是干什么呀?负责注意听,负责保存多个。
23:07
多个这个备忘录对象,因为它是一个集合嘛。他是负责保存多个备忘备忘录对象,哎,是以集合形式形式的,那么这样子呢,我们利于对多个对象的管理,使用集合管理,使用集合管理提高效率。提高效率了。你根据你的情况来来做就行了,比如说你想保存,对这个RN的哪个地方需要保存,你把加进去就行了,而且这方呢,我们可以用哈希map,可以把它进行一个扩展啊,进行一个扩展,我这不行不说这句话了,好紧接着还有最后一个是什么呢?就是我们的,呃,这应该说完了,Original me,看这个说完了我再扩展一下。就是如果你这个caretaker想保存多个origin的不同状态信息也是可以的。说明。说明,如果希望保存多个。
24:02
Origin对象。对象的不同。啊,不同时期的,不同时间的吧,时间的。嗯,状态也可以也可以,只需要干什么呢,只需。诶只需要干什么呢?把它用另外一个集合,比如说你们咱们可以用这个扩展一下,比如说用这个哈希map。哈希map来扩展就可以了,那哈希map这个你可以写数据,在这里面呢,再放一个集合。对不对,诶这是可以的嘛,那这个这这个string呢,就是我们的K就代表第几个啊这个呢,一个string一个几合,那这个string代表保存的是第几个origin letter的呃,信息,另外这个集合呢,在按照顺序里面放就完事了,非常简单,好吧,至于同学们可以稍微的扩展扩展,老师没有讲到的,提了一个思路,大家一下就能想到,这样才是一个比较好的听课的方式,那不能说老师讲了一个,诶说老师只只能保存一个origin,那保存多个怎么办呢?大家自己去稍微扩展一下嘛,思想已经有了。
25:11
好,各位同学,那关于我们这个备忘录模式的原理,还有它对应的代码,我们就说到这,其实下面的备忘录模式原理代码我们也说了哈,就是刚才写的代码。好的同学们,关于备忘录模式原理,工作原理,我们就先给大家聊到这里。
我来说两句