Java设计模式--解释器模式

本文深入探讨了解释器模式,包括其定义、适用场景、优缺点,并通过一个具体的计算器示例展示了如何使用解释器模式来解析和执行简单的算术表达式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、简介

1.1 模式定义

定义语言的文法,并且建立一个解析器来解释该语言中的句子,这里的“语言”意思是使用规定格式和语法的代码,它是一种类行为型,模式。

1.2 适用场景

1)可以将一个需要解释执行的语言中的句子表示为一个抽象语法树。
2)一些重复出现的问题可以用一种简单的语言来进行表达。
3)文法较为简单。对于复杂的文法,解释器模式中的文法类层次结构将变得很庞大而无法管理,此时最好使用语法分析程序生成器。
4)效率不是关键问题。最高效的解释器通常不是通过直接解释语法分析树实现的,而是需要将它们转换成另外一种形式,使用解释器模式的执行效率并不高。

1.3 优点

1)易于改变和扩展文法。由于在解释器模式中使用类来表示语言的文法规则,因此可以通过继承机制来改变或扩展文法,实现简单语言方便。
2)易于实现文法。在抽象语法树中每个节点类的实现方式都是相似的,这些类的编写都不是很复杂,它们还可以通过一些工具自动生成。
3)增加了新的解释表达式的方法。解释器模式可以让用户较为方便地增加新类型的表达式,增加新的表达式时无须对现有表达式类进行修改,符合“开闭原则”。

1.4 缺点

1)对于复杂文法难以维护。在解释器模式中,每一条规则至少需要定义一个类,因此如果一个语言包含太多文法规则,则可能难以管理和维护,此时可以考虑使用语法分析程序等方式来取代解释器模式。
2)执行效率较低。由于在解释器模式中使用了大量的循环和递归调用,因此在解释较为复杂的句子时期速度很慢。
3)应用场景很有限,在软件开发中很少需要自定义文法规则,因此该语言的使用频率很低,在一般的软件中难以找到其应用实例,导致理解和使用该模式的难度增大。

二、示例

2.1 结构图

在这里插入图片描述

2.2 抽象表达式类Node(抽象节点)
public interface Node {
	
	public int interpret();

}
2.3 终结符表达式类ValueNode(值节点类)
public class ValueNode implements Node{

	private int value;
	
	public ValueNode(int value) {
		this.value = value;
	}
	
	@Override
	public int interpret() {
		return value;
	}

}
2.4 抽象非终结符表达式类SymbolNode(符号节点类)
public abstract class SymbolNode implements Node{

	protected Node left;
	
	protected Node right;

	public SymbolNode(Node left, Node right) {
		this.left = left;
		this.right = right;
	}
	
}
2.5 非终结符表达式类DivNode(除法节点类)
public class DivNode extends SymbolNode{

	public DivNode(Node left, Node right) {
		super(left, right);
	}

	@Override
	public int interpret() {
		return super.left.interpret() / super.right.interpret();
	}

}
2.6 非终结符表达式类ModeNode(求模节点类)
public class ModNode extends SymbolNode{

	public ModNode(Node left, Node right) {
		super(left, right);
	}

	@Override
	public int interpret() {
		return left.interpret() % right.interpret();
	}

}
2.7 非终结符表达式类MulNode(乘法节点类)
public class MulNode extends SymbolNode{

	public MulNode(Node left, Node right) {
		super(left, right);
	}

	@Override
	public int interpret() {
		return super.left.interpret() * super.right.interpret();
	}

}
2.8 解释器封装类Calculator(计算器类)
public class Calculator {
	
	private Node node;
	
	public void build(String statement) {
		Node left = null,right = null;
		Stack<Node> stack = new Stack<>();
		
		String[] statementArr = statement.split(" ");
		for (int i = 0; i < statementArr.length; i++) {
			if (statementArr[i].equalsIgnoreCase("*")) {
				left = stack.pop();
				int val = Integer.parseInt(statementArr[++i]);
				right = new ValueNode(val);
				stack.push(new MulNode(left, right));
			}else if (statementArr[i].equalsIgnoreCase("/")) {
				left = stack.pop();
				int val = Integer.parseInt(statementArr[++i]);
				right = new ValueNode(val);
				stack.push(new DivNode(left, right));
			} else if (statementArr[i].equalsIgnoreCase("%")) {
				left = stack.pop();
				int val = Integer.parseInt(statementArr[++i]);
				right = new ValueNode(val);
				stack.push(new ModNode(left, right));
			} else {
				stack.push(new ValueNode(Integer.parseInt(statementArr[i])));
			}
		}
		this.node = stack.pop();
	}
	
	public int compute() {
		return node.interpret();
	}
	
}
2.9 客户端类Demo类
public class Demo {

	public static void main(String[] args) {
		String statement = "3 * 4 / 2 % 4";
		
		Calculator calculator = new Calculator();
		calculator.build(statement);
		
		int result = calculator.compute();
		
		System.out.println(statement + " = " + result);
		
	}
	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

书香水墨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值