前言:版本兼容,一直是迭代开发头疼的事,最近新版本加上了支持新题型,如果新创建一份问卷包含了新题型,那旧版本客户端就不支持,如果新创建的问卷不包含新题型,那么新旧客户端都支持。这里面我们通过给问卷类型枚举增加自定义注解的方式完成。顺便巩固下枚举与注解。
一、枚举
1.在创建枚举类的时候,该类已继承java.lang.Enum类,所以自定义枚举类无法继承别的类,但可以实现接口。
public interface Behaviour {
void print();
String getInfo();
}
public enum Color implements Behaviour{
RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);
// 成员变量
private String name;
private int index;
// 构造方法
private Color(String name, int index) {
this.name = name;
this.index = index;
}
//接口方法
@Override
public String getInfo() {
return this.name;
}
//接口方法
@Override
public void print() {
System.out.println(this.index+":"+this.name);
}
}
2.枚举类的构造方法使用private,如果可以构造枚举值,那枚举类的存在价值就没了.
3.枚举值对应的是枚举类的Field(属性),可以通过name()方法获取值本身的属性名。
4.使用枚举直观可读性强,但是相对的,存取的时候需要转化,在使用hibernate的时候,需要自定义一个新的映射类型。传送门:
http://bbs.csdn.net/topics/350033653
二、注解
1.定义一个注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface VersionSupport {
public String value() default "";
public int id();
}
2.javaSE5 标准注解@Override @Deprecated @SuppressWarnings
3.新的注解创建:@Target注解应用的地方 @Retention注解保存的级别 @Document 注解包含在javaDoc中 @Inherited子类允许继承父类中的注解
4.从原理上讲,注解处理就是通过反射机制获取被检查方法(属性.类)上的注解信息,然后根据注解元素的值进行特定的处理。在实例中将详细看到。
三、实例
1.添加新题型前的模型
public class Survey {
//问卷支持版本
private String versionSupport;
private List<Question> questions;
}
public class Question {
private QuestionType questionType;
private String content;
}
public enum QuestionType {
RADIT(1,"单选题"),
CHECK_BOX(2,"多选题");
private int key;
private String value;
private QuestionType(int key, String value){
this.key = key;
this.value = value;
}
}
2.现在增加一个新的题型(填空题),那么老的客户端对包含新题型的问卷肯定不支持,为了解决这个问题,可以在Survey类中增加一个新字段标记当前问卷支持的版本。这样就可以通过比对客户端传来的版本信息与问卷支持的版本信息来解决问题。那么如何获取问卷支持的版本呢呢?注解的作用来了:
/**
* 版本支持注解
* @author 飞翔的小马甲
* @since 2014年9月11日 下午10:12:34
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface VersionSupport {
public String value();
}
public enum QuestionType {
RADIT(1,"单选题"),
@VersionSupport("1.1")
CHECK_BOX(2,"多选题"),
@VersionSupport("1.2")
TEXT(3,"填空题");
private int key;
private String value;
private QuestionType(int key, String value){
this.key = key;
this.value = value;
}
}
3.survey新增一个方法获取当前支持的版本(注解解释器)问卷的questions初始化好以后,调用该方法。
/**
* 问卷类
*
* @author 飞翔的小马甲
* @since 2014年9月11日 下午10:36:16
*/
public class Survey {
//问卷支持版本
private String versionSupport;
private List<Question> questions;
public String getVersionSupport() {
return versionSupport;
}
public void setVersionSupport(String versionSupport) {
this.versionSupport = versionSupport;
}
public List<Question> getQuestions() {
return questions;
}
public void setQuestions(List<Question> questions) {
this.questions = questions;
}
public void initVersionSupport() throws Exception {
float vs = 0.0f;
for (Question question : questions) {
Field field = QuestionType.class.getField(question
.getQuestionType().name());
VersionSupport support = field.getAnnotation(VersionSupport.class);
if(support == null){
continue;
}else{
vs = Math.max(vs, Float.parseFloat(support.value()));
}
}
versionSupport = String.valueOf(vs);
}
@Override
public String toString() {
return "Survey [versionSupport=" + versionSupport + ", questions="
+ questions + "]";
}
}
4.开动测试,一切ok
/**
*
* @author XieFeixiang
* @since
* @version 2014年9月12日 t上午11:22:08
*/
public class Client {
public static void main(String[] args) {
List<Question> questions = new ArrayList<Question>();
questions.add(new Question(QuestionType.CHECK_BOX, "题目一"));
questions.add(new Question(QuestionType.TEXT, "题目二"));
questions.add(new Question(QuestionType.RADIT, "题目三"));
Survey survey = new Survey();
survey.setQuestions(questions);
try {
survey.initVersionSupport();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(survey);
}
}
5.输出结果
Survey [versionSupport=1.2, questions=[Question [questionType=CHECK_BOX, content=题目一], Question [questionType=TEXT, content=题目二], Question [questionType=RADIT, content=题目三]]]
五、总结
这里只是对注解的简单应用,接下来会参考spring,hibernate等框架上注解解释器的编写。或许会有更大的收货。