当前位置: 移动技术网 > IT编程>软件设计>设计模式 > 折腾Java设计模式之解释器模式

折腾Java设计模式之解释器模式

2019年01月14日  | 移动技术网IT编程  | 我要评论

解释器模式

解释器模式是类的行为模式。给定一个语言之后,解释器模式可以定义出其文法的一种表示,并同时提供一个解释器。客户端可以使用这个解释器来解释这个语言中的句子。

意图 给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子。

主要解决 对于一些固定文法构建一个解释句子的解释器。

何时使用 如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题。

如何解决 构件语法树,定义终结符与非终结符。

关键代码 构件环境类,包含解释器之外的一些全局信息,一般是 hashmap。

解释器模式相关uml图

类图

interpreter uml class diagram.svg

img

可以看出右侧的协作图(object collaboration diagram)展现出运行时的解释器模式。client向右侧抽象语法树发送解释请求,请求被转发并向下到树结构的所有对象。

解释器模式的主要角色

抽象解释器(abstractexpression/expression):声明一个所有具体表达式都要实现的抽象接口(或者抽象类),接口中主要是一个interpret()方法,称为解释操作。具体解释任务由它的各个实现类来完成,具体的解释器分别由终结符解释器terminalexpression和非终结符解释器nonterminalexpression完成。

终结符表达式(terminalexpression):实现与文法中的元素相关联的解释操作,通常一个解释器模式中只有一个终结符表达式,但有多个实例,对应不同的终结符。终结符一半是文法中的运算单元,比如有一个简单的公式r=r1+r2,在里面r1和r2就是终结符,对应的解析r1和r2的解释器就是终结符表达式。

非终结符表达式(nonterminalexpression):文法中的每条规则对应于一个非终结符表达式,非终结符表达式一般是文法中的运算符或者其他关键字,比如公式r=r1+r2中,+就是非终结符,解析+的解释器就是一个非终结符表达式。非终结符表达式根据逻辑的复杂程度而增加,原则上每个文法规则都对应一个非终结符表达式。

环境角色(context):这个角色的任务一般是用来存放文法中各个终结符所对应的具体值,比如r=r1+r2,我们给r1赋值100,给r2赋值200。这些信息需要存放到环境角色中,很多情况下我们使用map来充当环境角色就足够了。

干货代码

跳转到源码地址

简单的一个解释器计算加减乘除算法,环境上下文没有用好,其实计算规则更多的是人为设定的了。

本次的抽象接收器用的是抽象类,用接口代替也可以。

//抽象解释器
public abstract class abstractexpression {

    public abstract int interpreter(context context);
}

//非终结表达式:加法
@data
@allargsconstructor
public class add extends abstractexpression {

    private final abstractexpression left;

    private final abstractexpression right;

    @override
    public int interpreter(context context) {
        return left.interpreter(context) + right.interpreter(context);
    }
}

//非终结表达式:减法
@data
@allargsconstructor
public class subtract extends abstractexpression {

    private final abstractexpression left;

    private final abstractexpression right;

    @override
    public int interpreter(context context) {
        return left.interpreter(context) - right.interpreter(context);
    }
}

//非终结表达式:乘法
@data
@allargsconstructor
public class multiply extends abstractexpression {

    private final abstractexpression left;

    private final abstractexpression right;

    @override
    public int interpreter(context context) {
        return left.interpreter(context) * right.interpreter(context);
    }
}

//非终结表达式:除法
@data
@allargsconstructor
public class division extends abstractexpression {

    private final abstractexpression left;

    private final abstractexpression right;

    @override
    public int interpreter(context context) {
        int right = this.right.interpreter(context);
        if (right != 0) {
            return left.interpreter(context) / right;
        }

        return -1;
    }
}

//终结表达式:变量
@data
@allargsconstructor
public class variable extends abstractexpression {

    private final string key;

    @override
    public int interpreter(context context) {
        return context.getvalue(key);
    }
}

//环境上下文
@getter
public class context {

    private final map<string, integer> valuemap = maps.newhashmap();

    public void addvalue(final string key, final int value) {
        valuemap.put(key, integer.valueof(value));
    }

    public int getvalue(final string key) {
        return valuemap.get(key).intvalue();
    }
}


//
public class application {

    public static void main(string[] args) {
        context context = new context();
        context.addvalue("a", 6);
        context.addvalue("b", 9);
        context.addvalue("c", 1);

        variable a = new variable("a");
        variable b = new variable("b");
        variable c = new variable("c");

        abstractexpression multiplyvalue = new multiply(a, b);
        abstractexpression subtractvalue = new subtract(a, b);
        abstractexpression addvalue = new add(subtractvalue, c);
        abstractexpression divisionvalue = new division(multiplyvalue, addvalue);

        log.info("{}", context.getvaluemap());
        log.info("(a*b)/(a-b+c) = {}", divisionvalue.interpreter(context));
    }
}

结果如下:

image-20190112095954448

java中的应用

java中的表达式引擎

jdk中的应用

这个模式通常定义了一个语言的语法,然后解析相应语法的语句。

java.util.pattern

java.text.normalizer

java.text.format

参考

interpreter pattern

细数jdk里的设计模式

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网