面向对象设计模式之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).本篇则来学习下行为型模式的两个模式, 解 ...
随机推荐
- 2015第37周一struts2 jstl 标签
1.在jstl中使用struts2 <c:forEach var="ee" items="${requestScope.serviceList}" &g ...
- Count Primes ——LeetCode
Description: Count the number of prime numbers less than a non-negative number, n. 题目大意:给一个int,返回小于它 ...
- Rotate List —— LeetCode
Given a list, rotate the list to the right by k places, where k is non-negative. For example:Given 1 ...
- 光学字符识别OCR
1.功能: 光学字符识别(OCR,Optical Character Recognition)是指对文本资料进行扫描,然后对图像文件进行分析处理,获取文字及版面信息的过程 2.典型应用: 名片扫描 3 ...
- Eclipse的快捷键及常用设置
本篇文章转自:http://blog.csdn.net/idsunb/article/details/6604451 1.提示键配置一般默认情况下,Eclipse ,MyEclipse 的代码提示功能 ...
- How to distribute your own Android library through jCenter and Maven Central from Android Studio
In Android Studio, if you wish to include any library to your application. You could just simply add ...
- Tangled in Cables(Kruskal+map容器处理字符串)
/** 题意: 给你两个城市之间的道路(无向图),求出需要的 电缆.如果大于所提供的,就输出Not enough ... 否则输出所需要的电缆长度. 输入:N (给 ...
- qemu kvm 虚拟化
虚拟化: KVM是一个基于Linux内核的虚拟机,属于完全虚拟化.虚拟机监控的实现模型有两类:监控模型(Hypervisor)和宿主机模型(Host-based).由于监控模型需要进行处理器调度,还需 ...
- linux —— ubuntu 初次安装问题
本文收集了我自己安装ubuntu系统时的一些想法和遇到的一些问题,以及一些我自己感兴趣的软件的安装方法等 1. 50G ubuntu 分区方案 <plan> <key> / & ...
- python最简洁的条件判断语句写法
这篇文章主要介绍了Python返回真假值(True or False)小技巧,本文探讨的是最简洁的条件判断语句写法,本文给出了两种简洁写法,需要的朋友可以参考下 如下一段代码: def isLen(s ...