收藏私塾在线
 

欢迎您来到私塾在线网!   

请登录! 

免费注册 


javasscc的笔记
状态: 离线
人气:499301
访问用户量:1134
笔记经验:1858
总积分:1958
级别:普通会员
搜索本笔记
ta的交流分类
ta的交流主题贴(196)
ta的所有交流贴(200)
ta的全部笔记
全部笔记(98)
未分类笔记(0)
研磨设计模式(94)
课程问题(0)
设计模式综合项目实战(4)
存档
2013-05(4)
2012-08(39)
2012-07(55)

2012-08-24 09:50:21
研磨设计模式 之 职责链模式(Chain of Responsibility)1——跟着cc学设计系列
浏览(3006)|评论(0)   交流分类:Java|笔记分类: 研磨设计模式

23.1  场景问题

23.1.1  申请聚餐费用

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

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

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

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

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

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

23.1.2  不用模式的解决方案

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

/**

 * 处理聚餐费用申请的对象

 */

public class FeeRequest {

    /**

     * 提交聚餐费用申请给项目经理

     * @param user 申请人

     * @param fee 申请费用

     * @return 成功或失败的具体通知

     */

    public String requestToProjectManager(String user,double fee){

       String str = "";

       if(fee < 500){

           //项目经理的权限比较小,只能在500以内

           str = this.projectHandle(user, fee);

       }else if(fee < 1000){

           //部门经理的权限只能在1000以内

           str = this.depManagerHandle(user, fee);

       }else if(fee >= 1000){

           //总经理的权限很大,只要请求到了这里,他都可以处理

           str = this.generalManagerHandle(user, fee);

       }

       return str;

    }

    /**

     * 项目经理审批费用申请,参数、返回值和上面是一样的,省略了

     */

    private String projectHandle(String user, double fee) {

       String str = "";

       //为了测试,简单点,只同意小李的

       if("小李".equals(user)){

           str = "项目经理同意"+user+"聚餐费用"+fee+"元的请求";

       }else{

           //其它人一律不同意

           str = "项目经理不同意"+user+"聚餐费用"+fee+"元的请求";

       }

       return str;

    }

    /**

     * 部门经理审批费用申请,参数、返回值和上面是一样的,省略了

     */

    private String depManagerHandle(String user, double fee) {

       String str = "";

       //为了测试,简单点,只同意小李申请的

       if("小李".equals(user)){

           str = "部门经理同意"+user+"聚餐费用"+fee+"元的请求";

       }else{

           //其它人一律不同意

           str= "部门经理不同意"+user+"聚餐费用"+fee+"元的请求";

       }

       return str;

    }

    /**

     * 总经理审批费用申请,参数、返回值和上面是一样的,省略了

     */

    private String generalManagerHandle(String user, double fee) {

       String str = "";

      

       //为了测试,简单点,只同意小李的

       if("小李".equals(user)){

           str = "总经理同意"+user+"聚餐费用"+fee+"元的请求";

       }else{

           //其它人一律不同意

           str = "总经理不同意"+user+"聚餐费用"+fee+"元的请求";

       }

       return str;

    }

}

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

public class Client {

    public static void main(String[] args) {

       FeeRequest request = new FeeRequest();

      

       //开始测试

       String ret1 = request.requestToProjectManager("小李", 300);

       System.out.println("the ret="+ret1);     

       String ret2 = request.requestToProjectManager("小张", 300);

       System.out.println("the ret="+ret2);

      

       String ret3 = request.requestToProjectManager("小李", 600);

       System.out.println("the ret="+ret3);     

       String ret4 = request.requestToProjectManager("小张", 600);

       System.out.println("the ret="+ret4);

      

       String ret5 = request.requestToProjectManager("小李", 1200);

       System.out.println("the ret="+ret5);     

       String ret6 = request.requestToProjectManager("小张", 1200);

       System.out.println("the ret="+ret6);

    }

}

运行结果如下:

the ret1=项目经理同意小李聚餐费用300.0元的请求

