解释器模式

来源:互联网 发布:我国的有限元软件 编辑:程序博客网 时间:2024/06/10 16:03

一句话定义:

定义一个解释器,将固定格式的文本固定解释,来解释对应的语句。

使用场景:

1. 特定问题高频发生,将该领域的问题转化为对应的语句2. 简单语言需要解释执行,可表示为抽象语法树(简单的加减运算)

实现要点:

1. 构件语法树,定义终结符与非终结符。2. 构件环境类,包含解释器之外的一些全局信息,一般是 HashMap。3. 将复杂的问题简单化、模块化、分离实现、解释执行,方便进行扩展

情景假设:

创建一个进行简单顺序的加减法计算器,进行简单运算。

实现步骤:

1. 创建抽象解释器,提取所有解释器的共性
/** * Created by ffengz. * * 抽象算术运算解析器 * 提取所有解析器的共性 */public abstract class Expression {    /**     * 抽象的 解析方法     * context 这里没有用处  解释器之外的全局信息     * @return 解析获得的值     */    public abstract int interpret(int context);}
2. 创建数字解释器(终结符表达式)实现数字解析,和运算符号解释器(非终结符表达式)
/** * Created by ffengz. * * 数字解释器  只解析数字 */public class NumExpression extends Expression {    // 待解析的 数字    private int num;    public NumExpression(int num) {        this.num = num;    }    @Override    public int interpret(int context) {        return num;    }}
/** * Created by ffengz. * * 符号抽象解释器 * 提取运算符号解释器的共性 */public abstract class OperatorExpression extends Expression {    // 运算需要的数字解释器    protected Expression num1,num2;    public OperatorExpression(Expression num1, Expression num2) {        this.num1 = num1;        this.num2 = num2;    }}
3. 创建具体的加减法解释器,实现加减法解析
/** * Created by ffengz. * * 加法符号解释器 "+" */public class AddOperatorExpression extends OperatorExpression {    public AddOperatorExpression(Expression num1, Expression num2) {        super(num1, num2);    }    @Override    public int interpret(int context) {        // 分别调用解释器进行解释        return num1.interpret(context) + num2.interpret(context);    }}
/** * Created by ffengz.. * * 减法符号解释器 "-" */public class SubOperatorExpression extends OperatorExpression {    public SubOperatorExpression(Expression num1, Expression num2) {        super(num1, num2);    }    @Override    public int interpret(int context) {        return num1.interpret(context) - num2.interpret(context);    }}
4. 构建计算器
    // 声明计算器栈  保存所有运算信息    private Stack<Expression> mCalculator = new Stack<>();    /**     * 计算方法     * context 计算表达式     */    private int calculator(@NonNull String context) {        // 运算符号两边的数字        Expression numExp1, numExp2;        // 分割表达式的字符串        String[] elements = context.split(" ");        // 构造运算        for (int i = 0; i < elements.length; i++) {            switch (elements[i].charAt(0)) {                case '+': // 为 加法运算                    // 弹出左侧的数字解释器                    numExp1 = mCalculator.pop();                    // 构造下一个数字解释器  同时跳过下一个数字的解析                    numExp2 = new NumExpression(Integer.valueOf(elements[++i]));                    // 构造加法运算解释器 并压栈                    AddOperatorExpression item1 = new AddOperatorExpression(numExp1, numExp2);                    mCalculator.push(item1);                    break;                case '-': // 为 减法运算                    // 弹出左侧的数字解释器                    numExp1 = mCalculator.pop();                    // 构造下一个数字解释器  同时跳过下一个数字的解析                    numExp2 = new NumExpression(Integer.valueOf(elements[++i]));                    // 构造加法运算解释器 并压栈                    SubOperatorExpression item = new SubOperatorExpression(numExp1, numExp2);                    mCalculator.push(item);                    break;                default:                    NumExpression numExp = new NumExpression(Integer.valueOf(elements[i]));                    // 将数字解释器压栈                    mCalculator.push(numExp);                    break;            }        }        // 进行计算        return mCalculator.pop().interpret(0);    }
5. 结果验证
        // 解释器模式        int result = calculator("1 + 2 + 3 - 4 + 1");        Log.i("info", "onCreate: ==++  1 + 2 + 3 - 4 + 1 运算结果" + result);
0 0
原创粉丝点击