惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Webroot Blog
Webroot Blog
U
Unit 42
A
About on SuperTechFans
宝玉的分享
宝玉的分享
月光博客
月光博客
C
CERT Recently Published Vulnerability Notes
P
Privacy International News Feed
Microsoft Security Blog
Microsoft Security Blog
G
Google Developers Blog
P
Privacy & Cybersecurity Law Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
S
Securelist
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Spread Privacy
Spread Privacy
L
Lohrmann on Cybersecurity
Apple Machine Learning Research
Apple Machine Learning Research
K
Kaspersky official blog
Hugging Face - Blog
Hugging Face - Blog
B
Blog
I
Intezer
Last Week in AI
Last Week in AI
T
Threat Research - Cisco Blogs
V
V2EX
L
LangChain Blog
AI
AI
G
GRAHAM CLULEY
T
Tor Project blog
人人都是产品经理
人人都是产品经理
D
Docker
WordPress大学
WordPress大学
Google DeepMind News
Google DeepMind News
I
InfoQ
Y
Y Combinator Blog
C
Comments on: Blog
GbyAI
GbyAI
www.infosecurity-magazine.com
www.infosecurity-magazine.com
酷 壳 – CoolShell
酷 壳 – CoolShell
T
Tailwind CSS Blog
aimingoo的专栏
aimingoo的专栏
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
腾讯CDC
N
News and Events Feed by Topic
MyScale Blog
MyScale Blog
H
Help Net Security
Vercel News
Vercel News
T
Tenable Blog
博客园 - 三生石上(FineUI控件)
爱范儿
爱范儿

博客园 - 网络金领

C# WinForm 导出导入Excel/Doc 完整实例教程[使用Aspose.Cells.dll] DataTable的数据批量写入数据库 C# .NET锁屏程序(顺带屏蔽任务管理器) 步步为营 .NET 代码重构学习 十一 - 网络金领 步步为营 .NET 代码重构学习笔记 十 步步为营 .NET 代码重构学习笔记 九 步步为营 .NET 代码重构学习笔记 八 步步为营 .NET 代码重构学习笔记 七 步步为营 .NET 代码重构学习笔记 六、移动函数和移动值域(Move Method And Move Field) 步步为营 .NET 代码重构学习笔记 五、分解函数和替换算法(Replace Method And Substitute Algorithm) 步步为营 .NET 代码重构学习笔记 四、临时变量(Temporary Variable) 步步为营 .NET 代码重构学习笔记 二、提炼方法(Extract Method) 步步为营 .NET 代码重构学习笔记 三、内联方法(Inline Method) 步步为营 .NET 代码重构学习笔记 一、为何要代码重构 步步为营 .NET 设计模式学习笔记 二十四、Factory Method(工厂方法模式) 步步为营 .NET 设计模式学习笔记 二十二、Memento(备望录模式) 步步为营 .NET 设计模式学习笔记 二十一、Visitor(访问者模式) 步步为营 .NET 设计模式学习笔记 二十、Mediator(中介者模式) 步步为营 .NET 设计模式学习笔记 十九、Chain of Responsibility(职责链模式)
步步为营 .NET 设计模式学习笔记 二十三、Interpreter(解释器模式)
网络金领 · 2011-06-01 · via 博客园 - 网络金领

概述

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

意图

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

结构图

image

角色说明:

AbstractExpression:

- 声明一个抽象的Interpret方法,抽象语法树中所有的节点都必须实现该抽象方法。

TerminalExpression:

- 实现和语法中末端符号相关的Interpret方法。

- 在每个句子的末端符号中均需要一个TerminalExpression实例。

NonterminalExpression:

另外一个实现了AbstractExpression 接口的类,用来处理语法树中非末端节点的语法。它含有下一个AbstractExpression(s)的引用,调用它每个子节点的Interpret方法。

Context:

Interpreter方法所需要的信息的容器,该信息对Interpreter而言全局可见。充当几个AbstractExpresssion 实例之间的通讯频道。

PatternClient:

构建或者接收一个抽象语法书的实例。对于一个特定的句子而言,语法树往往由若干个TerminalExpressions 和 NonterminalExpression组成。PatterClient在合适的context下,调用Interpret方法。

