设计模式-行为型-解释器模式

描述

  • 对于形式变化比较多的情况下,可以把变化定义成节点,定义一个解释器,去逐步解析节点的合法性,得到最终结果。
  • 比如计算器:1+2+3+4-5,1+2+3-4+5,…
  • 把数字和+ - 定义成节点,由解释器去解析(提取语句规则,抽象成一种语言,然后解析这种语言的含义),得到最终结果。

定义语法规则:

  • express:表达式( | :表示或的意思)
  • plus:加法表达式
  • minus:减法表达式
  • value:最终结果
express ::= value | plus | minus
plus ::= express + express
minus ::= express - express
value ::= integer

角色

  • 抽象表达式角色:定义解释器的接口,约定规范,提供解析方法:interpret。
  • 终结符表达式角色:抽象表达式子类,用来实现终结符相关操作。如语法规则中的value。
  • 非终结符表达式角色:抽象表达式子类,用来实现非终结符相关操作。如语法规则中的:plus等。
  • 环境角色:定义解释器需要的数据,公共功能,传递所有解释器共享的数据。
  • 客户端:将表达式装换为解释器对象解析的抽象语法树,让解释器解析获得结果。

实现

public class Test {
    public static void main(String[] args) {
        Environment environment = new Environment();
        ParameterExpress a = new ParameterExpress("A");
        ParameterExpress b = new ParameterExpress("B");
        ParameterExpress c = new ParameterExpress("C");
        ParameterExpress d = new ParameterExpress("D");
        environment.add(a, 11);
        environment.add(b, 2);
        environment.add(c, 4);
        environment.add(d, 6);

        AbstractExpress express = new PlusExpress(new SubtractionExpress(new PlusExpress(a, b), c), d);
        Integer interpret = express.interpret(environment);
        System.out.println(express);
        System.out.println(interpret);

    }
}
// 抽象表达式
abstract class AbstractExpress {
    abstract Integer interpret(Environment environment);
}

// 环境角色,理解成容器,存储具体参数角色
class Environment {
    // 参数节点
    private Map<ParameterExpress, Integer> parameterExpressIntegerMap = new HashMap<>();
    // 存入数据
    public void add(ParameterExpress parameterExpress, Integer value) {
        parameterExpressIntegerMap.put(parameterExpress, value);
    }
    // 获取数据
    public Integer get(ParameterExpress parameterExpress) {
        return parameterExpressIntegerMap.get(parameterExpress);
    }
}

// 具体变量角色
class ParameterExpress extends AbstractExpress {
    // 变量名称
    private String name;

    ParameterExpress(String name){ this.name = name;}
    @Override
    Integer interpret(Environment environment) {
    	// 获取变量数据
        return environment.get(this);
    }

    @Override
    public String toString() {
        return name;
    }
}
// 具体加法表达式
class PlusExpress extends AbstractExpress {
    // 左边表达式
    private AbstractExpress left;
    // 右边表达式
    private AbstractExpress right;

    PlusExpress(AbstractExpress left, AbstractExpress right) {
        this.left = left;
        this.right = right;
    }

    @Override
    Integer interpret(Environment environment) {
    	// 加法表达式规则
        return left.interpret(environment) + right.interpret(environment);
    }

    @Override
    public String toString() {
        return left + "+" + right;
    }
}
// 具体减法表达式
class SubtractionExpress extends AbstractExpress {
    // 左边表达式
    private AbstractExpress left;
    // 右边表达式
    private AbstractExpress right;

    SubtractionExpress(AbstractExpress left, AbstractExpress right) {
        this.left = left;
        this.right = right;
    }

    @Override
    Integer interpret(Environment environment) {
    	// 减法表达式规则
        return left.interpret(environment) - right.interpret(environment);
    }

    @Override
    public String toString() {
        return left + "-" + right;
    }
}

优点

  • 易于扩展和改变表达式规则,表达式规则编写较为符合思考逻辑。符合开闭原则。

缺点

  • 复杂文法难以维护,每种规则都需要一个类,类个数太多难以管理维护,递归,执行效率较低,调试较麻烦。

使用场景

  • 当语言的文法较为简单,且执行效率不是问题,简单语法规则重复出现时。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值