背景
随着中国加入wto各国贸易频繁,不同的国度使用的语言不一样,但是在交流过程中很多国家以英文作为交流的对象,而翻译官就是将将两种不同的语言互相翻译,传达各自听得懂的语言,这里翻译,可以通过解释器模式一样来转换。
解释器模式是什么?
解释器模式(Interpreter Pattern),属于行为模式,给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
解释器模式可以干嘛?
通过解释器模式,可以给特定的字符定义解释的语言,通过解释后的语言进行解释成最终想要的结果。对于一些固定的语法沟通成一个解释的句子的解释器,比如 - * / = 这种计算中常用到的。
优点:
易拓展:容易拓展各类角色,并且比较灵活增减;
缺点:
效率低:需要通过解析成最终文本,所以计算量较大,效率比较低;
维护成本高:对于复杂的文法维护成本相当高;
角色:
抽象解释器(AbstractExpression/Expression):抽象表达式。声明一个抽象的解释操作,该接口为抽象语法树中所有的节点共享。
终结符表达式(TerminalExpression):终结符表达式。实现与文法中的终结符相关的解释操作。实现抽象表达式中所要求的方法。文法中每一个终结符都有一个具体的终结表达式与之相对应。
非终结符表达式(NonterminalExpression):非终结符表达式。为文法中的非终结符相关的解释操作。
环境角色(Context):环境类。包含解释器之外一些全局信息。
个人理解:
解释器就比如像讲的粤语转成普通话,而这个转换器就似于解释器,其中里面涉及语法和发音就是文本,具体的转就是语法问题;
解释器模式类图
源码下载:https://gitee.com/hong99/design-model/issues/I1IMES
实现代码
代码语言:javascript复制/**
* @Auther: csh
* @Date: 2020/6/8 11:42
* @Description:抽象解释器
*/
public interface Expression {
/**
*
* 功能描述:解释器接口
*
* @param:
* @return:
* @auther: csh
* @date: 2020/6/8 11:55
*/
public String interpret();
}
代码语言:javascript复制/**
* @Auther: csh
* @Date: 2020/6/8 14:22
* @Description:终结符表达式
*/
public class TerminalExpression implements Expression {
private String context;
public TerminalExpression(String context) {
this.context = context;
}
public String getContext() {
return context;
}
public void setContext(String context) {
this.context = context;
}
@Override
public String interpret() {
return context;
}
}
代码语言:javascript复制/**
* @Auther: csh
* @Date: 2020/6/8 11:56
* @Description:非终结符表达式
*/
public class ChineseExpression implements Expression {
private Expression expression;
public ChineseExpression(Expression expression) {
this.expression = expression;
}
@Override
public String interpret() {
String interpret = expression.interpret();
if(interpret.contains("chinese")){
return "中文";
}
return null;
}
}
代码语言:javascript复制/**
* @Auther: csh
* @Date: 2020/6/8 14:12
* @Description:非终结符表达式
*/
public class EnglishExpression implements Expression {
private Expression expression;
public EnglishExpression(Expression expression) {
this.expression = expression;
}
@Override
public String interpret() {
String interpret = expression.interpret();
if(interpret.contains("english")){
return "英文";
}
return null;
}
}
代码语言:javascript复制/**
* @Auther: csh
* @Date: 2020/6/8 15:01
* @Description:解释器工具
*/
public class LanguageUtil{
private Expression expression;
public LanguageUtil(Expression expression) {
this.expression = expression;
}
public String out(){
return expression.interpret()==null?"无法解释":expression.interpret();
}
}
代码语言:javascript复制/**
* @Auther: csh
* @Date: 2020/6/8 14:42
* @Description:
*/
public class Client {
public static void main(String[] args) {
String chinese = "chinese";
String test = "test";
String english = "english";
Expression chineseExpression = new TerminalExpression(chinese);
Expression englishExpression = new TerminalExpression(english);
Expression testExpression = new TerminalExpression(test);
System.out.println(new LanguageUtil(new EnglishExpression(englishExpression)).out());
System.out.println(new LanguageUtil(new ChineseExpression(chineseExpression)).out());
System.out.println(new LanguageUtil(new EnglishExpression(testExpression)).out());
}
}
代码语言:javascript复制英文
中文
无法解释
源码下载:https://gitee.com/hong99/design-model/issues/I1IMES最后
解释器模式说实用处不多,而且简单可以非常简单,复杂可以非常复杂,每个人的理解和写法不同,并且找了相关的资料基本每个人都有每个人的理解,但最终呈现出来的结果都不一样。不过本质是一样的无法就是将对象或者文本转通过特定语法转换成你想要的结果,也就是根据你自己定义的规则转换,所以变化多端。当然看了下网上各种大神的文案和分析,发现这个模式在spring el里面用得还是比较好的,还有我们常用的正则表达式基本都是这种模式来呈现的。
用到解释器的框架或场景
java中的表达式引擎
parsii
JEval
JEPLite
expr
Janino
MathEval
Java表达式引擎fel/groovy/expression4j/java脚本引擎的性能对比
JDK中的应用
java.util.Pattern
java.text.Normalizer
java.text.Format