Interpreter Expression 解释器模式
简介
Interpreter模式也叫解释器模式,是由GoF提出的23种设计模式中的一种。Interpreter是行为模式之一,它是一种特殊的设计模式,它建立一个解释器,对于特定的计算机程序设计语言,用来解释预先定义的文法。应用环境:如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题。而且当【文法简单】、【效率不是关键问题】的时候效果最好。当有一个语言需要【解释执行】,并且你可将该语言中的句子表示为一个【抽象语法树】,可以使用解释器模式。角色:
- 抽象表达式角色(AbstractExpression): 声明一个抽象的解释操作,这个接口为所有具体表达式角色都要实现的
- 终结符表达式角色(TerminalExpression): 实现与文法中的元素相关联的解释操作,通常一个解释器模式中只有一个终结符表达式,但有多个实例对应不同的终结符
- 非终结符表达式角色(NonterminalExpression): 文法中的每条规则对应于一个非终结表达式,非终结表达式根据逻辑的复杂程度而增加,原则上每个文法规则都对应一个非终结符表达式
- 环境角色(Context): 包含解释器之外的一些全局信息
优点:
- 解释器是一个简单语法分析工具,它最显著的优点就是【扩展性】,修改语法规则只要修改相应的【非终结符表达式】就可以了,若扩展语法,则只要增加【非终结符类】就可以了。
缺点:
- 解释器模式会引起【类膨胀】,每个语法都要产生一个非终结符表达式,语法规则比较复杂时,可能产生大量的类文件,难以维护
- 解释器模式采用【递归调用】方法,它导致调试非常复杂
- 解释器由于使用了大量的循环和递归,所以当用于解析复杂、冗长的语法时,【效率】是难以忍受的
注意事项:
- 尽量不要在重要模块中使用解释器模式,因为维护困难。在项目中,可以使用shell,JRuby,Groovy等脚本语言来代替解释器模式。
作用:用一组类代表某一规则类图:四则运算这个模式通常定义了一个语言的语法,然后解析相应语法的语句。java.util.Patternjava.text.Normalizerjava.text.Format
经典案例
public class Test2 {public static void main(String[] args) {//计算(7*8)/(7-8+2)的值Context context = new Context();context.addValue("a", 7);context.addValue("b", 8);context.addValue("c", 2);AbstractExpression multiplyValue = new MultiplyNTExpression(new TerminalExpression(context.getValue("a")), new TerminalExpression(context.getValue("b")));//a*bAbstractExpression subtractValue = new SubtractNTExpression(new TerminalExpression(context.getValue("a")), new TerminalExpression(context.getValue("b")));//a-bAbstractExpression addValue = new AddNTExpression(subtractValue, new TerminalExpression(context.getValue("c")));//(a-b)+cAbstractExpression divisionValue = new DivisionNTExpression(multiplyValue, addValue);//(a*b)/(a-b+c)System.out.println(divisionValue.interpreter(context));}}class Context {private Map<String, Integer> valueMap = new HashMap<String, Integer>();public void addValue(String key, int value) {valueMap.put(key, value);}public int getValue(String key) {return valueMap.get(key);}}/**抽象表达式角色(AbstractExpression): 声明一个抽象的解释操作,这个接口为所有具体表达式角色都要实现的*/abstract class AbstractExpression {public abstract int interpreter(Context context);}/**终结符表达式角色(TerminalExpression): 实现与文法中的元素相关联的解释操作,通常一个解释器模式中只有一个终结符表达式,但有多个实例对应不同的终结符*/class TerminalExpression extends AbstractExpression {//Terminal 终结符,末期的,晚期的。终结符就是语言中用到的基本元素,一般不能再被分解private int i;public TerminalExpression(int i) {this.i = i;}@Overridepublic int interpreter(Context context) {//不进行任何操作return i;}}/**非终结符表达式角色(NonterminalExpression): 文法中的每条规则对应于一个非终结表达式,非终结表达式根据逻辑的复杂程度而增加*/class AddNTExpression extends AbstractExpression {//Nonterminal 非终结符号,非末端private AbstractExpression left;private AbstractExpression right;public AddNTExpression(AbstractExpression left, AbstractExpression right) {this.left = left;this.right = right;}@Overridepublic int interpreter(Context context) {return left.interpreter(context) + right.interpreter(context);//加法操作}}class SubtractNTExpression extends AbstractExpression {private AbstractExpression left;private AbstractExpression right;public SubtractNTExpression(AbstractExpression left, AbstractExpression right) {this.left = left;this.right = right;}@Overridepublic int interpreter(Context context) {return left.interpreter(context) - right.interpreter(context);//减法操作}}class MultiplyNTExpression extends AbstractExpression {private AbstractExpression left;private AbstractExpression right;public MultiplyNTExpression(AbstractExpression left, AbstractExpression right) {this.left = left;this.right = right;}@Overridepublic int interpreter(Context context) {return left.interpreter(context) * right.interpreter(context);//乘法操作}}class DivisionNTExpression extends AbstractExpression {private AbstractExpression left;private AbstractExpression right;public DivisionNTExpression(AbstractExpression left, AbstractExpression right) {this.left = left;this.right = right;}@Overridepublic int interpreter(Context context) {int value = right.interpreter(context);if (value != 0) return left.interpreter(context) / value;//除法操作return -1111;}}
演示
public class Context {private Map<Variable, Boolean> map = new HashMap<Variable, Boolean>();public void assign(Variable var, boolean value) {map.put(var, new Boolean(value));}public boolean lookup(Variable var) throws IllegalArgumentException {Boolean value = map.get(var);if (value == null) throw new IllegalArgumentException();return value.booleanValue();}}public abstract class Expression {/**以环境为准,本方法解释给定的任何一个表达式 */public abstract boolean interpret(Context ctx);@Overridepublic int hashCode() {return this.toString().hashCode();}}class Constant extends Expression {private boolean value;public Constant(boolean value) {this.value = value;}@Overridepublic boolean equals(Object obj) {if (obj != null && obj instanceof Constant) {return this.value == ((Constant) obj).value;}return false;}@Overridepublic boolean interpret(Context ctx) {return value;}@Overridepublic String toString() {return new Boolean(value).toString();}}class Variable extends Expression {private String name;public Variable(String name) {this.name = name;}@Overridepublic boolean equals(Object obj) {if (obj != null && obj instanceof Variable) {return this.name.equals(((Variable) obj).name);}return false;}@Overridepublic String toString() {return name;}@Overridepublic boolean interpret(Context ctx) {return ctx.lookup(this);}}class And extends Expression {private Expression left, right;public And(Expression left, Expression right) {this.left = left;this.right = right;}@Overridepublic boolean equals(Object obj) {if (obj != null && obj instanceof And) {return left.equals(((And) obj).left) && right.equals(((And) obj).right);}return false;}@Overridepublic boolean interpret(Context ctx) {return left.interpret(ctx) && right.interpret(ctx);}@Overridepublic String toString() {return "(" + left.toString() + " AND " + right.toString() + ")";}}class Or extends Expression {private Expression left, right;public Or(Expression left, Expression right) {this.left = left;this.right = right;}@Overridepublic boolean equals(Object obj) {if (obj != null && obj instanceof Or) {return this.left.equals(((Or) obj).left) && this.right.equals(((Or) obj).right);}return false;}@Overridepublic boolean interpret(Context ctx) {return left.interpret(ctx) || right.interpret(ctx);}@Overridepublic String toString() {return "(" + left.toString() + " OR " + right.toString() + ")";}}class Not extends Expression {private Expression exp;public Not(Expression exp) {this.exp = exp;}@Overridepublic boolean equals(Object obj) {if (obj != null && obj instanceof Not) {return exp.equals(((Not) obj).exp);}return false;}@Overridepublic boolean interpret(Context ctx) {return !exp.interpret(ctx);}@Overridepublic String toString() {return "(Not " + exp.toString() + ")";}}public class Test {public static void main(String[] args) {Context ctx = new Context();Variable x = new Variable("x");Variable y = new Variable("y");Constant c = new Constant(true);ctx.assign(x, false);ctx.assign(y, true);Expression exp = new Or(new And(c, x), new And(y, new Not(x)));System.out.println("x=" + x.interpret(ctx));System.out.println("y=" + y.interpret(ctx));System.out.println(exp.toString() + "=" + exp.interpret(ctx));}}
附件列表
Interpreter Expression 解释器模式的更多相关文章
- Interpreter Expression 解释器模式 MD
解释器模式 简介 Interpreter模式也叫解释器模式,是行为模式之一,它是一种特殊的设计模式,它建立一个解释器,对于特定的计算机程序设计语言,用来解释预先定义的文法. 应用环境: 如果一种特定类 ...
- 解释器模式(Interpreter)
解释器模式(Interpreter)解释器模式是我们暂时的最后一讲,一般主要应用在OOP开发中的编译器的开发中,所以适用面比较窄. Context类是一个上下文环境类,Plus和Minus分别是用来计 ...
- Atitit.linq java的原理与实现 解释器模式
Atitit.linq java的原理与实现 解释器模式 1. Linq from where 的实现1 2. Where expr 的实现1 3. Attilax的一点变化2 4. 解释器模式的 ...
- 解释器模式(Interpreter、Context、Expression)
(给定一门语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子.) 解释器模式的定义是一种按照规定语法进行解析的方案,在现在项目中使用的比较少,其定义如下: Given ...
- [工作中的设计模式]解释器模式模式Interpreter
一.模式解析 解释器模式是类的行为模式.给定一个语言之后,解释器模式可以定义出其文法的一种表示,并同时提供一个解释器.客户端可以使用这个解释器来解释这个语言中的句子. 以上是解释器模式的类图,事实上我 ...
- 深入浅出设计模式——解释器模式(Interpreter Pattern)
模式动机 如果在系统中某一特定类型的问题发生的频率很高,此时可以考虑将这些问题的实例表述为一个语言中的句子,因此可以构建一个解释器,该解释器通过解释这些句子来解决这些问题.解释器模式描述了如何构成一个 ...
- 【设计模式 - 15】之解释器模式(Interpreter)
1 模式简介 解释器模式允许我们自定义一种语言,并定义一个这种语言的解释器,这个解释器用来解释语言中的句子.由于这种模式主要用于编译器的编写,因此在日常应用中不是很常用. 如果一种特定类型的 ...
- 面向对象设计模式之Interpreter解释器模式(行为型)
动机:在软件构建过程中 ,如果某一特定领域的问题比较复杂,类似的模式不断重复出现,如果使用普通的编程方式来实现将面临非常频繁的变化.在这种情况下,将特定领域的问题表达为某种语法规则的句子,然后构建一个 ...
- 第19章 解释器模式(Interpreter Pattern)
原文 第19章 解释器模式(Interpreter Pattern) 解释器模式 导读:解释器模式,平常用的比较的少,所以在写这个模式之前在博客园搜索了一番,看完之后那叫一个头大.篇幅很长,我鼓足了劲 ...
随机推荐
- postgresql 多实例运行
创建新的实例, (下面所用到的9.1版本,如果为其他版本,可以用版本号替换9.1) sudo /usr/bin/pg_createcluster -U postgres ...
- Problem:To Connect with MySQL in Virtual PC Environment
I'm trying to build a 1:n dev environment,with the help of Vsever(just like VMware worked on sever) ...
- Nopcommerce架构浅谈之文件结构
应该是在两年前了,在拜读园子里大神的文章时偶然了解到有个叫NopCommerce的商城系统,苦于没有时间,各种耽误,其中研究过一段时间,也就是一个星期时间,后来又耽搁了,直到最近,随着项目进入间歇期, ...
- 研究不定数量参数的函数并实现一个printf函数
一.前提知识 1.如何传递参数(主函数) a.函数的参数是通过栈传递,而且是从右到左依次入栈 b.即使是char型变量,在传递参数时,也是占用两个字节,因为push操作是两个字节为单位的. c.sho ...
- Python 字典 Print 格式化
__author__ = 'dell' ab = {'Swaroop': 'swaroopch@byteofpython.info', 'Larry': 'larry@wall.org', 'Mats ...
- Android 安装过程中的问题
Android 安装过程中的问题 上一篇我说到配置android环境,但是在具体的安装过程中,因为下载的软件或者方法不同,导致没有正确的结果,如果有一些错误的时候,可以试一试关闭eclipse软件, ...
- iOS之H5和Native混合开发
今天需要用到一个H5和Native 混合开发的项目,简单的写一点入门的东西,很简答: 先介绍一下简单的配置步骤: 1.新建项目:SB拖一个UIWebView 按住Ctrl 拖线delegate 设置为 ...
- Arbitrage
Description Arbitrage is the use of discrepancies in currency exchange rates to transform one unit o ...
- Delphi 指针大全(光看不练是学不会的)
大家都认为,C语言之所以强大,以及其自由性,很大部分体现在其灵活的指针运用上.因此,说指针是C语言的灵魂,一点都不为过.同时,这种说法也让很多人产生误解,似乎只有C语言的指针才能算指针.Basic不支 ...
- COJ 0349 WZJ的旅行(五)
WZJ的旅行(五) 难度级别:E: 运行时间限制:3000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 WZJ又要去旅行了T^T=0.幻想国由N个城市组成,由于道 ...