劣质代码产生的根源(2) 编程语言知识不足

本文介绍Java注解的应用,包括页面校验和控制方法调用顺序。通过实例展示如何自定义注解并结合反射进行有效验证。

产生劣质代码的另外一个原因是对编程员的知识掌握的不够充分。
很多特性如果得到正确的利用,会让代码变得更为简练易懂。但是由于对这些特性不够了解或者根本就不知道。只好写出不太好的代码。

本文以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 }

 

 

转载于:https://www.cnblogs.com/stephen-wang/archive/2012/10/26/2740366.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值