解释器模式 -- 大话设计模式
在今天,读书有时是件“麻烦”事。它需要你付出时间,付出精力,还要付出一份心境。--仅以《大话设计模式》来祭奠那逝去的……
解释器模式:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子
在软件开发特别是DSL开发中常常需要使用一些相对较复杂的业务语言,如果业务语言使用频率足够高,且使用普通的编程模式来实现会导致非常复杂的变化,那 么就可以考虑使用解释器模式构建一个解释器对复杂的业务语言进行翻译。这种做法虽然效率相对较低,但可以允许用户使用自定义的业务语言来处理逻辑,因此在 效率不是关键问题的场合还是较为有用的。
在实际的系统开发中使用的非常少,因为它会引起效率、性能以及维护等问题,一般在大中型的框架型项目能够找到它的身影,比如一些数据分析工具、报表设计工具、科学计算工具等等,若你确实遇到“一种特定类型的问题发生的频率足够高”的情况,准备使用解释器模式时,可以考虑一下Expression4J、MESP(Math Expression String Parser)、Jep等开源的解析工具包(这三个开源产品都可以百度、Google中搜索到,请读者自行查询),功能都异常强大,而且非常容易使用,效率也还不错,实现大多数的数学运算完全没有问题,自己没有必要从头开始编写解释器,有人已经建立了一条康庄大道,何必再走自己的泥泞小路呢?
1.四则运算
金融行业软件中,经常会遇到各种汇总、报表之类牵涉到四则运算,下面是简单的实现
定义上下文类(这个类根据需求自己扩展,也可以不定义)
/// <summary> /// 上下文类(包含解释器意外的全局信息) /// </summary> public class Context { /// <summary> /// 表达式(1+2) /// </summary> public string Expression { get; set; } /// <summary> /// 运算结果 /// </summary> public int Result { get; set; } }
定义解释器
/// <summary> /// 解释器(定义AbstractExpression接口或者抽象类) /// </summary> public abstract class AbstractExpression { public abstract int Interpret(int value, int result); } /// <summary> /// 加法解释器 /// </summary> public class AddExpression : AbstractExpression { public override int Interpret(int value, int result) { return result + value; } } /// <summary> /// 减法解释器 /// </summary> public class SubExpression : AbstractExpression { public override int Interpret(int value, int result) { return result - value; } }
定义一个帮助类,方便客户端调用
/// <summary> /// 对解释器进行封装,方便客户端使用 /// </summary> public class Operation { public static void Operate(Context context) { context.Expression = "+" + context.Expression; //对表达式进行封装 List<string> list = new List<string>(); while (context.Expression.Length > 0) { list.Add(context.Expression.Substring(0, 2)); context.Expression = context.Expression.Substring(2); } foreach (var v in list) { AbstractExpression expression = null; var operate = v.Substring(0, 1); switch (operate) { case "+": expression = new AddExpression(); break; case "-": expression = new SubExpression(); break; } context.Result = expression.Interpret(Convert.ToInt32(v.Substring(1, 1)), context.Result); } Console.WriteLine("运算结果为:{0}", context.Result); } }
开启场景模拟
static void Main(string[] args) { var str = "3+5+7"; Operation.Operate(new Context() { Expression = str, Result = 0 }); }
2.多语言翻译,待续……例子(http://www.cnblogs.com/saville/p/3379533.html)