解释器模式就是定义一种语言,并定义这个语言的解释器,解释器能够按照定义好的语法来将这种语言‘翻译’成使用者能理解的语言。
广泛上来讲,
Java是一种定义的语言,JVM就是一种‘解释器’,而计算机就是最终的使用者。我们写一段Java代码,而计算机只认识0101的机器语言,JVM就是将Java代码解释成0101的机器语言让计算机能够理解并运行。
我们还是以我们实验室的实例来说明下这个模式。
最近我们实验室的兽人工厂拿到了老总的一个批示:
复制代码
class LaoZong {
private String order = "MN1n2";
public String getOrder() {
return order;
}
public void setOrder(String order) {
this.order = order;
}
}
class ShouRenFactory {
public void readOrder() {
LaoZong lz = new LaoZong();
System.out.println(lz.getOrder());
}
}
public class Interpreter {
public static void main(String[] args) {
new ShouRenFactory().readOrder();
}
}
复制代码
于是兽人工厂拿到老板的指令就是"MN1n2"。完全不明白要干什么,于是需要找老板秘书来解释下:
复制代码
class ShouRenFactory {
public void readOrder() {
LaoZong lz = new LaoZong();
MiShu ms = new MiShu();
System.out.println(ms.translate(lz.getOrder()));
}
}
class MiShu {
public String translate(String order) {
//Black Box
String realWord = "生产男兽人1个女兽人2个";
return realWord;
}
}
复制代码
现在我们兽人工厂终于知道了老总的命令:"生产男兽人1个女兽人2个", 但是秘书是怎么知道老总的命令的呢,如果兽人工厂也能知道秘书解析的过程,那就不用每次都麻烦秘书来解释了。毕竟秘书是老板用的,而不是兽人工厂用的。
请教秘书解析的方法:
秘书说她先判断每一个字幕或者数组是什么类型的命令,然后再用不同的解释方法解释不同的类型,比如说‘M’就是命令类的,‘Nn’是产品名称类的,数字就是数量类的。
于是兽人工厂就根据秘书的方法实现了自己的解析方式:
复制代码
public class Interpreter {
public static void main(String[] args) {
new ShouRenFactory().readOrder();
}
}
class ShouRenFactory {
private String translate(String order) {
String realOrder = "";
//组装解释器
List expressions = new ArrayList();
expressions.add(new CommandExpression());
expressions.add(new ProductExpression());
expressions.add(new NumberExpression());
//挨个解释老总的命令
String[] codes = order.split("");
for (String code :codes) {
for (Expression expression : expressions) {
if (expression.matches(code)) {
realOrder += expression.excute(code);
break;
}
}
}
return realOrder;
}
public void readOrder() {
LaoZong lz = new LaoZong();
System.out.println(translate(lz.getOrder()));
}
}
abstract class Expression {
protected HashMap map = new HashMap();
private Set getMarkers() {
return map.keySet();
}
public boolean matches(String code) {
return getMarkers().contains(code);
}
abstract public String excute(String code);
}
class CommandExpression extends Expression {
public CommandExpression() {
map.put("M", "创建");
map.put("D", "销毁");
map.put("E", "维修");
}
@Override
public String excute(String code) {
return map.get(code);
}
}
class ProductExpression extends Expression {
public ProductExpression() {
map.put("N", "男兽人");
map.put("n", "女兽人");
}
@Override
public String excute(String code) {
return map.get(code