快捷搜索:

步步为营 .NET 设计模式学习笔记 二十三、Interp

概述

在软件构建历程中,假如某一特定领域的问题对照繁杂,类似的模式赓续重复呈现,假如应用通俗的编程要领来实现将面临异常频繁的变更。在这种环境下,将特定领域的问题表达为某种语律例则下的句子,然后构建一个说冥器来解释这样的句子,从而达到办理问题的目的。

意图

给定一个说话,定义它的文法的一种表示,并定义一种说冥器,这个说冥器应用该表示来解释说话中的句子。

布局图

角色阐明:

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模式实现,该模式仍是有用的。

您可能还会对下面的文章感兴趣: