面向对象设计模式之Interpreter解释器模式(行为型)
动机:在软件构建过程中 ,如果某一特定领域的问题比较复杂,类似的模式不断重复出现,如果使用普通的编程方式来实现将面临非常频繁的变化。在这种情况下,将特定领域的问题表达为某种语法规则的句子,然后构建一个解释器来解释这样的句子,从而达到解决问题的目的。
意图:给定一个语言,定义它的文法的一种表示,并定义一种解释器,这个解释器使用该表示来解释语言中的句子。
UML图解:

示例:接收中文形式的数字表示并能以罗马形式数字输出,应用解释器模式设计,如:四百七十一万六千四百五十二 =》4716452。代码如下
namespace Interpreter
{
/// <summary>
/// 定义一个数据上下文
/// </summary>
public class Context
{
string statement="";//待解释的数据
int data;//解释之后的数据
public Context (string statement)
{
this.statement = statement;
}
public int Data
{
get { return data; }
set { data = value; }
}
public string Statement
{
get { return statement; }
set { statement = value; }
} } /// <summary>
/// 抽象表达式解释器
/// </summary>
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);
} /// <summary>
/// 解释给定的中文表示数字上下文对象
/// </summary>
/// <param name="context"></param>
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 - GetLength());
}
if (context.Statement.EndsWith("零"))//应对如"四百七十一万零六千四百零五十二"中出现'零'的情况
{
context.Statement=context.Statement.Substring(0,context.Statement.Length-1);
}
}
} /// <summary>
/// 获取如“六千四百五十二”中,获取千位的'千'字,百位的'百'字,十位的'十'字
/// </summary>
/// <returns></returns>
public abstract string GetPostfix(); /// <summary>
/// 陪增级数(个-1,十位-10,百位-100,千位-1000)
/// </summary>
/// <returns></returns>
public abstract int Multiplier(); /// <summary>
/// 获取符合文法的一组长度(如获取“四百”,“五十”的长度)
/// </summary>
/// <returns></returns>
public virtual int GetLength()
{
return this.GetPostfix().Length + 1;
}
} /// <summary>
/// 个位解释器 解析个位
/// </summary>
public class GeExpression : Expression
{ public override string GetPostfix()
{
return "";
} public override int Multiplier()
{
return 1;
} public override int GetLength()
{
return 1;
}
} /// <summary>
/// 十位解释器 解析个位+十位
/// </summary>
public class ShiExpression : Expression
{ public override string GetPostfix()
{
return "十";
} public override int Multiplier()
{
return 10;
}
} /// <summary>
/// 百位解释器 解析个位+十位+百位
/// </summary>
public class BaiExpresssion : Expression
{ public override string GetPostfix()
{
return "百";
} public override int Multiplier()
{
return 100;
}
} /// <summary>
/// 千位解释器 解析个位+十位+百位+千位
/// </summary>
public class QianExpression : Expression
{ public override string GetPostfix()
{
return "千";
} public override int Multiplier()
{
return 1000;
}
} /// <summary>
/// 万位解释器 解析个位+十位+百位+千位+万位
/// </summary>
public class WanExpression : Expression
{
public override void Interpreter(Context context)
{
if (context.Statement.Length == 0)
{
return;
}
ArrayList tree = new ArrayList();
tree.Add(new GeExpression());
tree.Add(new ShiExpression());
tree.Add(new BaiExpresssion());
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 expression in tree)
{
expression.Interpreter(context);
}
context.Data = temp+this.Multiplier()*context.Data;
}
} } public override string GetPostfix()
{
return "万";
} public override int Multiplier()
{
return 10000;
}
}
//通过Interpreter模式很容易扩展亿相对的YiExpression类 public class App
{
public static void Main()
{ string chinese="四百七十一万六千四百五十二";
Context context =new Context(chinese);
ArrayList tree = new ArrayList();//需按顺序添加个十百千万等解释表达式对象
tree.Add(new GeExpression());
tree.Add(new ShiExpression());
tree.Add(new BaiExpresssion());
tree.Add(new QianExpression());
tree.Add(new WanExpression());
foreach (Expression exp in tree)
{
exp.Interpreter(context);
}
Console.WriteLine("{0}={1}",chinese,context.Data);
}
}
}
Interpreter模式的几个要点:
1.Interpreter模式的应用场景时Interpreter模式应用中的难点,只有满足“业务规则频繁变化,且 类似的模式不断重复出现,并且容易抽象为语法规则的问题”才合适使用Interpreter模式。
2.使用Interpreter模式来表示文法规则,从而可以使用面向对象技巧来方便地“扩展”文法。
3.Interpreter模式比较适合简单的文法表示,对于复杂的文法表示,Interpreter模式会产生比较大的类 层次结构,需要求助于语法分析生成器这样的标准工具。
面向对象设计模式之Interpreter解释器模式(行为型)的更多相关文章
- 设计模式(15)--Interpreter(解释器模式)--行为型
作者QQ:1095737364 QQ群:123300273 欢迎加入! 1.模式定义: 解释器模式是类的行为模式.给定一个语言之后,解释器模式可以定义出其文法的一种表示,并同时提供一个解 ...
- 设计模式15:Interpreter 解释器模式(行为型模式)
Interpreter 解释器模式(行为型模式) 动机(Motivation) 在软件构建过程中,如果某一特定领域的问题比较复杂,类似的模式不断重复出现,如果使用普通的编程方式来实现将面临非常频繁的变 ...
- 23、Interpreter 解释器模式
1.Interpreter 解释器模式 解释器模式是一种使用频率相对较低但学习难度较大的设计模式,它用于描述如何使用面向对象语言构成一个简单的语言解释器.在某些情况下,为了更好地描述某一些特定类型的问 ...
- 二十三、Interpreter 解释器模式
设计: 代码清单: Node public abstract class Node { public abstract void parse(Context context) throws Parse ...
- 设计模式之笔记--解释器模式(Interpreter)
解释器模式(Interpreter) 定义 解释器模式(Interpreter),给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子. 类图 描述 Expr ...
- 《JAVA设计模式》之解释器模式(Interpreter)
在阎宏博士的<JAVA与模式>一书中开头是这样描述解释器(Interpreter)模式的: 解释器模式是类的行为模式.给定一个语言之后,解释器模式可以定义出其文法的一种表示,并同时提供一个 ...
- Interpreter(解释器)-类行为型模式
1.意图 给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子. 2.动机 如果一种特定类型的问题发生的频率足够高,那么可能就值的将该问题的各个实例表述为一个 ...
- Java进阶篇设计模式之九----- 解释器模式和迭代器模式
前言 在上一篇中我们学习了行为型模式的责任链模式(Chain of Responsibility Pattern)和命令模式(Command Pattern).本篇则来学习下行为型模式的两个模式, 解 ...
- Java设计模式之九 ----- 解释器模式和迭代器模式
前言 在上一篇中我们学习了行为型模式的责任链模式(Chain of Responsibility Pattern)和命令模式(Command Pattern).本篇则来学习下行为型模式的两个模式, 解 ...
随机推荐
- datagridview bindingsource
调用bindindsource的ResetBindings() 方法
- cocos2d的框架思路
这是我第一次写cocos的框架思路哈,虽然只是写完了一个程序,按理来说应该再多写一些,多积累一些经验了再来写这个框架的构成,但是我觉得还是把我这次写代码的所有想法先记下来哈,等到以后继续写cocos的 ...
- 安装 macbook 双系统( OS X 和 Ubuntu )
打算 macbook 上面多安装一个 ubuntu 系统来用下.流程大致下面几步: 1. 备份重要资料 2. 划分硬盘区域用于安装 ubuntu 3. 下载 ubuntu ISO 文件,并刻录到 U ...
- SRM 396(1-250pt)
DIV1 250pt 题意:对于一个字符串s,若对于每一个i = 0 to s.size()-p-1都有s[i] = s[i+p]则称字符串s是p循环的."CATCATC", &q ...
- 用phpQuery像jquery一样解析html代码
简介 如何在php中方便地解析html代码,估计是每个phper都会遇到的问题.用phpQuery就可以让php处理html代码像jQuery一样方便. 项目地址:https://code.googl ...
- A - Til the Cows Come Home
裸的最短路,试一下刚看的spfa,虽然没有看代码,不过明白了大致的思想,先写一下试试吧,而且是个稀疏图,应该会很快吧. SPFA 算法采用图的存储结构是邻接表,方法是动态优化逼近法.算法中设立了一个先 ...
- M - 非常可乐
很明显看出来的广搜题目,不过因为有3个杯子相互倾倒,所以会产生6种倒发,比较冗杂,不过应该可以构造一个数组来解决这个问题,试试看吧 ////////////////////////////////// ...
- leetcode第一刷_Interleaving String
有关这样的字符串的题真是层出不穷啊,并且他们都有这样一个特点,就是递归的思路如此简单,但一定超时! 这个时候,dp就朝我们缓缓走来.递归超,dp搞!这道题的状态转移方程还是比較好写的,用ispart[ ...
- PreTranslateMessage作用和用法
PreTranslateMessage作用和用法 PreTranslateMessage是消息在送给TranslateMessage函数之前被调用的,绝大多数本窗体的消息都要通过这里,比較经常使用, ...
- java 连接数据库mysql的方法
1.把那个文件配置好环境变量. 2.创建数据库,插入数据 注意的地方: (1)环境变量 classpath(可大写,也可以小写,可放在个人变量,也可以试系统变量) 里面的值 F:\mysql-conn ...