专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »DotNet » 面向对象的设计模式:C#面向对象设计模式纵横谈 »正文

面向对象的设计模式:C#面向对象设计模式纵横谈

来源: 发布时间:星期一, 2008年9月22日 浏览:99次 评论:0
Interpreter模式是一种比较不常用的模式,因为这种模式存在一些弊端,他的使用有很大的条件限制。
Interpreter是一种特殊的设计模式,它建立一个解释器,对于特定的计算机程序设计语言,用来解释预先定义的文法。简单地说,Interpreter模式是一种简单的语法解释器构架。
先借用李建忠老师的代码例子

public class Program
{
static void Main()
{
string roman = "二十四万零二";

Context context = new Context(roman);
ArrayList tree = new ArrayList();
tree.Add(new GeExpression());
tree.Add(new ShiExpression());
tree.Add(new BaiExpression());
tree.Add(new QianExpression());
tree.Add(new WanExpression());

foreach(Expression exp in tree)
{
exp.Interpret(context);
}

Console.WriteLine("{0}={1}", roman, context.Data);

Console.Read();
}
}

public class Context
{
private string statement;
private int data;

public Context(string statement)
{
this.statement = statement;
}


public string Statement
{
get
{
return statement;
}
set
{
statement = value;
}
}

public int Data
{
get
{
return data;
}
set
{
data = value;
}
}
}

public abstract class Expression
{
protected Dictionary<string, int> table = new Dictionary<string,int>();

public Expression()
{
table.Add("一", 1);
table.Add("二", 2);
table.Add("三", 3);
table.Add("四", 4);
table.Add("五", 5);
table.Add("六", 6);
table.Add("七", 7);
table.Add("八", 8);
table.Add("九", 9);
}

public virtual void Interpret(Context context)
{
if(context.Statement.Length == 0)
{
return;
}


foreach(string key in table.Keys)
{
int value = table[key];
if(context.Statement.EndsWith(key + GetPostfix()))
{
context.Data += value * Multiplier();
context.Statement = context.Statement.Substring(0, context.Statement.Length - GetLength());
}

if(context.Statement.EndsWith("零"))
{
context.Statement = context.Statement.Substring(0, context.Statement.Length - 1);
}
}
}

public abstract string GetPostfix();
public abstract int Multiplier();
public virtual int GetLength()
{
return this.GetPostfix().Length + 1;
}
}

public class GeExpression : Expression
{

public override string GetPostfix()
{
return string.Empty;
}

public override int Multiplier()
{
return 1;
}

public override int GetLength()
{
return 1;
}
}

public class ShiExpression : Expression
{
public override string GetPostfix()
{
return "十";
}

public override int Multiplier()
{
return 10;
}
}

public class BaiExpression : Expression
{
public override string GetPostfix()
{
return "百";
}

public override int Multiplier()
{
return 100;
}
}

public class QianExpression : Expression
{
public override string GetPostfix()
{
return "千";
}

public override int Multiplier()
{
return 1000;
}
}

public class WanExpression : Expression
{
public override string GetPostfix()
{
return "万";
}

public override int Multiplier()
{
return 10000;
}

public override void Interpret(Context context)
{
if(context.Statement.Length == 0)
{
return;
}

ArrayList tree = new ArrayList();
tree.Add(new GeExpression());
tree.Add(new ShiExpression());
tree.Add(new BaiExpression());
tree.Add(new QianExpression());

foreach(string key in table.Keys)
{
if(context.Statement.EndsWith(this.GetPostfix()))
{
int temp = context.Data;
context.Data = 0;
context.Statement = context.Statement.Substring(0, context.Statement.Length - 1);

foreach(Expression exp in tree)
{
exp.Interpret(context);
}

context.Data = temp + this.Multiplier() * context.Data;
}
}
}
}

分析一下代码。
这段代码是将中文的数字转换为阿拉伯数字,如果按照面向过程的算法肯定是来截取字符串进行判断然后组合成正确的数字。在这段代码中则利用了interpreter模式将位数进行表达式的封装。
首先看抽象Expression类,首先他封装了一个字典类,这个字典保存了中文的1-9的字符及其对应的阿拉伯数字。Interpret方法,在便利字典中的每个中文数字,并且判断截取中文数字加其后缀是否是结尾,如果为真那么将对应的值乘以对应的位数,对应的位数是一个纯虚函数Multiplier,由派生类自己实现。在取得了对应的Expression的值后需要将中文数字语句中对应的字符串去掉,即GetLength函数,取得对应的位数符合加1。这是一个虚函数,可以由派生类重写。注意GeExpression就重写了此虚函数,因为个位数的长度是1,而不是位数符加1。

如果本文没有解决您的问题,请进老妖怪开发者社区提问

相关文章

读者评论

  • 共0条 分0页

发表评论

  • 昵称:
  • 内容: