生成代码的代码 之 错误代码类生成器
有时候在写代码时,会有很多的重复内容出现。在C/C++这样的语言里,可以通过宏定义来简化这些代码。可是在Java这样没有宏定义的语言里,就会有点麻烦。我们可以通过代码生成器来处理,也就是用一段代码来生成这些代码。
假定我们要写一个类,来封装所有的错误代码和错误消息。也就是要生成类似下面的一个类。其中以静态成员的形式封装所有的错误代码,而以一个Map来封装所有的错误消息。
package com.abc.example;
import java.util.HashMap;
import java.util.Map;
public class ErrorCode {
public static int ERROR_CODE_1 = 1001;
static Map<Integer, String> errormsg;
static {
errormsg = new HashMap<Integer, String>();
errormsg.put(ERROR_CODE_1, "error message 1");
}
public static String getErrorMessage(int code) {
return errormsg.get(code);
}
}
但是,这里可能会有很多种错误代码,每种错误代码都对应有一个错误消息。所以写这个类会有很多的重复代码。所以我们通过一段代码来生成这个类的代码。而这个类其实整体结构是固定的,只是其中的变量名,错误代码和错误消息是会变化的。所以我们可以利用模板库来生成这段代码。
这里笔者基于Node.js进行开发,因此选择了基于Node.js的模板库handlebar (https://github.com/wycats/handlebars.js/). 代码如下
// createerrorcode.js
var handlebars = require("handlebars");
var fs = require("fs");
var errorcodes = require("./errorcodes")
var templatefile = "ErrorCodeTemplate.java";
var source = fs.readFileSync(templatefile, "utf8");
var template = handlebars.compile(source);
var result = template(errorcodes);
fs.writeFile(errorcodes.name + ".java", result, function(e){
if (e) {
console.log("error: " + e);
}
});
// errorcodes.js
var errorcodes = {
"name": "ErrorCodes",
"codes": [
{"name": "ERROR_NAME", "code": 0, "message": "ok"},
]
};
module.exports = errorcodes;
模板如下
//ErrorCodeTemplate.java
package com.example;
import java.util.HashMap;
import java.util.Map;
public class {{name}} {
{{#codes}}
public static int {{name}} = {{code}};
{{/codes}}
static Map<Integer, String> errormsg;
static {
errormsg = new HashMap<Integer, String>();
{{#codes}}
errormsg.put({{name}}, "{{message}}");
{{/codes}}
}
public static String getErrorMessage(int code) {
return errormsg.get(code);
}
}
最终生成的类代码如下
package com.example;
import java.util.HashMap;
import java.util.Map;
public class ErrorCodes {
public static int ERROR_NAME = 0;
static Map<Integer, String> errormsg;
static {
errormsg = new HashMap<Integer, String>();
errormsg.put(ERROR_NAME, "ok");
}
public static String getErrorMessage(int code) {
return errormsg.get(code);
}
}