设计模式之解释器模式

本文介绍了解释器模式的概念、结构及使用场景,并通过一个具体的加减乘除运算例子展示了其在实际应用中的实现过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

解释器模式

解释器模式是一种类行为型模式,它主要是用来解释特定语言的特定文法表示,虽然这个在实际生产中不常用到,但是我们学习一下还是有帮助的。

定义

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

使用场景

当有一个语言需要解释执行,并且你可将该语言中的句子表示为一个抽象语法树时,可使用解释器模式。而当存在以下情况时该模式的效果最好:
1. 该文法简单对于复杂的文法,文法的类层次变得庞大而无法管理。此时语法分析程序生成器这样的工具是更好的选择。它们无需构建抽象语法树即可解释表达式,这样可以节省空间而且还可能节省时间。
2. 效率不是一个关键问题,最高效的解释器通常不是通过直接解释语法分析树实现的,而是首先将它们转换成另外一种形式。例如,正则表达式通常被转换成状态机。但即使在这种情况下,转换器仍可用解释器模式实现,该模式仍是有用的。

结构
解释器模式

实现
我们用一个加减乘除的例子来说明一下解释器模式,AbstractExpression接口设计及其实现

public abstract class AbstractExpression {

    public abstract int interpret(Context context);

}

public class TerminalExpression extends AbstractExpression {

    private int i ;

    public TerminalExpression(int a){
        i = a;
    }

    @Override
    public int interpret(Context context) {
        return i;
    }

}

public class Add extends AbstractExpression{

    private AbstractExpression left ,right ; 

    public Add(AbstractExpression left, AbstractExpression right){
        this.left = left;
        this.right = right;
    }

    @Override
    public int interpret(Context context) {

        return left.interpret(context) + right.interpret(context);
    }

}

public class Subtract extends AbstractExpression{

    private AbstractExpression left ,right ; 

    public Subtract(AbstractExpression left, AbstractExpression right){
        this.left = left;
        this.right = right;
    }

    @Override
    public int interpret(Context context) {

        return left.interpret(context) - right.interpret(context);
    }
}

public class Multiply extends AbstractExpression{

    private AbstractExpression left ,right ; 

    public Multiply(AbstractExpression left, AbstractExpression right){
        this.left = left;
        this.right = right;
    }

    @Override
    public int interpret(Context context) {

        return left.interpret(context) * right.interpret(context);
    }
}

public class Division extends AbstractExpression{

    private AbstractExpression left ,right ; 

    public Division(AbstractExpression left, AbstractExpression right){
        this.left = left;
        this.right = right;
    }

    @Override
    public int interpret(Context context) {

        return left.interpret(context)/right.interpret(context);
    }
}

Context的设计与实现

public class Context {


    private Map<Variable, Integer> valueMap = new HashMap<Variable, Integer>();  

    public void addValue(Variable x , int y){  

           Integer yi = new Integer(y);  
           valueMap.put(x , yi);  

    }  

    public int LookupValue(Variable x){  

           int i = ((Integer)valueMap.get(x)).intValue();  
           return i ;  

    }  
}

public class Variable extends AbstractExpression{

    @Override
    public int interpret(Context context) {

        return context.LookupValue(this);
    }

}

我们来测试一下,计算(a*b)/(a-b+2)

public class Client {

     private static AbstractExpression aex ;  

     private static Context con ;  

    public static void main(String[] args) {
        con = new Context();  
        //设置变量、常量  
        Variable a = new Variable();  
        Variable b = new Variable();  
        TerminalExpression c = new TerminalExpression(2);  

        //为变量赋值  
        con.addValue(a , 5);  
        con.addValue(b , 7);  

        //运算,对句子的结构由我们自己来分析,构造  
        aex = new Division(new Multiply(a , b), new Add(new Subtract(a , b) , c));  
        System.out.println("运算结果为:"+ aex.interpret(con));  

    }
}

解释器模式提供了一个简单的方式来执行语法,而且容易修改或者扩展语法。一般系统中很多类使用相似的语法,可以使用一个解释器来代替为每一个规则实现一个解释器。而且在解释器中不同的规则是由不同的类来实现的,这样使得添加一个新的语法规则变得简单。解释器模式用来做各种各样的解释器,如正则表达式等的解释器等等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值