博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
步步为营 .NET 设计模式学习笔记 二十三、Interpreter(解释器模式)
阅读量:5775 次
发布时间:2019-06-18

本文共 4692 字,大约阅读时间需要 15 分钟。

概述

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

意图

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

结构图

 

角色说明:

AbstractExpression:

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

TerminalExpression:

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

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

NonterminalExpression:

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

Context:

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

PatternClient:

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

 

生活中的例子

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

 

示例用例图

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

 

代码设计

先创建ReplyContent.cs:

///     /// 回复内容    ///     public class ReplyContent    {        private string _ReplyText;        public string ReplyText        {            get { return _ReplyText; }            set { _ReplyText = value; }        }    }

 

再创建InterPreter.cs:

public abstract class InterPreter    {        public string ConvertContent(ReplyContent content)        {            if (content.ReplyText.Length == 0)                return "请按规则回复审批短信.";            return Excute(content.ReplyText);        }        public abstract string Excute(string key);    }

 

再创建Approve.cs:

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

 

再创建DocumentNum.cs:

public class DocumentNum : InterPreter    {        public Dictionary
OddNum { get { Dictionary
OddID = new Dictionary
(); OddID.Add("0001", "123890890892345"); OddID.Add("0002", "123456717012345"); OddID.Add("0003", "123456669012345"); OddID.Add("0004", "123423444012345"); OddID.Add("0005", "123467845345345"); OddID.Add("0006", "123231234564345"); OddID.Add("0007", "128797897867745"); return OddID; } } public override string Excute(string key) { string value = null; if (OddNum.TryGetValue(key, out value)) { return value; } else { return "没找到对应的单号."; } } }

 

再创建ReplyClient.cs:

public class ReplyClient    {        public static string ApplyContent(string ReplayValue)        {            ReplyContent content = new ReplyContent();            string approvevalue = ReplayValue.Substring(0, 1);            string OddIDvalue = ReplayValue.Substring(1, 4);            string result = string.Empty;            InterPreter expression = new Approve();            content.ReplyText = approvevalue;            result = string.Format("你{0}", expression.ConvertContent(content));            expression = new DocumentNum();            content.ReplyText = OddIDvalue;            result += string.Format("单号是{0}的申请.\n", expression.ConvertContent(content));            return result;        }    }

 

最后再调用:

public partial class Run : Form    {        public Run()        {            InitializeComponent();        }        private void btnRun_Click(object sender, EventArgs e)        {            //-------------------------------------                      rtbResult.AppendText(ReplyClient.ApplyContent("Y0001"));             rtbResult.AppendText(ReplyClient.ApplyContent("y0002"));             rtbResult.AppendText(ReplyClient.ApplyContent("N0003"));             rtbResult.AppendText(ReplyClient.ApplyContent("n0004"));                    }    }

 

结果如下图:

 

实现要点

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

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

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

 

适用性

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

 

总结

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

转载于:https://www.cnblogs.com/springyangwc/archive/2011/05/05/2037146.html

你可能感兴趣的文章
Java基础2-基本语法
查看>>
SPI总线通信电路设计
查看>>
一个不错的vue项目
查看>>
屏蔽指定IP访问网站
查看>>
[leetcode] 237. Delete Node in a Linked List
查看>>
python学习 第一天
查看>>
根据毫秒数计算出当前的“年/月/日/时/分/秒/星期”并不是件容易的事
查看>>
python的图形模块PIL小记
查看>>
shell变量子串
查看>>
iOS的主要框架介绍 (转载)
查看>>
react报错this.setState is not a function
查看>>
poj 1183
查看>>
从根本解决跨域(nginx部署解决方案)
查看>>
javascript实现的一个信息提示的小功能/
查看>>
layer.js:2 Uncaught TypeError: Cannot read property 'extend' of undefined
查看>>
Centos7.x:开机启动服务的配置和管理
查看>>
HTML5 浏览器返回按钮/手机返回按钮事件监听
查看>>
使用 HPC Pack 为 Azure 中的 Windows HPC 工作负荷创建和管理群集的选项
查看>>
xss
查看>>
iOS:百度长语音识别具体的封装:识别、播放、进度刷新
查看>>