一、简介
1、定义
解释器模式(Interpreter pattern)是一种行为设计模式,它定义了一个表达式接口和具体的表达式实现类(分为终结符表达式和非终结符表达式)。表达式接口中定义了解释方法,具体的表达式实现类则实现了该解释方法,用于对语法进行解释。
2、解释器模式的结构
解释器模式涉及以下几个角色:
表达式接口(Expression):定义解释器需要实现的接口,通常包含一个解释方法(interpreter)用于解释表达式。
终结符表达式(Terminal Expression):实现了表达式接口的解释方法,用于解释语言中的终结符,例如变量、常量等。
非终结符表达式(Non-Terminal Expression):实现了表达式接口的解释方法,通常由多个终结符表达式组合而成,用于解释语言中的非终结符,例如算数运算符、逻辑运算符等。
环境(Context):包含需要解释的语言的上下文信息,例如变量、常量等。在解释器模式中,环境对象通常作为参数传递给解释器对象。
二、Java实现案例
1、加减乘除实现案例(未引入存储变量的上下文)
/**
* @Description: 表达式接口
* @Date: 2025-01-22 11:28
* @Author: gaoyufei
**/
public interface Expression {
int interpret();
}
/**
* @Description: 数字表达式 终结符表达式角色
* @Date: 2025-01-24 10:26
* @Author: gaoyufei
**/
public class NumberExpression implements Expression {
private int num;
public NumberExpression(int num) {
this.num = num;
}
@Override
public int interpret() {
return this.num;
}
@Override
public String toString() {
return num + "";
}
}
/**
* @Description: 加法表达式 非终结符表达式角色
* @Date: 2025-01-24 10:28
* @Author: gaoyufei
**/
public class PlusExpression implements Expression {
private Expression left;
private Expression right;
public PlusExpression(Expression left, Expression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret() {
return left.interpret() + right.interpret();
}
@Override
public String toString() {
return left + "+" + right + "=" + interpret();
}
}
/**
* @Description: 减法表达式 非终结符表达式角色
* @Date: 2025-01-24 10:28
* @Author: gaoyufei
**/
public class SubtractExpression implements Expression {
private Expression left;
private Expression right;
public SubtractExpression(Expression left, Expression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret() {
return left.interpret() - right.interpret();
}
@Override
public String toString() {
return left + "-" + right + "=" + interpret();
}
}
/**
* @Description: 乘法表达式 非终结符表达式角色
* @Date: 2025-01-24 10:28
* @Author: gaoyufei
**/
public class MultipliedExpression implements Expression {
private Expression left;
private Expression right;
public MultipliedExpression(Expression left, Expression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret() {
return left.interpret() * right.interpret();
}
@Override
public String toString() {
return left + "*" + right + "=" + interpret();
}
}
/**
* @Description: 除法表达式 非终结符表达式角色
* @Date: 2025-01-24 10:28
* @Author: gaoyufei
**/
public class DividedExpression implements Expression {
private Expression left;
private Expression right;
public DividedExpression(Expression left, Expression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret() {
return left.interpret() / right.interpret();
}
@Override
public String toString() {
return left + "/" + right + "=" + interpret();
}
}
/**
* @Description: 客户端
* @Date: 2025-01-24 10:39
* @Author: gaoyufei
**/
public class Client {
public static void main(String[] args) {
Expression expressionPlus = new PlusExpression(new NumberExpression(1), new NumberExpression(3));
System.out.println(expressionPlus.toString());
Expression expressionSub = new SubtractExpression(new NumberExpression(2), new NumberExpression(1));
System.out.println(expressionSub.toString());
Expression expressionMult = new MultipliedExpression(new NumberExpression(expressionPlus.interpret()), new NumberExpression(expressionSub.interpret()));
System.out.println(expressionMult.toString());
Expression expressionDivid = new DividedExpression(new NumberExpression(expressionPlus.interpret()), new NumberExpression(expressionSub.interpret()));
System.out.println(expressionDivid.toString());
}
}
2、加减乘除实现案例(引入存储变量的上下文)
import java.math.BigDecimal;
/**
* @Description: 表达式接口
* @Date: 2025-01-24 11:07
* @Author: gaoyufei
**/
public interface Expression {
BigDecimal interpret(Context context);
String getValue(Context context);
String getDesc();
}
import java.math.BigDecimal;
/**
* @Description: 终极表达式
* @Date: 2025-01-24 11:13
* @Author: gaoyufei
**/
public class Variable implements Expression{
private String name;
public Variable(String name){
this.name=name;
}
@Override
public BigDecimal interpret(Context context) {
return context.getValue(this);
}
@Override
public String getValue(Context context) {
return context.getValue(this).toString();
}
@Override
public String getDesc() {
return this.name;
}
}
import java.math.BigDecimal;
/**
* @Description: 加法表达式
* @Date: 2025-01-24 11:19
* @Author: gaoyufei
**/
public class AddExpression implements Expression{
private Expression left;
private Expression right;
public AddExpression(Expression left, Expression right){
this.left=left;
this.right=right;
}
@Override
public BigDecimal interpret(Context context) {
return left.interpret(context).add(right.interpret(context));
}
@Override
public String getValue(Context context) {
return "("+left.getValue(context)+"+"+right.getValue(context)+")";
}
@Override
public String getDesc() {
return "("+left.getDesc()+"+"+right.getDesc()+")";
}
}
import java.math.BigDecimal;
/**
* @Description: 减法表达式
* @Date: 2025-01-24 11:19
* @Author: gaoyufei
**/
public class SubExpression implements Expression{
private Expression left;
private Expression right;
public SubExpression(Expression left, Expression right){
this.left=left;
this.right=right;
}
@Override
public BigDecimal interpret(Context context) {
return left.interpret(context).subtract(right.interpret(context));
}
@Override
public String getValue(Context context) {
return "("+left.getValue(context)+"-"+right.getValue(context)+")";
}
@Override
public String getDesc() {
return "("+left.getDesc()+"-"+right.getDesc()+")";
}
}
import java.math.BigDecimal;
/**
* @Description: 乘法表达式
* @Date: 2025-02-07 11:10
* @Author: gaoyufei
**/
public class MultipliedExpression implements Expression{
private Expression left;
private Expression right;
public MultipliedExpression(Expression left,Expression right){
this.left=left;
this.right=right;
}
@Override
public BigDecimal interpret(Context context) {
return left.interpret(context).multiply(right.interpret(context));
}
@Override
public String getValue(Context context) {
return left.getValue(context)+"*"+right.getValue(context);
}
@Override
public String getDesc() {
return left.getDesc()+"*"+right.getDesc();
}
}
import java.math.BigDecimal;
/**
* @Description: 除法表达式
* @Date: 2025-02-07 11:14
* @Author: gaoyufei
**/
public class DividedExpression implements Expression{
private Expression left;
private Expression right;
public DividedExpression(Expression left,Expression right){
this.left=left;
this.right=right;
}
@Override
public BigDecimal interpret(Context context) {
return left.interpret(context).divide(right.interpret(context));
}
@Override
public String getValue(Context context) {
return left.getValue(context)+"/"+right.getValue(context);
}
@Override
public String getDesc() {
return left.getDesc()+"/"+right.getDesc();
}
}
import java.math.BigDecimal;
/**
* @Description: 客户端
* @Date: 2025-02-07 10:55
* @Author: gaoyufei
**/
public class Client {
public static void main(String[] args) {
//(x+y)*(z-q)/i=(5+3)*(8-6)/2=8
Context context=new Context();
Variable x= new Variable("x");
Variable y= new Variable("y");
Variable z= new Variable("z");
Variable q= new Variable("q");
Variable i= new Variable("i");
context.add(x,new BigDecimal(5));
context.add(y,new BigDecimal(3));
context.add(z,new BigDecimal(8));
context.add(q,new BigDecimal(6));
context.add(i,new BigDecimal(2));
Expression add=new AddExpression(x,y);
Expression sub=new SubExpression(z,q);
Expression mult=new MultipliedExpression(add,sub);
Expression divi=new DividedExpression(mult,i);
System.out.println(divi.getDesc()+"="+divi.getValue(context)+"="+divi.interpret(context));
}
}