设计模式(23)解释器模式

一、介绍:

1、定义:解释器(Interpreter)模式是一种对象的行为模式。给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。

2、组成结构:


(1)AbstractExpression(抽象表达式):约定解释器的解释操作,主要是一个interpret()方法。这个接口作为抽象语法树中所有节点(即终结符表达式和非终结符表达式)所共享

public abstract class AbstractExpression {
    public abstract void interpret(Context context);
}

(2) TerminalExpression(终结符表达式):用来实现文法中和终结符相关的解释操作,不再包含其它的解释器,如果用组合模式来构建抽象语法树的话,就相当于组合模式中的叶子对象,可以有多种终结符解释器。

public class TerminalExpression extends AbstractExpression{

    @Override
    public void interpret(Context context) {
        System.out.println("终结符解释器");
    }
}

(3)NonterminalExpression(非终结表达式):用来实现文法中和非终结符相关的解释操作,通常一个解释器对应一个语法规则,可以包含其它的解释器,如果用组合模式来构建抽象语法树的话,就相当于组合模式中的组合对象,可以有多种非终结符解释器。公式R=R1+R2中,R1、R2为终结符表达式,+为非终结表达式(其后需要跟随一个终结符表达式)。

public class NonterminalExpression extends AbstractExpression{

    @Override
    public void interpret(Context context) {
        System.out.println("非终结符解释器");
    }
}

(4) Context类(包含解释器之外的一些全局信息):也称“上下文”,常用HashMap来代替,通常包含解释器之外的一些全局信息(解释器需要的数据,或是公共的功能)。

public class Context {
    private String input;
    private String output;

    //Get、Set方法省略
}

客户端,构建文法表示的抽象语法树(Abstract Syntax Tree),该抽象语法树由终结符表达式和非终结符表达式的实例装配而成),并调用解释操作interpret()方法。 

Context context = new Context();
        List<AbstractExpression> list = new ArrayList<AbstractExpression>();
        list.add(new TerminalExpression());
        list.add(new NonterminalExpression());
        list.add(new TerminalExpression());
        list.add(new NonterminalExpression());
        for (AbstractExpression abstractExpression : list) {
            abstractExpression.interpret(context);
        }

3、适用场景:解释器模式似乎使用面不是很广,它描述了一个语言解释器是如何构成的,在实际应用中,我们可能很少去构造一个语言的文法。建议在以下情况中选用解释器模式: 当有一个语言需要解释执行,并且可以将语言中的句子表示为一个抽象语法树的时候,可以考虑使用解释器模式。  

二、demo:

1、加减法计算器:

//抽象表达式
public interface AbstractExpression {
     int interprete(HashMap<String, Integer> var);
}


//终结符表达式
public class VarExpression  implements AbstractExpression {

    private String key;

    public VarExpression(String key) {
        this.key = key;
    }

    public int interprete(HashMap<String, Integer> var) {
        return (Integer) var.get(this.key);
    }
}



//加法符号  非终结表达式
public class AddExpression implements AbstractExpression{

    private AbstractExpression left;
    private AbstractExpression right;

    public AddExpression(AbstractExpression left, AbstractExpression right) {
        this.left = left;
        this.right = right;
    }

    // 把左右两个表达式运算的结果加起来
    public int interprete(HashMap<String, Integer> var) {
        return this.left.interprete(var) + this.right.interprete(var);
    }
}



//减法符号  非终结表达式
public class SubExpression implements AbstractExpression{

    private AbstractExpression left;
    private AbstractExpression right;

    public SubExpression(AbstractExpression left, AbstractExpression right) {
        this.left = left;
        this.right = right;
    }

    // 把左右两个表达式运算的结果加起来
    public int interprete(HashMap<String, Integer> var) {
        return this.left.interprete(var) - this.right.interprete(var);
    }
}
//封装计算器类
public class Calculator {

    private AbstractExpression expression;

    public Calculator(String expStr) {
        // 定义一个堆栈,安排运算的先后顺序
        Stack<AbstractExpression> stack = new Stack<AbstractExpression>();
        // 表达式拆分为字符数组
        char[] charArray = expStr.toCharArray();
        // 运算
        AbstractExpression left = null;
        AbstractExpression right = null;
        for (int i = 0; i < charArray.length; i++) {
            switch (charArray[i]) {
                case '+':
                    left = stack.pop();
                    right = new VarExpression(String.valueOf(charArray[++i]));
                    stack.push(new AddExpression(left, right));
                    break;

                case '-':
                    left = stack.pop();
                    right = new VarExpression(String.valueOf(charArray[++i]));
                    stack.push(new SubExpression(left, right));
                    break;
                default: // 公式中的变量
                    stack.push(new VarExpression(String.valueOf(charArray[i])));
            }
        }
        // 把运算结果抛出来
        this.expression = stack.pop();
    }

    // 计算结果
    public int calculate(HashMap<String, Integer> var) {
        return this.expression.interprete(var);
    }
}


//客户端
public static void main(String args[]){
        // 构造运算元素的值列表
        HashMap<String, Integer> ctx = new HashMap<String, Integer>();
        ctx.put("a", 10);
        ctx.put("b", 20);
        ctx.put("c", 30);
        ctx.put("d", 40);
        ctx.put("e", 50);
        ctx.put("f", 60);
        Calculator calc = new Calculator("a+b-c");
        int result = calc.calculate(ctx);
        System.out.println("Result of a+b-c: " + result);
        calc = new Calculator("d-a-b+c");
        result = calc.calculate(ctx);
        System.out.println("Result of d-a-b+c: " + result);
    }


输出:
Result of a+b-c: 0
Result of d-a-b+c: 40

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

w_t_y_y

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

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

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

打赏作者

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

抵扣说明:

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

余额充值