00:03
使用职责链模式解决OA系统采购审批的需求,那前面呢,我们已经把这个需求说的比较清楚了,就这么。前面这几个就是5000由教学主任,1万由院长,3万。副校长,3万以上校长,所以说我们这个审批级别呢,一共有四个。现在呢,我们还是按以前的思路来说,先画出类图,再走代码,大家听起来会比较清晰一点,那还是打开我们eclipse,我们先来画出这一个OA审批的流程图啊,不类图。走一个。那现在在这里呢,我们写个OA。我要走。我们来看一下第一个类。首先根据前面的分析呢,我们是不是应该有一个抽象类啊。这个抽象类就是前面我们写写的handler,我取个名字叫approve。处理者这个类里边呢,它应该包含的有一个比较重要的属性,就是它本身也含另外一个处理者,所以说我几个op pro。
01:10
类型呢,对也是。对吧,然后呢,他们之间是一个聚合的关系。好的,同时它这里面应该还含有另外一个比较重要的方法。另外一个比较重要的方法就是他能够去处理什么呀,请求。对,所以说我再加一个operation。这个名字呢,我们取取下,叫做process process process。处理什么呢?处理一个request。好吧,就这样取这个名字,如果他能够去处理他就处理他,如果处理不了要下一个,当然他是个抽象类啊,我们说说刚才说的话呢,都是针针对他的子类而言的。针对它的子类而言的好,下面呢,我们说看有哪些子类,首先根据刚才分析,有先是系主任,所以说我取个名字叫depart。
02:05
Departmentro。APPVE,这是我们系这个级别。的处理。那么同样让他去继承。这是一个,我们再写第二个。那第二个是谁呢?是我们学院的处理级别,就是院长这个级别,College。OK,让他呢,也去继承approval。我们再来还有谁呢?同学们,下一个就是我们的副校长,这个级别是不是副校长呢?怎么去?然后school。School,然后master。副校长这个级别也让他去继承oper。还有一个。就是校长这个级别。校长呢,是处理最后的就是。金额大于3万的,我写个叫个。
03:02
Master。同样他也去继承我们的approver,好,这个就换完了,那换完以后呢,同学们都很清楚的知道。就是我们还需要一个请求,请求呢,我们会单做一个类,我取个名字哈,呃,因为我们是购买请求,我们就叫per。Purchase。购买的一个request。当然这个购买的请求里面呢,它也包含一些属性,待会这在写代码的时候,咱们再继续说这个purchase request呢,会被谁使用呢?会被我们approver使用。好,下面呢,我们就有一个端了。端它会怎么去用呢?它首先去创建或者说得到一个purchase request,然后将它传给下面的某一个arover的指类对象,让他处理就可以了。好的那类图我们就画完了,下面呢,我们来走代码,下面我们做代码,按照刚才讲解的顺序一个个写就行了,我们先画哪一个,同学们应该先写purchase request,为什么呢?因为他要用到它。
04:14
然,所以说先写他是比较合理的,先写出这个请求,那跟上我的思路,我们先写purchase。这个类OK。写上,这是我们请求。Per。Chis。什么呢?Request OK。那里面我们定一些属性吧,属性我们来定一些,这个呢,大家可以随意哈,比如说我们定义有这么几个信息,它的类型。这个是请求类型。让他请求类型完了,功能请求有个number,也就是说呃,它是第几个请求,咱们可以这样去处理对吧?OK,拿拿一个。Number。
05:00
呃,然后呢,我们再来看还有哪些需要做呢?诶这个写错了。还有比如说请求的金额,就是我们比较关心的float price来写个零。点0F,好。好,紧接着我们还有什么呢?同学们还有一个ID。我们认为它还有个ID号初始化呢,给他一个零就可以了,上面这个也可以给默认类型为零。Number也等于零,好吧。现在呢?我们需要一个什么呀?构造器,我们来写一个构造器吧。各造技能,把这四个都给他,其实有一个可以不给,就ID呢,我们让他随机的生成这个ID,我就不给了,那你要给也可以哈,比如说代,代表几号是第几个请求,但请求编号呢,有时候我们可能是随机生成的,这个大家可以自己去玩哈。给他也就给他吧,无所谓。好,那这样子的话呢,我们看看要补number这个就不要了,我们就一个价,就是代表这是第几个请求,然后呢,Price呢,就是金额type,我们可以保留number,我们干脆就别别要它了。
06:10
好吧,我们这样稍微的改进一下。好的。这样就可以好,这样就可以number,我们不要了。需要我们再加,现在暂时不要。好,这是我们的构造器。有了。构造器。那都要去有了过后像他前面的这些get的方法呢,咱们也给他一下,因为我们在显示这个请求具体信息的时候呢,我们需要get一下。OK,现在只要get不要了,好吧,就拿一个get get get。好,同学们,我们这一个够请求,咱们就选请求类。写完了,也就是说。我们的这个类图里面,它咱们就写完了。保存一下。好,那这个写完以后,我们写哪一个呢?来,我们现在写就是我们的。
07:04
审批人或者说请求的处理人,我们来写一下。Upper。写个类,这个类呢,我们做成一个抽象的。来一个abstract。那大家想一想,A,它是一个抽象的话呢,根据刚才的分析,它首先有一个属性。就是APPAPP。好,这个不行啊。诶,这个这个可以给他,哎重新来,那我们写一个APP power好。Power。就它自身呢,还有一个另外一个。审批或者叫处理人,我们再来一个string。OK,来一个string名字,这是它的名称,名字是什么?啊,这个是他的下一个后继者,就是下一个处理者,下一个处理者OK。下一个处理者,处理者。
08:01
那么同学想,肯定我们需要一个构造器。对吧。构造器给他这个,诶,嗯。这样写。ABBR给他一个构造器。那这个构造器里面要给我传一个什么呢?同学们,至少你要告诉我你的名字,就是你是校长呢,还是一个系主任,对不对?我们this name一下。对于创建的name。OK,紧接着我们继续下面写,下面呢,这个下一个处理者,你要给我一个set方法比较合理,所以说我们来得到一个晒的方法。对,你要给我,你的下一个处理者是谁?下一个处理者下一个处理者。好,那这个有了过,我们是不是还需要一个特别重要的方法。哪个方法呢?同学们,就是我们这儿所说的这个,就是你这是下一个处理者,那么同学们想一想,我们是不是有一个特别重要方法,你要去处理信息啊,所以说我们还要写一个叫做处理处理审批请求的方法。
09:12
他会要什么,他是要去去处理这个审批的,所以说他会要得到一个请求。这个时候,因为处理呢,是由是子类子类完成的,因此因此将该方法,该方法做成抽象。这个大家能理解哈,因为他自己的子类去处理,那么写个public,什么abstract。然后这个方法呢,叫VO,咱们就写个process,刚才已经写过了什么呢?Request,我们在处理的时候,你一定要给我传一个process request。对不对。你要给我一个请求,我才能去请求。拿到一个请求,那具体具体来说,这个怎么请求,那就是只能去实现了。
10:00
好的,那现在呢,我们又把哪个做完了呢?同学们,我们又把这个写完了,下面我们来写depart,就是系这个级别的处理方案。来写一个很快哈,并不是很,这个呢,并并不麻烦,大家一听就懂,Department。对不对。好,我们让他呢去继承,让他去继承我们前面写的这个。写下写的APP。对不对。好,显然这里面必须去实现。刚才那个抽象方法。同时呢,构造器我们也要去做一下department。构造器好的,那构造器我们这边写一个这这样的方法,就super调它类的,把名字传进去就可以了,显然我再去创建。一个系这个级别的处理者的时候,我要把名字传进去。这个搞定了。
11:01
处理的时候就根据情况来写了,大家还记不记得,对于一个系主任,他能处理的金额是小于等于。这个5000块钱,也就是说他应该这么去处理,我们从这个请求拿到他请求的金额点get。它的金额好,我们看看它的金额哈,这边现在number哦,这个金额price。从我们这边看出来,我们这个请求,这个price就是它的金额,他请求的金额好不好,这是一个请求的金额。那既然你是请求的金额,那么我们通过这个get price来处理就行了。get price。拿到你的这个钱,如果说你这个钱是小于等于5000块钱的,是不是。就该我来处理。那我来处理,我就写一句话,就是我能处理哈,OK,写这么一句话,我说。呃,请求编号。编号,这个编号ID我们把它打出来。
12:01
那我就写了哈,就是purchase。拿到它的编号,点get ID。被谁处理呢?被?OK,把我们这个人打出来,被谁谁谁处理呢,被this点内啊,就是被我们当前这个对象这个处理的请求了,被它处理了。好,就这个意思就行了,好吧,然后我这。换一行啊,不用换行了,就这处理吧,Else什么意思?Else就是说我处理不了,因为你的金额可能没有在这个范围内。是吧,没有,不不是小于等于5000的嘛,那如果说你没有在这个范围内怎么办呢?我让我的这个请求者就是我的下一个请求者,点什么呀,Process。是不是处理我让下一个,我的下一个后继者来处理这个请求完事了。其他的代码我相信大家知道怎么写了,大同小异,大同小异是不是大同小异只是。
13:03
这个范围不一样,好,我们快速的写一下,我们现在应该写哪个了呢?同学们跟上思路,下面是学院这个级别的college。Op p pro,好的。那他呢,也去继承哈,各位同学,他也去继承一下我们这个power。那代码呢,跟前跟前面非常的相似,那我就推一个来了,同学们,我把这个复制下来。稍微改发一下,首先构造器这块改一下。是不是OK,这边处理请求范围是不是发生变化了,那么同学们想一想,我们刚才讲过,学院的处理的是它是大于5000块,小于等于,嗯。1万块钱是由院长来处理的,所以说这边呢,我们要这样写了,把条件进行一个变化。就他的金额要大于啊,大于五千五五大于5000。并且呢,并且要小于等于什么呀,小于要小于等于1万块钱。
14:05
在这个范围里面呢,我们这个请求就让他来处理,否则让下一个去处理,是不是这样子不用改了70多。我们紧接着再来写下一个处理者,下一个处理者是我们的副校长,副校长也很简单啊,咱们写一个v school。Col school zner。好,我们看一下。好,School,我们把这个school写到这里,过后呢,我们写到,嗯,还有个master。Master,然后呢,这边有个power。Eight。AP pro v,好吧,就把这个名称咱们写到这里就可以了。好,我们接着往下继续走。好,把这个稍微改一下,School master,好,我们往下走。
15:04
然后呢,让他也去继承哈,继承A。同样它跟前面的实现的思路也是非常相似的,对不对,非常相似的,所以说我把这个代码呢,拿过来改一下。不需要再重新再写一遍了,改下就可以了,首先构造器我们需要改一下,同时范围要变化,这个时候范围呢,变成了大于1万块。是不是大于1万块大于1万块呢?小于等于3万块。好,这个请求就被什么呢?就被我们这个副校长去处理了。紧接着我们再来写校长最后这个处理者。看一下。校长呢?我们就叫school。OL school master。Master OK,然后呢,它也是一个处理者。构上,同样,我们让它继承aro。
16:01
好的处理过后呢,我们仍然把这个代码拿过来用一下。改一改就可以了,是不是改一改就可以了。那么他改的时候呢,我们把构造器的名称改一下,然后这边要改了,因为他是处理大于这个3万块钱以上的。说这边条件呢,改一下,改成这个大于3万。OK,那就是这样大于3万块。大于3万块钱以上呢,由我们的校长来处理完事。那现在我们可以看到,嗯。现在呢,我们已经把就是把这几个就写完了,Process我们也写完了,现在我们来写一个client,进行一个简单的测试,看看行不行走一个。代码来测试一下写client端。Client端。把主方法勾上。好的,那现在我们第一步呢,先创建一个请求,对不对,我们先创建一个请求,请求呢,我们就这样写了,就是purchase。
17:06
好,这样类型,我们给他一个一价格,比如说这次价格是,比如说是他。呃,31000块钱,编号为一。OK。编号为一,拿到了我们这一个请求,这个请求呢,我要开始发给一个人,但是我们现在还要创建,创建相关的什么呀,审批人。审批人。那审批人我们怎么创建呢?来六,我们从系主任这边开始创建。给他一个名字,叫主任。或者张主任都可以啊,比如说你是一个叫张主任。张。张主任。OK。拿到名称,第二个呢,我们再来拿一个院长,留一个college。
18:00
对,College给他一个名字,我们叫做李院长。好,李院长呢,也创建起来。紧接着我们再来创建一个校长、副校长,那就是VS。Schoolmaster。那么我们写一个叫做王副校长。副校。复效。给王副校拿到了再来,最后一个就是什么呢?就是我们的校长,又一个校长school。School。那校长呢,我们就取个叫做。啊,叫做什么呢?童校长A叫做。嗯。叫做这个增生,你是王五对不对,我们再来一个就是。童校长。好,童校长。拿到了我们不同的级别,让不同的去处理,但是大家想想,我这样做我能能够马上去用吗?同学们想我这样用行不行,我让department系主任去处理这个请求。
19:09
把这个请求往这一放,大家觉得我这样做会有什么后果没有?我这样做行不行,我这样如果一执行你会看到呢,同学们,我一执行大家看到他会出一个什么情况,大家想一想啊。首先我这一次大家看到抛出了一个异常。抛出一个异常。来看这里。他在地方抛出了一个空指针异常,大家知道为什么吗?是因为是因为如果说大家看。因为你在处理这个请求的,这个请求呢,是31000块钱,其实最终是由校长来处理的。那么当他不能处理的时候,他会叫他下一个处理者去处理,这个时候他下一个处理者你并没有给他设置,他就报控制帧了,假如我这个钱呢,是这样子的,他就不会出错,比如说我给了1000块钱。这个主任他本身就能处理,所以说你看请求编号为一被张主任处理了,但是你3万就不行,你31000块钱是他要往下一个人去找的,因此在这个过程中,我们还需要。
20:07
需要将各个审批审批级别的下一个人处理好,设置好。好,OK,你这个不是不处理好要出问题,因此我们来处理一下department.set。他的下一个处理者是谁呢?就应该是我们的院长Colin。同样,你这个college。Pro,他的下一个处理者是谁呢?是我们的副校长。对不对,那副校长呢?同学们,副校长set下一个。他是谁呢?当然就是我们校长了,那我问大家一个问题,这样写对不对?这样写也不行。这样写呢?也会存在一个问题,假如我现在是一个1000块钱。是一个1000块钱,但是呢,我上来过后,我就让我们的这个校长去处理,这是有可能的。
21:03
对,假如说我在调用的时候,我说有一个请求,我直接让这个校长来处理。校长其实是不能处理。1000块钱的。而它下面又没有,因此你这样一执行,他会仍然报一个控制的异常。是不是,所以说你不要忘了一件事情,我们要形成一个环状,这个地方要形成一个环状啊,各位同学要处理人,处理人处理人形成。构成环状。构成一个环形。当然我这个地方所谓的构成一个环形是指的什么呢?是指的就是说你你一定要找到一个去处理。也就是说我们允许从校长这边开始去处理,这是有可能的,当然如果说如果说你就构成一个单链的,构成一个单单单单向的,那也可以,那你就必须从第一个人掉。也行,就是如果你你说老师那对不起,我在校长的下一个,我就认为他已经到头了,他没有下一个人,我不想去处理,呃,不想去设置,那如果这样的话,那你一定要记住,你所有的处理一定要从第一个人开始找也可以,那如果说你认为我从校长那边也可以处理任何一个请求。
22:16
那么你就不要忘了要做成一个环状,那我们把它加上就行了,Schoolmaster。Power set谁呢?把department set进去就行了,它就形成一个环状,最终它总能找到一个去处理,你看现在我这一处理,他会找到谁呢?他会找到张主任。是这样的吧,OK,那同样道理,假设现在我们当然正规情况下我们还是,呃,正规情况下还是应该从我们戏组这最低的这个级别开始去找,对不对,是这样子的。呃,但是有时候为为了提高这个效率呢,你可以简单判断一个范围,直接找中间这个人也是可以的,比如说现在我把它调成31000,然后调成31000,你们发现呢,这样一走,诶,他还是找到我们的校长了。是不是被童校长处理了,那么那我问大家,也就是说其实这个请求啊,你你随便找哪个人都能找到,比如说你说我我让副校长去处去去处去处理这个请求,其实也能找到他。
23:13
为什么呢?因为你是个环形的,所以你这样一次性都都OK啊,都OK,你看最终都找到我们的童校长。好同学们,那代码呢,我们就聊到这儿,代码我们就聊这也就说通过职责链模式来解决OA系统的审批,我们就说到这里,他们他们就根据我们的一个什么呀,根据我们的一个类类图形成了一个环状,那最后它的情况大概是这样子的啊,那这个这个线呢,我就。嗯,这样化了,他会这样去找他。诶,他去找他,他去找他,如果他不能处理呢,他就去找他明白好词着链这个代码的。讲解,我们就聊到这里。
我来说两句