今天咱们来说解释器模式【Interpreter Pattern】,如何理解这一个模式呢?一个简单的例子、中英文翻译器这个东西的做用是啥呢?将不知道的英文翻译成中文以便于理解、或者把中文翻译成英文来使用。其中目的也就是将语言进行翻译解释方便去理解使用。那么解释器模式呢?也有类似的逻辑、该模式实现了一个表达式接口、该接口解释一个特定的上下文。主要对于一些固定文法构建一个解释句子的解释器。html
在软件系统中,若是有一些特殊的领域问题较为复杂,疑似的模式不断重复出现。这样使用通常的编程方式会使程序编码极为频繁。在这样的状况下,将这种特定的领域的问题转换表达为某种语法规则的句子。构建一个解释器来解释这样的句子、从而能够达到解决问题的目的。正则表达式
给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子。编程
看上面的案例图,咱们一块儿看下其中包含的五个部份内容:设计模式
抽象表达式:定义解释器接口、约定的操做。其中Interpret接口专门用来实现解释器的功能bash
终结符表达式:实现抽象表达式要求的接口、文法中每个终结符都有其对应的具体终结表达式。ide
非终结表达式:文法中每个规则都须要一个具体的非终结符表达式、通常表示文法中的运算符或者一些关键字。ui
上下文类:这个角色用来存放终结符对应的具体的位置。this
客户端:指使用解释器的客户端。编码
咱们看看这么一个案例,在平常的程序开发中偶尔会遇到中文转阿拉伯数字。对于一些运算须要中文转数字计算。咱们看看这一问题如何解决吧:spa
namespace Interpreter_Pattern
{
class InterpreterPattern
{
}
/// <summary>
/// Context: 环境类
/// </summary>
public class Context
{
private string _statement;
public Context(string statement)
{
this._statement = statement;
contextMap.Add("一", 1);
contextMap.Add("二", 2);
contextMap.Add("三", 3);
contextMap.Add("四", 4);
contextMap.Add("五", 5);
contextMap.Add("六", 6);
contextMap.Add("七", 7);
contextMap.Add("八", 8);
contextMap.Add("九", 9);
}
public string Statement
{
get { return this._statement; }
set { this._statement = value; }
}
public Dictionary<string, int> contextMap = new Dictionary<string, int>();
}
/// <summary>
/// AbstractExpression: 抽象表达式
/// </summary>
public abstract class AbstractExpression
{
public abstract void Interpret(Context context);
}
public class TerminalExpression : AbstractExpression
{
public override void Interpret(Context context)
{
if (context.Statement!=null)
{
foreach (var Key in context.contextMap.Keys)
{
if (context.Statement.Contains(Key))
{
context.Statement= context.Statement.Replace(Key, context.contextMap[Key].ToString());// context.contextMap[Key]);
}
}
}
//return context;
}
}
public class NonterminalExpression : AbstractExpression
{
public override void Interpret(Context context)
{
if (context.Statement.Contains("加"))
{
context.Statement= context.Statement.Replace("加","+");
}
if (context.Statement.Contains("减"))
{
context.Statement= context.Statement.Replace("减", "-");
}
if (context.Statement.Contains("乘"))
{
context.Statement= context.Statement.Replace("乘", "*");
}
if (context.Statement.Contains("除"))
{
context.Statement= context.Statement.Replace("除", "/");
}
//return context;
}
}
}复制代码
namespace Interpreter_Pattern
{
class Program
{
static void Main(string[] args)
{
Context context = new Context("三加八加九减二乘五除三");
AbstractExpression abstractExpression = new TerminalExpression();
abstractExpression.Interpret(context);
AbstractExpression noabstractExpression = new NonterminalExpression();
noabstractExpression.Interpret(context);
Console.WriteLine(context.Statement);
}
}
}复制代码
一、能够将一个须要解释执行的语言中的句子表示为一个抽象语法树。
二、一些重复的问题可使用一种简单的语言进行表达。
三、语言的文法较为简单的时候能够考虑
一、可扩展性高、比较灵活。
二、增长了新的解释表达式的方式较为方便。
三、容易实现简单的文法。
一、可利用场景少。
二、对于复制的文法维护较为困难。
三、解释器模式会引发类的膨胀。
到这里咱们就看完了解释器模式,其实咱们仔细想一想正则表达式是否是也有点类似呢?正则表达式也是一个典型的解释器。解释器模式也就是给定一个语言,定义表示和解释器。而后用这个解释器来解释语言中的句子。解释器模式在日常的运用中较少、通常多用于表达式计算或者编译器、SQL语句解析等。到这里咱们已经介绍完了23种设计模式。咱们能够经过这个系列开头的文章进行一个总体的回顾。
用爱生活,你会使本身幸福!用爱工做,你会使不少人幸福!
欢迎你们扫描下方二维码,和我一块儿踏上设计模式的闯关之路吧!