35解释器模式(Interpreter Pattern)

动机(Motivate):
    在软件构建过程中,如果某一特定领域的问题比较复杂,类似的模式不断重复出现,如果使用普通的编程方式来实现将面临非常频繁的变化。
    在这种情况下,将特定领域的问题表达为某种文法规则下的句子,然后构建一个解释器来解释这样的句子,从而达到解决问题的目的。
意图(Intent):
    
给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
结构图(Struct):
            
生活中的例子:
             
适用性:

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

 1     class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             string roman = "五千四百三十二"//5432
 6             Context context = new Context(roman);
 7 
 8             //Build the 'parse tree'
 9             ArrayList tree = new ArrayList();
10             tree.Add(new OneExpression());
11             tree.Add(new TenExpression());
12             tree.Add(new HundredExpression());
13             tree.Add(new ThousandExpression());            
14 
15             //Interpret
16             foreach (Expression exp in tree)
17             {
18                 exp.Interpret(context);
19             }
20             Console.WriteLine("{0} = {1}", roman, context.Data);
21             //Wait for user
22             Console.Read();
23         }
24     }

创建一个抽象类Expression,来描述共同的操作。

 1     public abstract class Expression
 2     {
 3         protected Dictionary<stringint> table = new Dictionary<stringint>(9);
 4         public Expression()
 5         {
 6             table.Add(""1);
 7             table.Add(""2);
 8             table.Add(""3);
 9             table.Add(""4);
10             table.Add(""5);
11             table.Add(""6);
12             table.Add(""7);
13             table.Add(""8);
14             table.Add(""9);
15         }
16         public virtual void Interpret(Context context)
17         {
18          if(context.Statement.Length==0)
19             {
20               return;
21             }
22         foreach(string key in table.Keys)
23         {
24          int value=table[key];
25          if(context.Statement.EndsWith(key + GetPostifix()))
26             { 
27               context.Data +=value*Multiplier();
28               context.Statement = context.Statement.Substring(0,context.Statement.Length- this.GetLength());
29             }
30 
31             if(context.Statement.EndsWith(""))
32             {
33                 context.Statement = context.Statement.Substring(0, context.Statement.Length - 1);
34             }
35             if (context.Statement.Length == 0)
36             {
37                 return;
38             }
39          }
40        }
41 
42         public abstract string GetPostifix();
43         public abstract int Multiplier();
44         public virtual int GetLength()
45         {
46             return this.GetPostifix().Length + 1;
47         }
48     }

然后创建一个公共类Context,定义一些全局信息。

 1    public class Context
 2     {
 3         private string statement;
 4         private int data;
 5 
 6         //Constructor
 7         public Context(string statement)
 8         {
 9             this.statement = statement;
10         }
11         //Properties
12         public string Statement
13         {
14             get { return statement; }
15             set { statement = value; }
16         }
17         public int  Data
18         {
19             get { return data; }
20             set { data  = value; }
21         }
22     }

 

 1     public class OneExpression : Expression
 2     {
 3         public override string GetPostifix()
 4         {
 5             return "";
 6         }
 7         public override int Multiplier() { return 1; }
 8         public override int GetLength()
 9         {
10             return 1;
11         }
12     }
13     public class TenExpression : Expression
14     {
15         public override string GetPostifix()
16         {
17             return "";
18         }
19         public override int Multiplier() { return 10; }
20         public override int GetLength()
21         {
22             return 2;
23         }
24     }
25     public class HundredExpression : Expression
26     {
27         public override string GetPostifix()
28         {
29             return "";
30         }
31         public override int Multiplier() { return 100; }
32         public override int GetLength()
33         {
34             return 2;
35         }
36     }
37     public class ThousandExpression : Expression
38     {
39         public override string GetPostifix()
40         {
41             return "";
42         }
43         public override int Multiplier() { return 1000; }
44         public override int GetLength()
45         {
46             return 2;
47         }
48     }

