浅谈Java解释器模式

网友投稿 265 2022-09-22


浅谈Java解释器模式

​ **请注意!请注意!!!**今天讲给大家讲解非常“有用”的设计模式,解释器模式!!!

​ 设计模式有三大种类,一种是创建型模式,一种是结构型模式,最后一种是行为性模式,那么解释器模式属于哪一种呢?带领大家一起来了解学习解释器模式!

​ 本次介绍围绕着以下五点展开。什么是解释器模式?用来做什么?怎么做?有哪些优点?有哪些不足?

​ 解释器模式顾名思义,就是用来定义和解释。

​ 给定一种特定语言,这个语言有特定的文法,解释器可以解释这个语言中的句子含义。即解释器提供一种语言,如java,同时它也提供一种手段去解析java语言写出来的代码。

​ 大家可能也会想到这就是类似编译原理,一个算术表达式要经过词法分析,语法分析,构建语法树啥的;还有正则表达式;SQL解析,编译器等等,其实都是解析式模式的一种实现。

​ 那怎么做?一个是说要有像编译原理中的终结符和非终结符,构建一颗语法树。同时需要有一个环境类,来管理输入和输出。

​ 这里我们举一个例子,输入一个表达式a+b-c+d-e,同时给这5个变量赋值,计算出它的值。那么使用解释器模式要如何实现?

​ 我们为解释器定义一个抽象解释类Expression,所有的流转通过interpreter方法实现。

​ 上http://下文管理输入输出使用一个HashMap去实现。

​ 定义符号解释类SymbolExpression,加法解释类AddExpreesion,减法解释类SubExpression。

类图:

具体代码实现:

public abstract class Expression {

// map中携带了表达式中的变量名(key) 和 对应的值(value)

public abstract int interpreter(Map var);

}

public class VarExpression extends Expression {

// 表达式中对应的变量名

String key;

public VarExpression(String var) {

this.key = var;

}

@Override

public int interpreter(Map var) {

return var.get(key);

}

}

public class SymbolExpression extends Expression {

// +或-符号 左右两边的表达式

Expression var1;

Expression var2;

public SymbolExpression(Expression var1, Expression var2) {

this.var1 = var1;

this.var2 = var2;

}

@Override

public int interpreter(Map var) {

// 实现抽象方法

// 该类不需要用到该方法 默认返回0

return 0;

}

}

public class AddExpression extends SymbolExpression {

public AddExpression(Expression var1, Expression var2) {

super(var1, var2);

}

@Override

public int interpreter(Map var) {

return var1.interpreter(var) + var2.interpreter(var);

}

}

public class SubExpression extends SymbolExpression {

public SubExpression(Expression var1, Expression var2) {

super(var1, var2);

}

@Override

public int interpreter(Map var) {

return var1.interpreter(var) - var2.interpreter(var);

}

}

public class Calculator {

// 表达式

private Expression expression;

// 解析出表达式

public Calculator(String expStr) {

Stack stack = new Stack<>();

Expression left, right = null;

char[] expStrCharArray = expStr.toCharArray();

for(int i = 0; i < expStrCharArray.length; i++) {

switch (expStrCharArray[i]) {

case '+':// 加法运算 获取左边表达式 右边数值

left = stack.pop();

right = new VarExpression(String.valueOf(expStrCharArray[++i]));

stack.push(new AddExpression(left, right));

break;

case '-':// 减法运算 获取左边表达式 右边数值

left = stack.pop();

right = new VarExpression(String.valueOf(expStrCharArray[++i]));

stack.push(new SubExpression(left, right));

break;

default:// 表达式中的变量

stack.push(new VarExpression(String.valueOf(expStrCharArray[i])));

break;

}

}

// 最后会获得被Expression包装起来的一个表达式

this.expression = stack.pop();

}

// 计算结果

public int run(Map var) {

return this.expression.interpreter(var);

}

}

public class Client {

public static void main(String[] args) throws IOException {

String expStr = getExpStr();

Map var = getValue(expStr);

Calculator calculator = new Calculator(expStr);

System.out.println("运算结果:" + expStr + "=" + calculator.run(var));

}

//获得表达式

public static String getExpStr() {

return "a+b-c+d-e";

}

//获得值映射

public static HashMap getValue(String expStr) throws IOException {

HashMap map = new HashMap<>();

for(char ch : expStr.toCharArray()) {

if(ch != '+' && ch != '-' ) {

if(! map.containsKey(String.valueOf(ch))) {

System.out.print("请输入" + String.valueOf(ch) + "的值:");

http://String in = (new BufferedReader(new InputStreamReader(System.in))).readLine();

map.put(String.valueOf(ch), Integer.valueOf(in));

}

}

}

return map;

}

}

结果

/*

请输入a的值:1

请输入b的值:3

请输入c的值:5

请输入d的值:7

请输入e的值:9

运算结果:a+b-c+d-e=-3

*/

​ 或许看代码会有点云里雾里,希望大家能手动敲一遍,或许会对整个过程有更进一步的理解,在编码的同时不断思考,提升自我。

​ 很容易发现解释器模式是属于行为性模式的一种,这种模式更关注对象之间的通信。

​ 解释器模式优点,结构清晰,可拓展性好。但也有缺点,一般用在比较底层场景,平常敲代码可使用的场景比较少,并且解释器模式采用的是递归的方式,当语言比较长,性能不高;同时如果文法比较复杂,也需要更多的相应解释类。

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:VLAN基础及VLAN间路由(vlan间的路由协议)
下一篇:ISIS与OSPF的区别(小白学习的小总结)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~