场景:把中文数字转换成罗马数字,如把九万九千九百九十九转换成99999,并且方便扩展到其它位,如扩展到亿位。
结构
代码
/**/
/*
* 上下文
*/
namespace DesignPattern.Interpreter
{
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;
}
}
}
}
* 上下文
*/
namespace DesignPattern.Interpreter
{
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;
}
}
}
}
/**/
/*
* 解释器
*/
namespace DesignPattern.Interpreter
{
public abstract class Expression
{
protected Dictionary<string, int> table = new Dictionary<string, int>(9);
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 abstract string GetPostfix();
public abstract int Multiplier();
public virtual int GetLength()
{
return this.GetPostfix().Length + 1;
}
public virtual void Interpreter(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 * this.Multiplier();
context.Statement = context.Statement.Substring(0, context.Statement.Length - this.GetLength());
}
if (context.Statement.EndsWith("零"))
{
context.Statement = context.Statement.Substring(0, context.Statement.Length - this.GetLength());
}
}
}
}
public class GeExpression : Expression
{
public override string GetPostfix()
{
return "";
}
public override int Multiplier()
{
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 Interpreter(Context context)
{
if (context.Statement.Length == 0)
{
return;
}
IList<Expression> expressionCollection = new List<Expression>();
expressionCollection.Add(new GeExpression());
expressionCollection.Add(new ShiExpression());
expressionCollection.Add(new BaiExpression());
expressionCollection.Add(new QianExpression());
foreach (string key in table.Keys)
{
int temp = context.Data;
context.Data = 0;
context.Statement = context.Statement.Substring(0, context.Statement.Length - 1);
foreach(Expression expression in expressionCollection)
{
expression.Interpreter(context);
}
context.Data += temp + this.Multiplier() * context.Data;
}
}
}
}
* 解释器
*/
namespace DesignPattern.Interpreter
{
public abstract class Expression
{
protected Dictionary<string, int> table = new Dictionary<string, int>(9);
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 abstract string GetPostfix();
public abstract int Multiplier();
public virtual int GetLength()
{
return this.GetPostfix().Length + 1;
}
public virtual void Interpreter(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 * this.Multiplier();
context.Statement = context.Statement.Substring(0, context.Statement.Length - this.GetLength());
}
if (context.Statement.EndsWith("零"))
{
context.Statement = context.Statement.Substring(0, context.Statement.Length - this.GetLength());
}
}
}
}
public class GeExpression : Expression
{
public override string GetPostfix()
{
return "";
}
public override int Multiplier()
{
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 Interpreter(Context context)
{
if (context.Statement.Length == 0)
{
return;
}
IList<Expression> expressionCollection = new List<Expression>();
expressionCollection.Add(new GeExpression());
expressionCollection.Add(new ShiExpression());
expressionCollection.Add(new BaiExpression());
expressionCollection.Add(new QianExpression());
foreach (string key in table.Keys)
{
int temp = context.Data;
context.Data = 0;
context.Statement = context.Statement.Substring(0, context.Statement.Length - 1);
foreach(Expression expression in expressionCollection)
{
expression.Interpreter(context);
}
context.Data += temp + this.Multiplier() * context.Data;
}
}
}
}
/**/
/*
* 客户程序
*/
namespace DesignPattern.Interpreter
{
public class Client
{
private string chineseDigit;
private Context context;
IList<Expression> expressionCollection = new List<Expression>();
public Client(string chineseDigit)
{
this.chineseDigit = chineseDigit;
context = new Context(chineseDigit);
expressionCollection.Add(new GeExpression());
expressionCollection.Add(new ShiExpression());
expressionCollection.Add(new BaiExpression());
expressionCollection.Add(new QianExpression());
}
public string ChineseDigit
{
get
{
return chineseDigit;
}
set
{
value = chineseDigit;
}
}
public int GetRomanDigit()
{
foreach (Expression expression in expressionCollection)
{
expression.Interpreter(context);
}
return context.Data;
}
}
}
* 客户程序
*/
namespace DesignPattern.Interpreter
{
public class Client
{
private string chineseDigit;
private Context context;
IList<Expression> expressionCollection = new List<Expression>();
public Client(string chineseDigit)
{
this.chineseDigit = chineseDigit;
context = new Context(chineseDigit);
expressionCollection.Add(new GeExpression());
expressionCollection.Add(new ShiExpression());
expressionCollection.Add(new BaiExpression());
expressionCollection.Add(new QianExpression());
}
public string ChineseDigit
{
get
{
return chineseDigit;
}
set
{
value = chineseDigit;
}
}
public int GetRomanDigit()
{
foreach (Expression expression in expressionCollection)
{
expression.Interpreter(context);
}
return context.Data;
}
}
}
要点:
1、本模式应用场景:只有满足“业务规则频繁变化,且类似的模式不断重复出现,并且容易抽象成语法规则的问题”。
2、使用本模式来表达文法规则,从而可以使用面向对象技巧来方便地扩展文法。
3、本模式比较适合简单的文法表示,对于复杂的文法表示,本模式会产生比较大的类层次结构,需要求助于语法分析生成器这样的标准工具。