the ret2=项目经理不同意小张聚餐费用300.0元的请求

the ret3=部门经理同意小李聚餐费用600.0元的请求

the ret4=部门经理不同意小张聚餐费用600.0元的请求

the ret5=总经理同意小李聚餐费用1200.0元的请求

the ret6=总经理不同意小张聚餐费用1200.0元的请求

23.1.3  有何问题

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

  • 聚餐费用申请的处理流程是可能会变动的。
        比如现在的处理流程是:提交申请给项目经理,看看是否适合由项目经理处理,如果不是à看看是否适合由部门经理处理,如果不是à总经理处理的步骤。今后可能会变化成:直接提交给部门经理,看看是否适合由部门经理处理,如果不是à总经理处理这样的步骤。也就是说,对于聚餐费用申请,要求处理的逻辑步骤是灵活的。
  • 各个处理环节的业务处理也是会变动的。
        因为处理流程可能发生变化,也会导致某些步骤的具体的业务功能发生变化,比如:原本部门经理审批聚餐费用的时候,只是判断是否批准;现在,部门经理可能在审批聚餐费用的时候,核算本部门的实时成本,这就出现新的业务处理功能了。

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

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

       把上面的问题抽象一下:客户端发出一个请求,会有很多对象都可以来处理这个请求,而且不同对象的处理逻辑是不一样的。对于客户端而言,无所谓谁来处理,反正有对象处理就可以了。

       而且在上述处理中,还希望处理流程是可以灵活变动的,而处理请求的对象需要能方便的修改或者是被替换掉,以适应新的业务功能的需要。

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

 


---------------------------------------------------------------------------

私塾在线学习网原创内容  跟着cc学设计系列 之 研磨设计模式

研磨设计讨论群【252780326】

原创内容,转载请注明出处【http://sishuok.com/forum/blogPost/list/0/5813.html

---------------------------------------------------------------------------

相关笔记推荐
精品视频课程推荐

研磨设计模式——跟着cc学设计系列视频教程
本视频课程是北京Java私塾原创精品书籍《研磨设计模式》一书的配套学习视频,由《研磨设计模式》的第一作者CC录制 课程目标:全面、系统的掌握GoF设计模式的知识,达到可以在实际项目开发中运用的能力 技术要点:如何实现可配置、如何实现缓存以及缓存的管理、如何实现用缓存来控制多实例的创建、如何实现参数化工厂、 如何实现可扩展工厂、如何实现原型管理器、如何实现Java的静态代理和动态代理、如何实现多线程处理队列请求、 如何实现命令的参数化配置、可撤销的操作、宏命令、队列请求和日志请求、如何实现翻页迭代、如何检测环状结构、 如何实现通用的增删改查、如何模拟工作流来处理流程、如何实现简单又通用的XML读取、如何实现模拟AOP的功能......

freevoice(局域网对讲机)——Android4项目实战视频教程
实现通过Wifi来在局域网内相互传递信息和语音通话的功能;学习Service;Broadcast Receiver;SharedPreference;SQLite;语音录制、播放、传输等;网络开发:wifi处理、UDP编程、TCP编程;多种设计模式的应用 等等

软件系统功能设计实战训练视频教程
本课程是《软件系统功能设计实战训练》网络班的全套学习视频,通过6个具体的设计案例,综合应用几乎全部的GoF设计模式,以及多种设计理念和方法。 每个设计案例都各有侧重点,训练的难度会逐步加大,以切实帮助各位学员快速的掌握软件系统设计的方法,提升自己的软件系统设计能力。

Java高级视频教程-理论部分
Java程序设计基础、设计模式基础、框架的基本概念等知识。

《设计模式综合项目实战》——跟着cc学设计系列精品视频教程

浏览(3006)|评论(0)   交流分类:Java|笔记分类: 研磨设计模式

评论(0)
请登录后评论 登录

关于我们 | 联系我们 | 用户协议 | 私塾在线服务协议 | 版权声明 | 隐私保护

版权所有 Copyright(C)2009-2012 私塾在线学习网