劣质代码的产生原因(2)编程语言知识不足 (续)
2.反射 (Reflect)
反射是Java1.5开始出现的特性,反射是通过名称访问类、方法、域、声明的方法。反射方法的出现为Java增加了更多的特性。
a.访问private类型的属性和方法
由于不能访问private的域和方法而无法对相应的功能进行xUnit的测试。但是反射提供了访问private方法的途径,所以,对于private的方法可以进行xUnit测试。
1 public class Testee { 2 3 private void execute(){ 4 System.out.println("method called"); 5 } 6 }
1 import java.lang.reflect.InvocationTargetException; 2 import java.lang.reflect.Method; 3 4 import org.junit.After; 5 import org.junit.Before; 6 import org.junit.Test; 7 8 public class Tester { 9 10 @Before 11 public void setUp() throws Exception { 12 } 13 14 @After 15 public void tearDown() throws Exception { 16 } 17 18 @Test 19 public void test() { 20 Testee testee = new Testee(); 21 try { 22 Method method = Testee.class.getDeclaredMethod("execute", new Class[]{}); 23 method.setAccessible(true); 24 method.invoke(testee, null); 25 } catch (SecurityException e) { 26 e.printStackTrace(); 27 } catch (NoSuchMethodException e) { 28 e.printStackTrace(); 29 } catch (IllegalArgumentException e) { 30 e.printStackTrace(); 31 } catch (IllegalAccessException e) { 32 e.printStackTrace(); 33 } catch (InvocationTargetException e) { 34 e.printStackTrace(); 35 } 36 } 37 38 }
采用了反射机制可以帮助增加测试覆盖率。
b.遍历域、声明或者方法
如前节所述,为了能够实现对域的校验,需要对所有的域进行遍历。前节中的例子已经提到了对于方法、域、声明的遍历方法。
c.根据名称生成不同类型的对象实例
在采用状态模式(State Pattern)或者策略模式(Strategy Pattern)的时候,可以根据名称来进行类的实例的生成。
1 public interface State { 2 public void run(); 3 }
public class AState implements State { @Override public void run() { System.out.println("A state"); } }
1 public class BState implements State { 2 3 @Override 4 public void run() { 5 System.out.println("B state"); 6 } 7 }
1 public class StateFactory { 2 3 public static State create(String name) { 4 5 Class clazz; 6 try { 7 clazz = Class.forName(name +"State"); 8 return (State) clazz.newInstance(); 9 } catch (ClassNotFoundException e) { 10 e.printStackTrace(); 11 } catch (InstantiationException e) { 12 e.printStackTrace(); 13 } catch (IllegalAccessException e) { 14 e.printStackTrace(); 15 } 16 return null; 17 } 18 19 }
1 public class Starter { 2 3 public static void main(String[] args) { 4 String name = "A"; 5 State state = StateFactory.create(name); 6 7 state.run(); 8 } 9 10 }
这样通过名称可以来生成类的实例。上面的例子是状态模式,可以举一反三想到策略模式,比如:计算器可以根据符号的名称来生成计算的类。具体的制作留给读者来尝试。
-----------------------------------------------------------------
现为独立咨询师。为软件企业或者其他企业的软件采购部门提供咨询,帮助改进软件开发流程,员工技术能力提升,以帮助企业在质量成本交货期三方面得到改善。