产生劣质代码的另外一个原因是对编程员的知识掌握的不够充分。
很多特性如果得到正确的利用,会让代码变得更为简练易懂。但是由于对这些特性不够了解或者根本就不知道。只好写出不太好的代码。
本文以Java语言为例,将一些高级特性列出来以飨读者。
1.声明 (Annotation)
在Java5中就开始引入了Annotation概念。这个概念帮助
a. 编译用声明
例如:@Deprecated, @Override
b. 语法检验用声明
例如:@SuppressWarnings
c. 运行时声明
例如:@
d.自定义声明
例一:根据annotation来进行页面校验。
假设一个考试成绩登记页面,登记的成绩不能超过100,为了简化起见,我们用main方法来代替页面输入。
首先定义一个声明
1 import java.lang.annotation.Retention; 2 import java.lang.annotation.RetentionPolicy; 3 4 @Retention(RetentionPolicy.RUNTIME) 5 public @interface Max { 6 int value(); 7 }
然后定义一个Validator,用以检查输入,仅为Max做处理。
1 import java.lang.annotation.Annotation; 2 import java.lang.reflect.Field; 3 4 public class Validator { 5 6 public static boolean validate(Object object) { 7 try { 8 Field[] fields = object.getClass().getDeclaredFields(); 9 for (Field field : fields) { 10 Annotation[] annotations = field.getAnnotations(); 11 for (Annotation a : annotations) { 12 if (a instanceof Max) { 13 if (field.getInt(object) < ((Max) a).value()) 14 return true; 15 } 16 } 17 } 18 } catch (IllegalArgumentException e) { 19 e.printStackTrace(); 20 } catch (IllegalAccessException e) { 21 e.printStackTrace(); 22 } 23 return false; 24 } 25 26 }
考试的数据类
1 public class Exam { 2 3 public Exam(int s) { 4 score = s; 5 } 6 7 @Max(100) 8 public int score; 9 }
登记类以及main方法
1 public class Register { 2 3 public static void main(String[] args) { 4 Register reg = new Register(); 5 reg.register(new Exam(125)); 6 7 } 8 9 public void register(Exam exam) { 10 if (Validator.validate(exam)) { 11 System.out.println("success"); 12 } else { 13 System.out.println("out of range."); 14 } 15 } 16 }
采用这种方法设计之后可以将所有的校验集中在一起做,并且生成错误列表——这部分内容上述例子没有实现,留给读者自己尝试。
另外,这种做法,对于每种数据的校验限制都直接明确的定义在属性上方,可以方便修改。
例二:根据annotation控制调用顺序。
定义一个声明:Before
1 import java.lang.annotation.Retention; 2 import java.lang.annotation.RetentionPolicy; 3 4 @Retention(RetentionPolicy.RUNTIME) 5 public @interface Before { 6 7 }
下面是Before的使用方法
1 public class Register extends Controller { 2 3 Session session; 4 5 public void register(Exam exam) { 6 if (Validator.validate(exam)) { 7 System.out.println("success"); 8 } else { 9 System.out.println("out of range."); 10 } 11 } 12 13 @Before 14 public boolean checkTimeOut() { 15 if (session == null) { 16 return false; 17 } 18 return true; 19 } 20 }
下面是调用代码:
1 import java.lang.annotation.Annotation; 2 import java.lang.reflect.InvocationTargetException; 3 import java.lang.reflect.Method; 4 5 public class Controller { 6 7 public void execute(Object obj, String methodName, Object... parameters) { 8 9 try { 10 Method[] methods = obj.getClass().getDeclaredMethods(); 11 for (Method m : methods) { 12 for (Annotation a : m.getAnnotations()) { 13 if (a instanceof Before) { 14 m.invoke(obj); 15 } 16 } 17 } 18 19 Class[] classes = new Class[parameters.length]; 20 for (int i = 0; i < classes.length; i++) { 21 classes[i] = parameters[i].getClass(); 22 } 23 24 Method method = obj.getClass().getDeclaredMethod(methodName, 25 classes); 26 27 method.invoke(obj, parameters); 28 29 } catch (IllegalArgumentException e) { 30 e.printStackTrace(); 31 } catch (IllegalAccessException e) { 32 e.printStackTrace(); 33 } catch (InvocationTargetException e) { 34 e.printStackTrace(); 35 } catch (SecurityException e) { 36 e.printStackTrace(); 37 } catch (NoSuchMethodException e) { 38 e.printStackTrace(); 39 } 40 } 41 42 /** 43 * @param args 44 */ 45 public static void main(String[] args) { 46 47 Register reg = new Register(); 48 Exam exam = new Exam(125); 49 Controller controller = new Controller(); 50 controller.execute(reg, "register", exam); 51 } 52 53 }