MaoBisheng

Asp.Net(C#) & SQL & Oracle

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

 

15. Interpreter 解释器模式      2008-09-07

动机(Motivation)

在软件构建过程中,如果某一特定领域的问题比较复杂,类似的结构不断重复出现,如果使用普通的编程方式来实现将面临非常频繁的变化。

在这种情况下,将特定领域的问题表达为某种语法规则下的句子,然后构建一个解释器来解释这样的句子,从而达到解决问题的目的。

意图(Intent)

给定一个语言,定义它的文法的一种表示,并定义一种解释器,这个解释器使用该表示来解释语言中的句子。           ——《设计模式》GoF 

基本代码:  
    //包含解释器之外的一些全局信息
    class Context
    {
        
private string input;
        
public string Input
        {
            
get { return input; }
            
set { input = value; }
        }

        
private string output;
        
public string Output
        {
            
get { return output; }
            
set { output = value; }
        }
    }

 

    //抽象表达式,声明了一个抽象的解释操作,这个接口为抽象语法树中的所有节点所共享
    abstract class AbstractExpression
    {
        
public abstract void Interpret(Context context);
    }

 

    //终结符表达式,实现与文法中的终结符相关联的解释操作
    class TerminalExpression : AbstractExpression
    {
        
public override void Interpret(Context context)
        {
            Console.WriteLine(
"终端解释器");
        }
    }

 

    //非终结符表达式,为文法中的非终结符实现解释操作,对文法中的每一条规则
    
//R1,R2.Rn都需要定义一个具体的非终结符表达式类
    class NonterminalExpression : AbstractExpression
    {
        
public override void Interpret(Context context)
        {
            Console.WriteLine(
"非终端解释器");
        }
    }

 

Interpreter 的几个要点:

Interpreter模式的应用场合是Interpreter模式应用中的难点,只有满足“业务规则频繁变化,且类似的结构不断重复出现,并且容易抽象为语法规则的问题”才适合使用Interpreter模式。

使用Interpreter模式来表示文法规则,从而可以使用面向对象技巧来方便地“扩展”文法。

Interpreter模式比较适合简单的文法表示,对于复杂的文法表示,Interpreter模式会产生比较大的类层次结构,需要求助于语法分析生成器这样的标准工具。

适用性

1.需要类似命令行界面的人机交互:虽然图形界面占统治地位,但仍有些场合需要类似命令行的人机交互。如:查询检索等应用,输入检索表达式要更有效率。

2.用表达式表示逻辑或数学运算:如在统计软件中,某些指标间的关系用表达式比某一种数据结构表示要简洁方便的多。

3.定制输出:如用户需要保存查询的结果。(???)

 

例子:(以李建忠老师《C#设计模式纵横谈》举的例子为例,将中文的数字转换成数学数字)

Context类:包含解释器之外的一些全局信息

Code

 

抽象的Expression类:抽象表达式,声明了一个抽象的解释操作,这个接口为抽象语法树中的所有节点所共享

Code

 

TerminalExpression:终结符表达式,实现与文法中的终结符相关联的解释操作

Code

 

NonterminalExpression:非终结符表达式,为文法中的非终结符实现解释操作

Code

 

客户端代码:

Code

 

运行结果:一千零五万六千零七十二 = 10056072

如果要对功能进行扩展,把数字继续增大至亿,只需再增加一个YiExpression类,继承于Expression类,并重写类中的解释器就够了。。。

 

posted on 2008-09-08 18:47  MaoBisheng  阅读(636)  评论(0编辑  收藏  举报