解释器模式

一句话定义:

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

使用场景:

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);
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值