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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了行为型设计模式之解释器模式相关的知识,希望对你有一定的参考价值。

解释器模式

应用场景

适用场景:

1.一些重复出现的问题可以用一种简单的语言来进行表达;

2.一个简单语法需要解释的场景。

主要角色

解释器模式主要包含四种角色:

1.抽象表达式(Expression)

2.终结符表达式(TerminalExpression)

3.非终结符表达式(NonterminalExpression)

4.上下文环境类(Context)

优缺点

优点:

1、扩展性强:在解释器模式中由于语法是由很多类表示的,当语法规侧更改时,只需修改相应的非终结符表达式即可;若扩展语法时,只需添加相应非终结符类即可
    
2、增加了新的解释表达式的方式

3、易于实现文法:解释器模式对应的文法应当是比较简单且易于实现的,过于复杂的语法并不适合使用解释器模式

缺点

1、语法规则较复杂时,会引起类膨胀:解释器模式每个语法都要产生一个非终结符表达式当语法规则比较复杂时,就会产生大量的解释类,增加系统维护困难

2、执行效率比较低:解释器模式采用递归调用方法,每个非终结符表达式只关心与自关的表达式,每个表达式需要知道最终的结果,因此完整表达式的最终结果是通过从后往前递归调用的方式获取得到。
    
   当完整表达式层级较深时,解释效率下降,且出错时调试困难,因为递归迭代层级太深

基本使用

创建抽象表达式

创建一个抽象表达式接口,定义一个表达式解释方法,由具体子类进行具体解释

public interface IExpression 
    /**
     *  对表达式进行解释
     */
    Object interpret();

创建终结符表达式

public  abstract class TerminalExpression implements IExpression 

    protected IExpression a;
    
    protected IExpression b;

    public TerminalExpression(IExpression a, IExpression b) 
        this.a = a;
        this.b = b;
    

创建非终结符表达式

public class AddNonterminalExpression extends TerminalExpression 

    public AddNonterminalExpression(IExpression a, IExpression b) 
        super(a, b);
    

    public int interpret() 
        return this.a.interpret()+this.b.interpret();
    

public class SubNonterminalExpression extends TerminalExpression 

    public SubNonterminalExpression(IExpression a, IExpression b) 
        super(a, b);
    

    public int interpret() 
        return this.a.interpret()-this.b.interpret();
    

public class NumNonterminalExpression implements IExpression 
    private int value;

    public NumNonterminalExpression(int value) 
        this.value = value;
    


    public int interpret() 
        return this.value;
    

创建上下文环境类

public class CalculatorContext 
    private Stack<IExpression> stack = new Stack<IExpression>();

    public CalculatorContext(String expression) 
        this.parse(expression);
    

    /**
     * 解析表达式
     *
     * @param expression 表达式
     */
    private void parse(String expression) 
        String[] elements = expression.split(" ");
        IExpression aExpr, bExpr;

        for (int i = 0; i < elements.length; i++) 
            String operator = elements[i];
            if (CalculatorContext.isOperator(operator)) 
                aExpr = this.stack.pop();
                System.out.println("出栈: " + aExpr.interpret());
                bExpr = new NumNonterminalExpression(Integer.valueOf(elements[++i]));
                TerminalExpression res = CalculatorContext.util(aExpr, bExpr, operator);
                this.stack.push(res);
                System.out.println("计算: " + aExpr.interpret() + operator + bExpr.interpret());
                System.out.println("计算结果: " + res.interpret() + " 入栈");
             else 
                NumNonterminalExpression numNonterminalExpression = new NumNonterminalExpression(Integer.valueOf(elements[i]));
                this.stack.push(numNonterminalExpression);
                System.out.println("入栈: " + numNonterminalExpression.interpret());
            
        
    

    /**
     * 计算结果
     *
     * @return
     */
    public int calculate() 
        int interpret = this.stack.pop().interpret();
        System.out.println("计算结果: " + interpret + "出栈");
        return interpret;
    

    /**
     * 计算结果
     */
    public static TerminalExpression util(IExpression a, IExpression b, String symbol) 
        if (symbol.equals("+")) 
            return new AddNonterminalExpression(a, b);
         else if (symbol.equals("-")) 
            return new SubNonterminalExpression(a, b);
         else 
            return null;
        
    

    public static boolean isOperator(String symbol) 
        return (symbol.equals("+") || symbol.equals("-"));
    

客户端执行

    public static void main(String[] args) 
        // 创建上下文对象进行解释
        CalculatorContext calculatorContext = new CalculatorContext("10 + 20");
        // 获取执行结果
        System.out.println("calculatorContext.calculate() = " + calculatorContext.calculate());

        CalculatorContext calculatorContext2 = new CalculatorContext("10 + 20 - 15");
        System.out.println("calculatorContext.calculate() = " + calculatorContext2.calculate());
    
入栈: 10
出栈: 10
计算: 10+20
计算结果: 30 入栈
计算结果: 30出栈
calculatorContext.calculate() = 30
入栈: 10
出栈: 10
计算: 10+20
计算结果: 30 入栈
出栈: 30
计算: 30-15
计算结果: 15 入栈
计算结果: 15出栈
calculatorContext.calculate() = 15

以上是关于行为型设计模式之解释器模式的主要内容,如果未能解决你的问题,请参考以下文章

Java经典23种设计模式之行为型模式

行为型模式之解释器模式

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

Python设计模式:行为型

004-行为型-11-解析器模式(Interpreter)

JAVA设计模式(22):行为型-解释器模式(Interpreter)