wuhongyan008 发表于 2013-2-4 22:16:44

用反射和annotation消除“if else”语句

 
在项目过程中,出现了这么一段丑陋的“ifelse”代码,如下:
 
      public List<BreadcrumbVO> getBreadCrumbList(){            ……                     if(A){                  doA();            } else if (B){                  doB();            } else if (C);                                       doC();            } else if (D){                  doD();            } else if (E){                  DoE();            }                      ……                  }  
可以看出,因为条件不同,在这段逻辑代码中出现了大量的“ifelse”语句,这种代码是明显不符合面向对象思想的,是必须要重构的!
这个问题可以用多态来解决!一般是用多态+ Factory模式来解决,具体思路就是:
1. 新建一个接口或者abstract类,定义一个abstract方法,交给子类实现
2. 将每一个if分支中的代码独立出来,作为步骤1中接口或者abstract类的子类,并实现其abstract方法,有多少个if分支,就有多少个子类
3. 新建一个Factory类,用于根据不同判断条件,生成不同子类
4. 在原逻辑方法中使用“父类引用指向子类实例(Factory生成)”。
 
这样业务逻辑比较清楚,可以不用管生成的子类实例具体是什么,代码可扩展性比较强。当有新的判断条件时,只需新增一个子类,并在Factory类中新增该类的生成代码即可。但是这种解决方案还存在一些问题:类太多,不方便维护和管理;“ifelse”依然存在,只是从业务逻辑中转移到Factory类而已
 
于是我想出了另外一个解决方案,可彻底消除”ifelse”语句,不管是在业务逻辑中还是在Factory类中。我的这种解决方案采用了 reflect + annotation + Factory, 具体思路就是:
1. 新建一个annotation类,用于替代“if”分支的判断条件
2. 新建一个Factory方法
3. 将原业务逻辑中if else分支中的代码剥离出来,在Factory类中创建对应的method(我的if else分支中的代码比较简单,要是复杂点的话,可以采用类来实现),在method上添加annotation
4. 在Factory中利用反射和annotation根据不同的条件调用相对应的处理函数
具体代码如下:
 
      public String findString(){            String viewId = FacesContext.getCurrentInstance().getViewRoot().getViewId();             for (Method m : this.getClass().getDeclaredMethods()){                  if (m.getAnnotation(MethodConditions.class) != null){                        MethodConditions condition = m.getAnnotation(MethodConditions.class);                        if (parameters.get(condition.id()) != null                              && viewId.equalsIgnoreCase(condition.viewId())){                                                   try {…                        } catch (Exception e) {                                                               }                                              }                  }            }            …                }         @MethodConditions(id = "a", viewId = "/a/a.xhtml")      private String doA(){            …                      }       @MethodConditions(id = "b", viewId = "/b/b.xhtml")      private String doB(){            …          }         @MethodConditions(id = "c", viewId = "/c/c.xhtml")      private String doC(){            …      }         @MethodConditions(id = "d", viewId = "/d/d.xhtml")      private String doD(){            …                      }               @MethodConditions(id = "e", viewId = "/e/e.xhtml")      private String doE(){            …                }   import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME)@Target({ElementType.METHOD})public @interface MethodConditions {      String id();      String viewId();}  
 
 
 
页: [1]
查看完整版本: 用反射和annotation消除“if else”语句