JAVA设计模式第七章:解释器模式

JAVA设计模式第七章:解释器模式,第1张

解释器模式


解释器模式属于行为型模式
是按照一定的语义进行解释的方案,在日常编码中使用较少
在java中expression4J spring的SpEL表达式

代码实现

用解释器模式实现对一个简单的加减法计算的解析

  1. Context 解释器上下文
  2. Expression 解释器接口
  3. 非终结符表达式: 通常由其它表达式组成;
  4. 终结符表达式: 一般为取值表达式,为递归树的叶子节点
/**
 * 上下文
 *
 * @author cans
 * @date 2022/5/14
 **/
public class Context {

    private final Map<String, Integer> params = new HashMap<>();

    public void put(String key, int value) {
        params.put(key, value);
    }

    public int getParam(String key) {
        return this.params.get(key);
    }

}

/**
 * 非终结表达式
 *
 * @author cans
 * @date 2022/5/14
 **/
public class AddExpression implements Expression {

    private final Expression left;
    private final Expression right;

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

    @Override
    public int interpret(Context context) {
        return left.interpret(context) + right.interpret(context);
    }
}
/**
 * 非终结表达式 减法
 *
 * @author cans
 * @date 2022/5/14
 **/
public class SubExpression implements Expression {
    private final Expression left;
    private final Expression right;

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

    @Override
    public int interpret(Context context) {
        return left.interpret(context) - right.interpret(context);
    }
}
/**
 * 终结符表达式
 *
 * @author cans
 * @date 2022/5/14
 **/
public class ValueExpression implements Expression {

    private final String key;

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

    @Override
    public int interpret(Context context) {
        return context.getParam(key);
    }
}


/**
 * demo
 *
 * @author cans
 * @date 2022/5/14
 **/
public class ExpressionDemo {

    @Test
    public void demoTest() {

        String ex = "a+b-c";

        Context context = new Context();
        context.put("a", 1);
        context.put("b", 9);
        context.put("c", 3);
        Expression expression = this.parse(ex.toCharArray());
        int interpret = expression.interpret(context);
        System.out.println(ex + " = " + interpret);

    }

    private Expression parse(char[] arr) {
        String one = String.valueOf(arr[0]);
        ValueExpression left = new ValueExpression(one);
        if (arr.length == 1) {
            return left;
        }
        String op = String.valueOf(arr[1]);
        Expression nextExp = this.parse(getNextChar(arr));
        if (op.equals("+")) {
            return new AddExpression(left, nextExp);
        } else if (op.equals("-")) {
            return new SubExpression(left, nextExp);
        }
        return null;
    }


    private char[] getNextChar(char[] arr) {
        char[] newArr = new char[arr.length - 2];
        System.arraycopy(arr, 2, newArr, 0, arr.length - 2);
        return newArr;
    }
}

输出结果: a+b-c = 7

总结

优势:

  1. 扩展性极强也是最大的优势了

劣势:

  1. 类膨胀: 每个语法都需要一个实现类去对应解析,通常使用表达式都会比较复杂所以会产生很多实现类,为后期维护带来麻烦;
  2. 实现使用了递归: 递归会造成调试异常复杂,不利于维护;
  3. 效率问题: 循环和递归造成效率低下;

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/923178.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-16
下一篇 2022-05-16

发表评论

登录后才能评论

评论列表(0条)

保存