Net设计模式实例之解释器模式(Interpreter Pattern)
来源:互联网 发布:程序员杂志 下载 编辑:程序博客网 时间:2024/06/05 20:35
一、解释器模式简介(Brief Introduction)
解释器模式(Interpreter Pattern),给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。使用了解释器模式,可以很容易地改变和扩展文法,因为该模式使用类来表示文法规则,可以使用继承来改变或扩展该文法。也比较容易实现文法,因为定义抽象语法树中各个节点的类的实现大体类似,这些类容易直接编写。
二、解决的问题(What To Solve)
如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子,这样就可以构建一个解释器,该解释器通过解释这些句子来解决问题。
三、解释器模式分析(Analysis)
1、解释器模式结构
AbstractExpression抽象类:声明一个接口,用于执行一个操作。
TerminalExpression类:终结符表达式,实现与文法中的终结符相关的解释操作。
NonterminalExpression类:非终结符表达式,为文法中的非终结符实现解释操作。对文法中每一条规则R1、R2.......RN都需要一个具体的非终结符表达式类。
Context类:包含解释器之外的一些全局信息。
2、源代码
1、抽象表达式AbstractExpression
public abstract class AbstractExpression
{
public abstract void Interpret(Context context);
}
2、终结符表达式TerminalExpression
public class TerminalExpression:AbstractExpression
{
public override void Interpret(Context context)
{
Console.WriteLine("调用终止符表达式Terminal.Interpret()");
}
}
3、非终结符表达式NonterminalExpression
public class NonterminalExpression:AbstractExpression
{
public override void Interpret(Context context)
{
Console.WriteLine("调用非终止符表达式Nonterminal.Interpret()");
}
}
4、上下文类Context
public class Context
{
}
5、客户端代码
static void Main(string[] args)
{
Context context = new Context();
ArrayList list = new ArrayList();
//填充语法树
list.Add(new TerminalExpression());
list.Add(new NonterminalExpression());
list.Add(new TerminalExpression());
list.Add(new TerminalExpression());
//解析
foreach (AbstractExpression abstractExpression in list)
{
abstractExpression.Interpret(context);
}
Console.ReadKey();
}
3、程序运行结果
四.解释器模式案例分析(Example)
1、场景
罗马字符转换为十进制数字,如下图所示
Expression抽象类:抽象表达式,声明一个抽象的解释器操作,这个抽象类为抽象语法树中所有的节点所共享。
ThousandExpression类:用来核对罗马字符中的 M ;
HundredExpression类:用来核对罗马字符中的C, CD, D or CM;
TenExpression类:用来核对罗马字附中的X, XL, L and XC;
OneExpression类:用来核对罗马字附中的I, II, III, IV, V, VI, VI, VII, VIII, IX。
2、代码
1、上下文类Context
class Context
{
private string _input;
private int _output;
public Context(string input)
{
this._input = input;
}
public string Input
{
get { return _input; }
set { _input = value; }
}
public int Output
{
get { return _output; }
set { _output = value; }
}
}
2、抽象表达式类Expression
abstract class Expression
{
public void Interpret(Context context)
{
if (context.Input.Length == 0)
return;
if (context.Input.StartsWith(Nine()))
{
context.Output += (9 * Multiplier());
context.Input = context.Input.Substring(2);
}
else if (context.Input.StartsWith(Four()))
{
context.Output += (4 * Multiplier());
context.Input = context.Input.Substring(2);
}
else if (context.Input.StartsWith(Five()))
{
context.Output += (5 * Multiplier());
context.Input = context.Input.Substring(1);
}
while (context.Input.StartsWith(One()))
{
context.Output += (1 * Multiplier());
context.Input = context.Input.Substring(1);
}
}
public abstract string One();
public abstract string Four();
public abstract string Five();
public abstract string Nine();
public abstract int Multiplier();
}
3、终止符表达式类ThousandExpression、HundredExpression、TenExpression等
/// <summary>
/// A 'TerminalExpression' class
/// <remarks>
/// 用来核对罗马字符中的 M
/// </remarks>
/// </summary>
class ThousandExpression : Expression
{
public override string One() { return "M"; }
public override string Four() { return " "; }
public override string Five() { return " "; }
public override string Nine() { return " "; }
public override int Multiplier() { return 1000; }
}
/// <summary>
/// A 'TerminalExpression' class
/// <remarks>
/// 用来核对罗马字符中的C, CD, D or CM;
/// </remarks>
/// </summary>
class HundredExpression : Expression
{
public override string One() { return "C"; }
public override string Four() { return "CD"; }
public override string Five() { return "D"; }
public override string Nine() { return "CM"; }
public override int Multiplier() { return 100; }
}
/// <summary>
/// A 'TerminalExpression' class
/// <remarks>
/// 用来核对罗马字附中的X, XL, L and XC
/// </remarks>
/// </summary>
class TenExpression : Expression
{
public override string One() { return "X"; }
public override string Four() { return "XL"; }
public override string Five() { return "L"; }
public override string Nine() { return "XC"; }
public override int Multiplier() { return 10; }
}
/// <summary>
/// A 'TerminalExpression' class
/// <remarks>
/// 用来核对罗马字附中的I, II, III, IV, V, VI, VI, VII, VIII, IX
/// </remarks>
/// </summary>
class OneExpression : Expression
{
public override string One() { return "I"; }
public override string Four() { return "IV"; }
public override string Five() { return "V"; }
public override string Nine() { return "IX"; }
public override int Multiplier() { return 1; }
}
4、客户端代码
static void Main(string[] args)
{
string roman = "MCMXXVIII";
Context context = new Context(roman);
// Build the 'parse tree'
List<Expression> tree = new List<Expression>();
tree.Add(new ThousandExpression());
tree.Add(new HundredExpression());
tree.Add(new TenExpression());
tree.Add(new OneExpression());
// Interpret
foreach (Expression exp in tree)
{
exp.Interpret(context);
}
Console.WriteLine("{0} = {1}",roman, context.Output);
Console.ReadKey();
}
3、运行结果
五、总结(Summary)
解释器模式(Interpreter Pattern),给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。当有一个语言需要解释执行,并且你可将该语言中的句子表示为一个抽象的语法树时,可以考虑使用解释器模式。
参考资料:http://www.dofactory.com/Patterns/PatternInterpreter.aspx
- Net设计模式实例之解释器模式(Interpreter Pattern)
- 设计模式总结之Interpreter Pattern(解释器模式)
- 设计模式 - Interpreter Pattern(解释器模式)
- 设计模式 - Interpreter Pattern(解释器模式)
- 设计模式【解释器模式Interpreter Pattern】
- 设计模式读书笔记之解释器模式(Interpreter pattern)
- 设计模式之解释器模式(Interpreter Pattern)
- 设计模式(行为型)之解释器模式(Interpreter Pattern)
- 设计模式读书笔记之解释器模式(Interpreter pattern)
- 设计模式之解释器模式--- Pattern Interpreter
- 浅谈设计模式:解释器模式(Interpreter Pattern)
- 【Java设计模式】· 解释器模式(Interpreter Pattern)
- .NET设计模式(20):解释器模式(Interpreter Pattern)
- "围观"设计模式(27)--行为型之解释器模式(Interpreter Pattern)
- 设计模式拾荒之解释器模式( Interpreter Pattern ): 最不容易实现的设计模式
- 解释器模式(Interpreter Pattern)
- 解释器模式(Interpreter Pattern)
- 解释器模式(Interpreter Pattern)
- MD5加密
- Git 常用命令
- 【软件测试】测试环境的建立
- 实战录 | Java中多种格式报表导出方案的比较
- js获取浏览器返回按钮事件
- Net设计模式实例之解释器模式(Interpreter Pattern)
- 上拉电阻和下拉电阻的选择
- TCP/IP、Http、Socket的区别
- Net设计模式实例之命令模式(Command Pattern)
- 输出字符串最后一个单词的长度
- Redis学习-数据结构
- 关于BETA、RC、ALPHA、Release、GA等版本号的意义
- 【Java】消化单例设计模式
- 小鱼的数字游戏