Interpreter实现要点:
  Interpreter模式的应用场合是interpreter模式应用中的难点,只有满足"业务规则频繁变化,且类似的模式不断重复出现,并且容易抽象为语法规则的问题"才适合使用Interpreter模式。
    使用Interpreter模式来表示文法规则,从而可以使用面向对象技巧来方便地“扩展”文法。
    Interpreter模式比较适合简单的文法表示,对于复杂的文法表示,Interpreter模式会产生比较大的类层次结构,需要求助于语法分析生成器这样的标准工具。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/438631.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

37职责链模式(Chain of Responsibility Pattern)

动机(Motivate)&#xff1a; 在软件构建过程中&#xff0c;一个请求可能被多个对象处理&#xff0c;但是每个请求在运行时只能有一个接受者&#xff0c;如果显示指定&#xff0c;将必不可少地带来请求发送者与接受者的紧耦合。 如何使请求的发送者不需要指定具体的接受…

python3中format函数列表_Python3之字符串格式化format函数详解(上)

173.jpg概述在Python3中&#xff0c;字符串格式化操作通过format()方法或者fstring实现。而相比于老版的字符串格式化方式&#xff0c;format()方法拥有更多的功能&#xff0c;操作起来更加方便&#xff0c;可读性也更强。该函数将字符串当成一个模板&#xff0c;通过传入的参数…

38备忘录模式(Memento Pattern)

对象状态的回溯&#xff1a; 对象状态的变化无端&#xff0c;如何回溯/恢复对象在某个点的状态&#xff1f; 动机&#xff1a; 在软件构建过程中&#xff0c;某些对象的状态在转换过程中&#xff0c;可能由于某种需要&#xff0c;要求程序能够…

python剪切文件如何恢复_用python实现的可以拷贝或剪切一个文件列表中的所有文件...

# coding:utf-8import osimport sysdef cut_and_paste_file(source, destination):source: file path 中文destination: directory pathdef format_path(path):if not os.path.isabs(path):path os.path.join(os.getcwd(), path)return pathdef mk_dir(path):if not os.path.e…

39策略模式(Strategy Pattern)

算法与对象的耦合&#xff1a; 对象可能经常需要使用多种不同的算法&#xff0c;但是如果变化频繁&#xff0c;会将类型变得脆弱... 动机&#xff1a; 在软件构建过程中&#xff0c;某些对象使用的算法可能多种多样&#xff0c;经常改变&#xff0c;如果将…

python选择表单_如何使用Python在表单中选择选项?

下面是一些基本用法示例&#xff1a;>>> import mechanize>>> br mechanize.Browser()>>> br.open(http://www.w3schools.com/html/html_forms.asp)表单有一个name属性&#xff1b;但有时它是空的&#xff1a;>>> [f.name for f in br.fo…

40访问者模式(Visitor Pattern)

类层次结构的变化&#xff1a; 类层次结构中可能经常由于引入新的操作&#xff0c;从而将类型变得脆弱... 动机&#xff1a; 在软件构建过程中&#xff0c;由于需求的改变&#xff0c;某些类层次结构中常常需要增加新的行为(方法),如果直接…

ssh中c3p0连接mysql_ssh 中使用c3p0 的连接池配置 | 学步园

applicationContext.xml 文件&#xff1a;xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xmlns:jee"http://www.springframework.org/schema/jee"xsi:schemaLocation"http://www.springframework.org/schema/beans http://www.springframewor…

41状态模式(State Pattern)

对象状态影响对象行为&#xff1a; 对象拥有不同的状态&#xff0c;往往会行使不同的行为... 动机&#xff1a; 在软件构建过程中&#xff0c;某些对象的状态如果改变以及其行为也会随之而发生变化&#xff0c;比如文档处于只读状态&#xff0c;其支…

python中空格属于字符吗_举例说明python中空格是属于字符

