← 返回首页
设计模式基础教程(二十五)
发表时间:2021-08-27 18:16:29
解释器模式

1. 解释器模式 如果在系统中某一特定类型的问题发生的频率很高,此时可以考虑将这些问题的实例表述为一个语言中的句子,因此可以构建一个解释器,该解释器通过解释这些句子来解决这些问题。

解释器模式描述了如何构成一个简单的语言解释器,主要应用在使用面向对象语言开发的编译器中。

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

解释器模式包含如下角色: - AbstractExpression: 抽象表达式 - TerminalExpression: 终结符表达式 - NonterminalExpression: 非终结符表达式 - Context: 环境类 - Client: 客户类

2.实例

现需要构造一个语言解释器,使得系统可以执行整数间的乘、除和求模运算。如用户输入表达式“3 * 4 / 2 % 4”,输出结果为2。使用解释器模式实现该功能。

项目结构图如下:

设计解释器接口

public interface Node {
    public int interpret();
}

设计抽象符号类

public abstract class SymbolNode implements Node {
    protected Node left;
    protected Node right;

    public SymbolNode(Node left, Node right) {
        super();
        this.left = left;
        this.right = right;
    }
}

设计值节点类

public class ValueNode implements Node {

    private int value;
    public ValueNode(int value) {
        super();
        this.value = value;
    }
    @Override
    public int interpret() {
        // TODO Auto-generated method stub
        return this.value;
    }
}

分别设计乘法、除法和求模节点类

//MulNode.java
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();
    }
}

//DivNode.java
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();
    }
}
//ModNod.java
public class ModNode extends SymbolNode {
    public ModNode(Node left, Node right) {
        super(left, right);
    }
    @Override
    public int interpret() {
        return super.left.interpret() % super.right.interpret();
    }

}

设计计算器类

public class Calculator {

    private String statement;
    private Node node;

    public void build(String statement){
        Node left=null,right=null;

        Stack stack=new Stack();
        String[] statementArr=statement.split(" ");

        int len=statementArr.length;
        for(int i=0;i<len;i++){
            if(statementArr[i].equalsIgnoreCase("*")){
                left=(Node)stack.pop();
                int val=Integer.parseInt(statementArr[++i]);
                right=new ValueNode(val);
                stack.push(new MulNode(left, right));
            }else if(statementArr[i].equalsIgnoreCase("/")){
                left=(Node)stack.pop();
                int val=Integer.parseInt(statementArr[++i]);
                right=new ValueNode(val);
                stack.push(new DivNode(left, right));
            }else if(statementArr[i].equalsIgnoreCase("%")){
                left=(Node)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=(Node)stack.pop();
    }

    public int compute(){
        return node.interpret();
    }
}

测试类

public class TestInterpretDemo01 {

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

运行结果:
3 * 2 * 4 / 6 % 5 = 4