【设计模式-解释器模式】

时间:2022-07-24
本文章向大家介绍【设计模式-解释器模式】,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

【导读】加密解密都是需要特定的算法,而这个算法就是一个解释器。又比如翻译器,各种语言都有其翻译器。针对特定语言会有特定的解释器,这就是解释器模式。

一、定义

给定一个语言,定义它文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。为了解释一种语言,创建一种解释器。

二、实例

比如定义一种算法表示,a b c * +,这种是先b+c,然后将b+c的结果在乘于a,最终解释就是(b+c)*a。

首先定义各种字符的解释:

1、抽象解释器
public interface Interpreter {
    int interpret();
}

2、数字解释器,直接返回数字
public class NumberInterpreter implements Interpreter {

    private int number;

    public NumberInterpreter(int number) {
        this.number = number;
    }

    public NumberInterpreter(String number) {
        this.number = Integer.parseInt(number);
    }

    @Override
    public int interpret() {
        return this.number;
    }
}

3、加法解释器,包含两个数字解释器,直接相加
public class AddInterpreter implements Interpreter {

    private Interpreter firstInterpreter,secondInterpreter;

    public AddInterpreter(Interpreter firstInterpreter, Interpreter secondInterpreter) {
        this.firstInterpreter = firstInterpreter;
        this.secondInterpreter = secondInterpreter;
    }

    @Override
    public int interpret() {
        return this.firstInterpreter.interpret() 
              + this.secondInterpreter.interpret();
    }
}

4、乘法解释器。包含两个数字解释器,直接相乘
public class MultiInterpreter implements Interpreter {

    private Interpreter firstInterpreter,secondInterpreter;

    public MultiInterpreter(Interpreter firstInterpreter, Interpreter secondInterpreter) {
        this.firstInterpreter = firstInterpreter;
        this.secondInterpreter = secondInterpreter;
    }

    @Override
    public int interpret() {
        return this.firstInterpreter.interpret() 
              * this.secondInterpreter.interpret();
    }
}

工具类:

public class OperatorUtil {
    1、判断当前字符是否是运算符
    public static boolean isSymbol(String symbol) {
        return symbol.equals("*") || symbol.equals("+");
    }

    2、根据运算符去选择特定的解释器 
    public static Interpreter getExpressionObject(Interpreter firstInterpreter,Interpreter secondInterpreter,String symbol) {
        if (symbol.equals("*")) {
            return new MultiInterpreter(firstInterpreter,secondInterpreter);
        } else if (symbol.equals("+")) {
            return new AddInterpreter(firstInterpreter,secondInterpreter);
        }
        return null;
    }

}

解释一整串字符:

public class MyExpressionParser {
    1、利用栈先进后出的特性去存储
    private static Stack<Interpreter> stack = new Stack<Interpreter>();

    public static int parse(String str) {
        String[] split = str.split(" ");
        for (String s : split) {
            2、如果是数字,则直接入栈
            if (!OperatorUtil.isSymbol(s)) {
                Interpreter interpreter = new NumberInterpreter(s);
                stack.push(interpreter);
                System.out.println("入栈:"+interpreter.interpret());
            } else {
                3、如果是运算符,则将两个数字出栈
                Interpreter firstInterpreter = stack.pop();
                Interpreter secondInterpreter = stack.pop();
                System.out.println("出栈:"+firstInterpreter.interpret() + "和" + secondInterpreter.interpret());
                4、根据运算符选择特定的解释器 
                Interpreter expressionObject = OperatorUtil.getExpressionObject(firstInterpreter, secondInterpreter, s);
                int interpret = expressionObject.interpret();
                Interpreter inStack = new NumberInterpreter(interpret);
                5、运算完后在进行入栈
                stack.push(inStack);
                System.out.println("将临时结果:"+interpret+"入栈");
            }
        }
        6、最终输出结果
        int result = stack.pop().interpret();
        System.out.println("最终结果为:"+result);
        return result;
    }

}

测试类:

public static void main(String[] args) {
        String str = "6 100 11 + *";
        int parse = MyExpressionParser.parse(str);
    }

结果:

其过程是这样的:

(1)如果是数字入栈

(2)如果不是数字,将栈顶两个元素弹出,进行运算

(3)将运算结果入栈

(4)重复上述操作

类图:

三、源码实例

(1)正则表达式的解析。