设计模式-解释器(译)

276 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第7天,点击查看活动详情

解释器模式是一种行为设计模式,用于为某种语言定义语法表达,并且提供一种解释器来处理语法

解释器模式

最好的解释器模式的例子就是java编译器解释java源代码成字节码,从而可以被JVM理解。Google翻译也是一个解释器模式的例子,它可以翻译任意的语言成其它的语言

解释器模式例子

为了实现解释器模式,我们需要创建一个解释器上线文引擎,来做解释工作

然后我们需要创建不同的表达式实现,来处理不同的功能性的解释

最终我们创建一个客户端来处理从用户端的输入,然后决定用哪一种表达式来生成输出给用户

让我们用一个例子来理解解释器模式,用户有两种输入格式,“<Number> in Binary” or “<Number> in Hexadecimal。我们的解释器输出相应格式,“<Number> in Binary= <Number_Binary_String>” and “<Number> in Hexadecimal= <Number_Binary_String>

首先我么写一个解释器上下文类,来做具体的解释工作

package com.journaldev.design.interpreter;

public class InterpreterContext {

	public String getBinaryFormat(int i){
		return Integer.toBinaryString(i);
	}
	
	public String getHexadecimalFormat(int i){
		return Integer.toHexString(i);
	}
}

接着我们创建不同类型的表达式来使用解释器山下文(Interpreter Context)

package com.journaldev.design.interpreter;

public interface Expression {

	String interpret(InterpreterContext ic);
}

我们有两个表达式的实现,一个是转换为二进制,另一个是转换为十六进制

package com.journaldev.design.interpreter;

public class IntToBinaryExpression implements Expression {

	private int i;
	
	public IntToBinaryExpression(int c){
		this.i=c;
	}
	@Override
	public String interpret(InterpreterContext ic) {
		return ic.getBinaryFormat(this.i);
	}

}
package com.journaldev.design.interpreter;

public class IntToHexExpression implements Expression {

	private int i;
	
	public IntToHexExpression(int c){
		this.i=c;
	}
	
	@Override
	public String interpret(InterpreterContext ic) {
		return ic.getHexadecimalFormat(i);
	}

}

现在我们创一个客户端程序,使用正确的表达式来转换用户的输入,然后构造输出

package com.journaldev.design.interpreter;

public class InterpreterClient {

	public InterpreterContext ic;
	
	public InterpreterClient(InterpreterContext i){
		this.ic=i;
	}
	
	public String interpret(String str){
		Expression exp = null;
		//create rules for expressions
		if(str.contains("Hexadecimal")){
			exp=new IntToHexExpression(Integer.parseInt(str.substring(0,str.indexOf(" "))));
		}else if(str.contains("Binary")){
			exp=new IntToBinaryExpression(Integer.parseInt(str.substring(0,str.indexOf(" "))));
		}else return str;
		
		return exp.interpret(ic);
	}
	
	public static void main(String args[]){
		String str1 = "28 in Binary";
		String str2 = "28 in Hexadecimal";
		
		InterpreterClient ec = new InterpreterClient(new InterpreterContext());
		System.out.println(str1+"= "+ec.interpret(str1));
		System.out.println(str2+"= "+ec.interpret(str2));

	}
}

这个客户程序用一个main方法来测试,运行输出如下

28 in Binary= 11100
28 in Hexadecimal= 1c

解释器类图

interpreter-pattern-java.png

重要点

  1. 当我们需要创建语法表达式树时,可以使用解释器模式
  2. 解释器模式需要大量的错误检查和大量的表达式代码来估算,这会随着语法的复杂变得复杂,变得很难维护和低效
  3. java.util.Pattern 以及 java.text.Format的子类,都是解释器模式在JDK中的运用

原文链接