LN项目截止到昨天为止算是彻底的完工了,功能实现方面没有问题,但是这个一星期出来的“早产儿”还是有很多其他问题,比如代码的重复量过高、各个类之间耦合太大。整个系统中虽然用到了分层的思想,但是基本上BLL层的代码是一致的,也就是说如果需求改动(比如增加审核的部门,或者原先的部门审核顺序进行调整)则需要改动整个的BLL层。
现在整个系统的架构如下图所示:
整体上的架构没什么问题,经典的MVC。其实这次做的系统有点四不像,宏观的看是MVC但是具体到Model层我们又走了.Net中的三层架构的老路子,这就导致了每个servlet对应各自的bll,于是就造成了bll层的重复代码太多。
Duplicate Code(重复代码)是代码的坏味道之一(“代码的坏味道”——引用自《重构》)。
于是……
通过对整个LN系统的分析可以看出来这个系统就是一个职责链,首先是用户填写申请信息,然后由各个部门一级一级的进行审批,最终得到通过(或者进行驳回)。尽管和经典的设计模式当中的职责链模式不是一模一样但是不影响我们用职责链模式对系统进行重构。
尝试用职责链模式重构BLL层之后的部分类图如下图:
根据从数据库得来的各个部门的签署意见,将这些意见赋值到实体类中,根据这些意见判断此次申请被那些部门审核过,同时判断审核是否通过。这里简化代码没有涉及DAL以及SqlHelper的代码部分,只将结果进行打印输出,核心代码如下:
public class Chain { public static void main(String arg[]) { //构造各个部门(级别)的类 abstracBll levelone=new levelOne(); abstracBll leveltwo=new levelTwo(); abstracBll levelthree=new levelThree(); //设定各个部门之间的上下级关系 levelone.setManager(leveltwo); leveltwo.setManager(levelthree); //实例化申请类(实例化实体类) entityApplication enApplication=new entityApplication(); enApplication.suggestion1="同意"; enApplication.suggestion2="同意"; enApplication.suggestion3="同意"; //开始由最低级的部门进行判断该申请是否能通过 levelone.apply(enApplication); } } //抽象的B层类 abstract class abstracBll { protected abstracBll level; //申请的抽象方法 public abstract void apply(entityApplication application); //设定处理此次申请的部门 public void setManager(abstracBll level) { this.level=level; } } //第一级部门所对应的类 class levelOne extends abstracBll { public void apply(entityApplication application) { //判断第一级签署意见是否是同意,如果同意则转入下一级别进行再次判断,否则表示此申请被驳回 if(application.suggestion1=="同意") { System.out.println("第一级同意"); level.apply(application); } else { System.out.println("被第一级驳回!"); } } } //第二级部门所对应的类 class levelTwo extends abstracBll { public void apply(entityApplication application) { if(application.suggestion2=="同意") { System.out.println("第二级同意"); level.apply(application); } else { System.out.println("被第二级驳回!"); } } } //第三级部门所对应的类 class levelThree extends abstracBll { public void apply(entityApplication application) { //判断最后一级是否通过审核,如果通过则表示此审核通过审核,否则表示最后一级没有通过 if(application.suggestion3=="同意") { System.out.println("第三级同意,此审核通过!"); } else { System.out.println("被第三级驳回!"); } } } //申请的实体类 class entityApplication { public String suggestion1; public String suggestion2; public String suggestion3; }
运行结果如下图:
通过重构后如果系统在原来的基础上增加或者调整部门的先后审核顺序则只需要增加bll类或者调整servlet中对bll层的先后调用关系即可。这样的话无需改动整个的B层,而且可以清晰的看到在servlet调用Bll的时候只需要操纵整条职责链中的第一个链即可,不与其他的类发生关系,大大的降低了耦合,提高了代码的复用性,有利于后期的维护(蓝色部分为面向对象的套话)。