设计模式学习笔记十六(Interpreter解释器模式)

来源:互联网 发布:软件项目中标通知书 编辑:程序博客网 时间:2024/05/21 09:32

动机:在软件构建过中,如果某一特定领域的问题比较复杂,类似的模式不断重复出现,如果使用普通的编程方式来实现将面临非常频繁的变化。在这种情况下,将特定领域的问题表达为某种语法规则下的句子,然后构建一个解释器来解释这样的句子,从而达到解决问题的目的。

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

基本Code

         //将汉字的数字转换成数值表示,如四千五百六十万三千零二十五――>45603025

public class Context

    {

         private string statement;

         public long data;

         public Context(string statement)

         {

             this.statement=statement;

         }

         public string Statement

         {

             get{return statement;}

             set{statement=value;}

         }

         public long Data

         {

             get{return data;}

             set{data=value;}

         }

    }

 

    public abstract class Expression

    {

         protected Dictionary<string,int> table=new Dictionary<string,int>();

         public Expression()

         {

             table.Add("",1);

             table.Add("",2);

             table.Add("",3);

             table.Add("",4);

             table.Add("",5);

             table.Add("",6);

             table.Add("",7);

             table.Add("",8);

             table.Add("",9);

         }

         public virtual void Interpret(Context context)

         {

             if (context.Statement.Length==0)

             {

                  return;

             }

             foreach(string key in table.Keys)

             {

                  int value=table[key];

                  if (context.Statement.EndsWith(key+GetPostfix()))

                  {

                       context.Data+=value*this.Multiplier();

                       context.Statement=

context.Statement.Substring(0,context.Statement.Length-this.GetLength());

                  }

                  //可能出现五千零二十的情况

                  if (context.Statement.EndsWith(""))

                  {

 context.Statement=

context.Statement.Substring(0,context.Statement.Length-1);

                  }

 

             }

        }

        public abstract string GetPostfix();

        public abstract int Multiplier();

        public virtual int GetLength()

        {

             return this.GetPostfix().Length+1;

        }

    }

    public class GeExpression:Expression

    {

         public override string GetPostfix()

         {

             return "";

         }

         public override int GetLength()

         {

             return 1;

         }

        public override int Multiplier()

        {

            return 1;

        }

    }

    public class ShiExpression:Expression

    {

         public override string GetPostfix()

         {

             return "";

         }

         public override int Multiplier()

         {

             return 10;

         }

    }

    public class BaiExpression:Expression

    {

         public override string GetPostfix()

         {

             return "";

         }

         public override int Multiplier()

         {

             return 100;

         }

    }

    public class QianExpression:Expression

    {

         public override string GetPostfix()

         {

             return "";

         }

         public override int Multiplier()

         {

             return 1000;

         }

    }

    public class WanExpression:Expression

    {

         public override string GetPostfix()

         {

             return "";

         }

         public override void Interpret(Context context)

         {

             if (context.Statement.Length==0)

                  return;

             ArrayList tree=new ArrayList();

             tree.Add(new GeExpression());

             tree.Add(new ShiExpression());

             tree.Add(new BaiExpression());

             tree.Add(new QianExpression());

             foreach(string key in table.Keys)

             {

                  int value=table[key];

                  if (context.Statement.EndsWith(this.GetPostfix()))

                  {

                        long temp=context.Data;

     context.Data=0;   

     context.Statement=

context.Statement.Substring(0,context.Statement.Length-1);

                    foreach(Expression exp in tree)

                    {

                         exp.Interpret(context);

                    }

                    context.Data=temp+context.Data*this.Multiplier();

                  }

             }

 

         }

         public override int Multiplier()

         {

             return 10000;

         }

    }

 

    //扩展,加入亿

    public class YiExpression:Expression

    {

         public override string GetPostfix()

         {

             return  "亿";

         }

         public override void Interpret(Context context)

         {

             if (context.Statement.Length==0)

                  return;

             ArrayList tree=new ArrayList();

             tree.Add(new GeExpression());

             tree.Add(new ShiExpression());

             tree.Add(new BaiExpression());

             tree.Add(new QianExpression());

             tree.Add(new WanExpression());

             foreach(string key in table.Keys)

             {

                  int value=table[key];

                  if (context.Statement.EndsWith(this.GetPostfix()))

                  {

                        long temp=context.Data;

context.Data=0;                                        context.Statement=

context.Statement.Substring(0,context.Statement.Length-1);

                    foreach(Expression exp in tree)

                    {

                         exp.Interpret(context);

                    }

                    int i;

                    context.Data=temp+context.Data*this.Multiplier();

                  }

             }

         }

         public override int Multiplier()

         {

             return 100000000;

         }

}

 

class App

    {

        static void Main(string[] args)

        {

            string roman = "五十四亿四十七万六千四百五十二";// 5400476452

            Context context = new Context(roman);

            ArrayList tree = new ArrayList();

            tree.Add(new GeExpression());

            tree.Add(new ShiExpression());

            tree.Add(new BaiExpression());

            tree.Add(new QianExpression());

            tree.Add(new WanExpression());

            tree.Add(new YiExpression());

            foreach (Expression exp in tree)

            {

                exp.Interpret(context);

            }

            Console.WriteLine("{0}――>{1}", roman, context.Data);

            Console.ReadLine();

        }

    }

Interpreter模式结构图:

Interpreter模式要点:

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

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

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

 
原创粉丝点击