初尝Interpretor 模式
这个模式,一般用的很少。通常一个解释器,都会有专门的对象或者更底层(更高效)的工具来解决相应的问题。但有通常,就会有特殊的情况。当我们需要剖析某个具有结构性的对象,而这个对象并没有那么庞大时,就可以采用Interpretor 模式。
意图:
给定一个语言,定义它的文法的一种表示,并定义一种解释器,这个解释器使用该表示来解释语言中的句子。
结构图:
这个模式让我纠结了几天。原因不在理解这个模式本身,而是老师在课堂举的一个解释器的例子(将汉语数字转换成阿拉伯数字。比如:九千一百二十万六千三百二十一 –>91206321 )这样的计算处理,不用设计模式,也能实现。但,使用了设计模式,可以在代码复用以及一些小型的语法处理问题得到很好的效果。当然最后还是实现了,但这充分说明,自己实现一个解释器,并不容易。
在写代码的过程中,我有尝试从最高位向低位来转换,但发现后期扩展就受到了这个方向的限制。所以,我得出了一个不完全的总结,就是在使用Interpretor 模式的过程中,应该先从最小的单位单元(个位)进行,然后依次递增。
代码:
using System;
using System.Collections;
using System.Collections.Generic;
namespace DesignPattern
{
class Program
{
static void Main(string[] args)
{
//初始化翻译数据...
string[] numbers = { "九千一百二十万",
"九千一百二十万六千三百二十一",
"六千",
"六千零一",
"六千零一十",
"六千一",
"六千一百",
"六千二百一十",
"六千二百一",
"六千二百零一",
"六千零二十一",
"六千三百二十一",
"一百",
"一百一",
"一百一十",
"一百零一",
"一百一十一",
"二十一",
"二十",
"八" };
ArrayList contextList = new ArrayList();
for (int i = 0; i < numbers.Length; i++)
{
contextList.Add(new Context(numbers[i]));
}
//初始化编译器...
OneExpression one = new OneExpression();
TenExpression ten = new TenExpression();
HundredExpression hun = new HundredExpression();
ThousandExpression thou = new ThousandExpression();
TenThousandExpression tenThou = new TenThousandExpression();
ArrayList list = new ArrayList();
list.Add(one);
list.Add(ten);
list.Add(hun);
list.Add(thou);
list.Add(tenThou);
//开始翻译工作啦...
foreach (Context c in contextList)
{
Console.Write("Input: {0}\t", c.Input);
foreach (Expression ex in list)
ex.Interprete(c);
Console.WriteLine("Output: {0}", c.Output);
}
}
}
class Context {
private string _input;
public string Input
{
get { return _input; }
set { _input = value; }
}
private long _output;
public long Output
{
get { return _output; }
set { _output = value; }
}
public Context(string input) {
this._input = input;
}
}
abstract class Expression
{
protected Dictionary charDic = new Dictionary();
protected Stack mutiplier = new Stack();
protected int _data;
public Expression()
{
charDic.Add("一", 1);
charDic.Add("二", 2); charDic.Add("两", 2);
charDic.Add("三", 3); charDic.Add("四", 4);
charDic.Add("五", 5); charDic.Add("六", 6);
charDic.Add("七", 7); charDic.Add("八", 8);
charDic.Add("九", 9);
}
public abstract void Interprete(Context context);
}
class OneExpression : Expression
{
public override void Interprete(Context context)
{
//throw new NotImplementedException();
if (context.Input.Length <= 0) return;
if (context.Input.Length == 1)
{
if (charDic.ContainsKey(context.Input))
{
this._data = charDic[context.Input];
context.Output += this._data;
context.Input = String.Empty;
return;
}
}
string lastWord = context.Input.Substring(context.Input.Length - 1);
string preWord = context.Input.Substring(0, context.Input.Length - 1);
if (context.Input.Length == 2)
{
if (charDic.ContainsKey(lastWord))
{
this._data = charDic[lastWord];
context.Output += this._data;
context.Input = context.Input.Substring(0, context.Input.Length - 1);
}
}
if (context.Input.Length > 2)
{
if (charDic.ContainsKey(lastWord))
{
if (preWord.EndsWith("十") || preWord.EndsWith("零"))
{
this._data = charDic[lastWord];
context.Output += this._data;
context.Input = context.Input.Substring(0, context.Input.Length - 2);
}
}
}
}
}
class TenExpression : Expression
{
public override void Interprete(Context context)
{
if (context.Input.Length <= 0) return;
if (context.Input.Length == 1)
{
if (this.charDic.ContainsKey(context.Input))
{
context.Output += charDic[context.Input] * 10;
}
if (context.Input.Equals("十"))
{
context.Output += 10;
}
context.Input = String.Empty;
return;
}
string lastWord = context.Input.Substring(context.Input.Length - 1);
string preWord = context.Input.Substring(0, context.Input.Length - 1);
if (context.Input.Length == 2)
{
if (lastWord.Equals("十"))
{
if (this.charDic.ContainsKey(preWord))
{
context.Output += this.charDic[preWord] * 10;
context.Input = String.Empty;
}
}
}
if (context.Input.Length > 2)
{
if (lastWord.Equals("十"))
{
lastWord = preWord.Substring(preWord.Length - 1);
preWord = preWord.Substring(0, preWord.Length - 1);
}
if (this.charDic.ContainsKey(lastWord))
{
if (preWord.EndsWith("百") || preWord.EndsWith("零"))
{
this._data = this.charDic[lastWord];
context.Output += this._data * 10;
context.Input = preWord.Substring(0, preWord.Length - 1);
}
}
}
}
}
class HundredExpression : Expression
{
public override void Interprete(Context context)
{
if (context.Input.Length == 0) return;
if (context.Input.Length == 1)
{
if (this.charDic.ContainsKey(context.Input))
{
this._data = this.charDic[context.Input];
context.Output += this._data * 100;
}
context.Input = String.Empty;
return;
}
string lastWord = context.Input.Substring(context.Input.Length - 1);
string preWord = context.Input.Substring(0, context.Input.Length - 1);
if (context.Input.Length == 2)
{
if (lastWord.Equals("百"))
{
if (this.charDic.ContainsKey(preWord))
{
context.Output += this.charDic[preWord] * 100;
context.Input = String.Empty;
}
}
}
if (context.Input.Length > 2)
{
if (lastWord.Equals("百"))
{
lastWord = preWord.Substring(preWord.Length - 1);
preWord = preWord.Substring(0, preWord.Length - 1);
}
if (this.charDic.ContainsKey(lastWord))
{
if (preWord.EndsWith("千") || preWord.EndsWith("零"))
{
this._data = this.charDic[lastWord];
context.Output += this._data * 100;
context.Input = preWord.Substring(0, preWord.Length - 1);
}
}
}
}
}
class ThousandExpression : Expression
{
public override void Interprete(Context context)
{
if (context.Input.Length <= 0) return;
if (context.Input.Length == 1)
{
if (this.charDic.ContainsKey(context.Input))
{
this._data = this.charDic[context.Input];
context.Output += this._data * 1000;
}
context.Input = String.Empty;
return;
}
string lastWord = context.Input.Substring(context.Input.Length - 1);
string preWord = context.Input.Substring(0, context.Input.Length - 1);
if (context.Input.Length == 2)
{
if (lastWord.Equals("千"))
{
if (this.charDic.ContainsKey(preWord))
{
context.Output += this.charDic[preWord] * 1000;
context.Input = String.Empty;
}
}
}
if (context.Input.Length > 2)
{
if (lastWord.Equals("千"))
{
lastWord = preWord.Substring(preWord.Length - 1);
preWord = preWord.Substring(0, preWord.Length - 1);
}
if (this.charDic.ContainsKey(lastWord))
{
if (preWord.EndsWith("万") || preWord.EndsWith("零"))
{
this._data = this.charDic[lastWord];
context.Output += this._data * 1000;
context.Input = preWord.Substring(0, preWord.Length - 1);
}
}
}
}
}
class TenThousandExpression : Expression
{
public override void Interprete(Context context)
{
if (context.Input.Length <= 0) return;
if (context.Input.EndsWith("万"))
{
context.Input = context.Input.Substring(0, context.Input.Length - 1);
}
long temp = context.Output;
context.Output = 0;
OneExpression one = new OneExpression();
TenExpression ten = new TenExpression();
HundredExpression hun = new HundredExpression();
ThousandExpression thou = new ThousandExpression();
ArrayList list = new ArrayList();
list.Add(one);
list.Add(ten);
list.Add(hun);
list.Add(thou);
foreach (Expression ex in list)
{
ex.Interprete(context);
}
context.Output *= 10000;
context.Output += temp;
}
}
}
运行结果:
这里是测试程序,如果有bug,请联系我哟。点击下载:Interpretor 演示代码 (36)


近期评论