生活中的例子

在日常生活中英汉辞典的作用就是把中文翻译成英文或者是把英文翻译成中文,它的实现原理就是词典库里先把对应的中文和英文存在数据库表里,然后根据你输入的内容来匹配出相应的结果出来.

示例用例图

在公司里,借款单申请需要高管来审批,而高管又不会上班时间都坐在电脑面前,公司就有个系统,员工的借款申请都会通过手机短信方式来提示高管,高管可以通过回复短信来审批单据,高管一般都很懒,不愿回复太多的字,只能回复Y或y来表示同意,N或n表示拒绝,用四位标识码代替借款申请单号,用例图如下:

image

代码设计

先创建ReplyContent.cs:

04 public class ReplyContent
06     private string _ReplyText;
08     public string ReplyText
10         get { return _ReplyText; }
11         set { _ReplyText = value; }

再创建InterPreter.cs:

01 public abstract class InterPreter
03     public string ConvertContent(ReplyContent content)
05         if (content.ReplyText.Length == 0)
06             return "请按规则回复审批短信.";
07         return Excute(content.ReplyText);
10     public abstract string Excute(string key);

再创建Approve.cs:

01 public class Approve : InterPreter
03     public override string Excute(string key)
05         if (key == "Y" || key == "y")
07             return "同意";
09         else if (key == "N" || key == "n")
11             return "拒绝";
15             return "回复内容有误,请重新回复.";

再创建DocumentNum.cs:

01 public class DocumentNum : InterPreter
03      public Dictionary<string, string> OddNum
07              Dictionary<string, string> OddID = new Dictionary<string, string>();
08              OddID.Add("0001", "123890890892345");
09              OddID.Add("0002", "123456717012345");
10              OddID.Add("0003", "123456669012345");
11              OddID.Add("0004", "123423444012345");
12              OddID.Add("0005", "123467845345345");
13              OddID.Add("0006", "123231234564345");
14              OddID.Add("0007", "128797897867745");
15              return OddID;
19      public override string Excute(string key)
21          string value = null;
22          if (OddNum.TryGetValue(key, out value))
24              return value;
28              return "没找到对应的单号.";

再创建ReplyClient.cs:

01 public class ReplyClient
03     public static string ApplyContent(string ReplayValue)
05         ReplyContent content = new ReplyContent();
06         string approvevalue = ReplayValue.Substring(0, 1);
07         string OddIDvalue = ReplayValue.Substring(1, 4);
08         string result = string.Empty;
09         InterPreter expression = new Approve();
10         content.ReplyText = approvevalue;
11         result = string.Format("你{0}", expression.ConvertContent(content));
12         expression = new DocumentNum();
13         content.ReplyText = OddIDvalue;
14         result += string.Format("单号是{0}的申请.\n", expression.ConvertContent(content));
15         return result;

最后再调用:

01 public partial class Run : Form
05         InitializeComponent();
08     private void btnRun_Click(object sender, EventArgs e)
10         //-------------------------------------
12          rtbResult.AppendText(ReplyClient.ApplyContent("Y0001"));
13          rtbResult.AppendText(ReplyClient.ApplyContent("y0002"));
14          rtbResult.AppendText(ReplyClient.ApplyContent("N0003"));
15          rtbResult.AppendText(ReplyClient.ApplyContent("n0004"));

结果如下图:

image

实现要点

1.Interpreter模式的应用场合是Interpreter模式应用中的难点,只有满足“业务规则频繁变化,且类似的模式不断重复出现,并且容易抽象为语法规则
的问题”才适合使用Interpreter模式。
2.使用Interpreter模式来表示文法规则,从而可以使用面向对象技巧来方便地“扩展”文法。

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

适用性

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

总结

效率不是一个Interpreter关心的关键问题。最高效的解释器通常不是通过直接解释语法分析树实现的,而是首先将它们转换成另一种形式。例如:正则表达式通常被转换成状态机。但即使在这种情况下,如果效率不是一个关键问题,转换器仍可用Interpreter模式实现,该模式仍是有用的。