python中空格属于字符吗&#xff1f;答案是肯定的&#xff0c;空格在Python中也是属于字符的。案例&#xff1a;输入一行字符&#xff0c;分别统计出其中英文字母、空格、数字和其它字符的个数。#!/usr/bin/python# -*- coding: UTF-8 -*-import strings raw_input(input a st…

python如何引发和处理异常_在python3.6中,如何捕捉异常并引发异常以便稍后处理?...

假设我有两个例外&#xff1a;class FooError (Exception):def __init__(self, *args, **kwargs):default_message A foo error has occurred!if not (args or kwargs): args (default_message,)super().__init__(*args, **kwargs)class BarError (Exception):def __init__(s…

2字节十六进制浮点数 qt_Qt之8个字节转化为double小数

首先要理解double的存储方式&#xff0c;具体可查找相关的博客本文实现的是将8个字节(存储为16进制的字符串)转化为对应的double类型double MainWindow::qByteArraytodouble(QString qstr){QByteArray byte;StringToHex(qstr,byte);double result;memcpy(&result, byte.dat…

【转】如何将域中的AD数据导入SharePoint

最近刚装好sharepoint2010&#xff0c;想要研究一下&#xff0c;第一件想做的事就是想把AD中的用户信息导入到SharePoint中。 那现在就来看看我是怎么操作的&#xff1a; 1.打开管理中心 sharepoint是通过“用户配置文件同步服务”来实现同步&#xff0c;所以第一步要开启这个…

Apsara Clouder专项技能认证:实现调用API接口

一.API 简介 1.API 的概念 API(Application Programming Interface应用程序编程接口)是一些预定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码或理解内部工作机制的细节 2.API 的特点 API 是一个明确定义的接口,可以为其…

druid加密mysql_Druid 数据库用户密码加密 代码实现

标签&#xff1a;druid-1.0.16.jar 阿里巴巴的开源数据连接池 jar包明文密码私钥(privateKey)加密加密密码加密密码公钥(publicKey)解密明文密码程序代码如下&#xff1a;package com.t1;import com.alibaba.druid.filter.config.ConfigTools;public class DruidTest {public s…

select switch语句总是搞混,总结如下

select switch语句总是搞混&#xff0c;总结如下 类C&#xff1a;c c c# java &#xff1a; 比较 switch(expression) { case constant-expression : statement(s); break; /* optional */ case constant-expression : statement(s); brea…

java路径怎么找_Java路径怎么找

有一种情况是装好java了&#xff0c;配置好java环境(在Linux里面比较复杂)了&#xff0c;但忘了路径了&#xff1f;&#xff01;解决&#xff1a;先要申明一下which java是定位不到安装路径的。which java定位到的是java程序的执行路径。网上的资料都是人云亦云&#xff0c;完全…

【转】什么是CORS

CORS 全称是跨域资源共享&#xff08;Cross-Origin Resource Sharing&#xff09;&#xff0c;是一种 AJAX 跨域请求资源的方式&#xff0c;支持现代浏览器&#xff0c;IE支持10以上。 CORS与JSONP的使用目的相同&#xff0c;但是比JSONP更强大。JSONP只支持GET请求&#xff0c…

java web 连接linux_如何将javaweb项目部署到linux下

以下是对将javaweb项目部署到linux下的方法进行了详细的分析介绍一般都在windows下开发的现在部署到linux下将项目达成war包(用eclipse项目右键>Export>选择war file)将tomcat(用winSCP当然你也可以用secureCRT用securCRT需要建立sftp(即上传文件的目录)用put tomcat命令…

第一节:复习委托,并且通过委托的异步调用开启一个新线程和异步回调、异步等待

一. 再谈委托 1. 委托是一个关键字为delegate的自定义类型&#xff0c;通过委托可以把方法以参数的形式传递给另外一个方法&#xff0c;实现插件式的开发模式&#xff1b; 同时调用委托的时候&#xff0c;委托所包含的所有方法都会被实现。 2. 委托的发展历史&#xff1a;new…