23.1 场 景 问 题

23.1.1 申请聚餐费用

来考虑这样一个功能:申请聚餐费用的管理。

很多公司都有这样的福利,就是项目组或者是部门可以向公司申请一些聚餐费用,用于组织项目组成员或者是部门成员进行聚餐活动,以增进人员之间的情感,更有利于工作中的相互合作。

申请聚餐费用的大致流程一般是:由申请人先填写申请单,然后交给领导审查,如果申请批准下来了,领导会通知申请人审批通过,然后申请人去财务核领费用,如果没有核准,领导会通知申请人审批未通过,此事也就此作罢。

不同级别的领导,对于审批的额度是不一样的,比如,项目经理只能审批500元以内的申请;部门经理能审批1000元以内的申请;而总经理可以审核任意额度的申请。

也就是说,当某人提出聚餐费用申请的请求后,该请求会由项目经理、部门经理、总经理之中的某一位领导来进行相应的处理,但是提出申请的人并不知道最终会由谁来处理他的请求,一般申请人是把自己的申请提交给项目经理,或许最后是由总经理来处理他的请求,但是申请人并不知道应该由总经理来处理他的申请请求。

那么该怎样实现这样的功能呢?

23.1.2 不用模式的解决方案

分析上面要实现的功能,主要就是要根据申请费用的多少,然后让不同的领导来进行处理就可以实现了。也就是有点逻辑判断而已。示例代码如下:

8dc59ec04cc14ede92e4f2b175d77f0d

3ffba2b0f7ff4e9ca27a89bea60d9978

7390f0c2d93b4a04b2870deb558c5b0f

022947377e334ff1adc4ba6700fd99f6

写个客户端来测试看看效果。示例代码如下:

19044d1c315b4a68990c4c99fa3a3aca

运行结果如下:

d6412a14179a499ca40fb42643db4bf9

038c098b2fee40548a02b9d6ec2fb338

23.1.3 有何问题

上面的实现很简单,基本上没有什么特别的难度。仔细想想,这么实现有没有问题呢?仔细分析申请聚餐费用的业务功能和目前的实现,主要面临着以下问题。

■ 聚餐费用申请的处理流程是可能会变动的。

比如现在的处理流程是:提交申请给项目经理,看看是否适合由项目经理处理,如果不是→看看是否适合由部门经理处理,如果不是→总经理处理的步骤。今后可能会变化成:直接提交给部门经理,看看是否适合由部门经理处理,如果不是→总经理处理这样的步骤。也就是说,对于聚餐费用申请,要求处理的逻辑步骤是灵活的。

■ 各个处理环节的业务处理也是会变动的。

因为处理流程可能发生变化,也会导致某些步骤具体的业务功能发生变化,比如,原本部门经理审批聚餐费用的时候,只是判断是否批准;现在,部门经理可能在审批聚餐费用的时候,核算本部门的实时成本,这就出现新的业务处理功能了。

采用上面的实现,如果处理的逻辑发生了变化,解决的方法,一个是生成一个子类,覆盖requestToProjectManager方法,然后在里面实现新的处理;另外一个方法就是修改处理申请方法的源代码来实现。要是具体处理环节的业务处理功能发生了变化,那就只好找到相应的处理方法,进行源代码修改了。

总之都不是什么好方法,也就是说,如果出现聚餐费用申请的处理流程变化的情况,或者是出现各个处理环节的功能变化的时候,上面的实现方式是很难灵活地变化来适应新功能的要求的。

把上面的问题抽象一下:客户端发出一个请求,会有很多对象都可以来处理这个请求,而且不同对象的处理逻辑是不一样的。对于客户端而言,无所谓谁来处理,反正有对象处理就可以了。而且在上述处理中,还希望处理流程是可以灵活变动的,而处理请求的对象需要能方便地修改或者是被替换掉,以适应新的业务功能的需要。

请问如何才能实现上述要求?