首页
设计模式
常用bat文件
Maven教程
前端公共工具类
mongodb
算法收集与实现
Sqlserver常用知识
Oracle常用知识梳理
更多……
申请加入课程
单例模式
外观模式
工厂模式
建造者模式
原型模式
适配器模式
桥接模式
过滤器模式
组合模式
装饰器模式
享元模式
代理模式
责任链模式
命令模式
解释器模式
迭代器模式
中介者模式
备忘录模式
观察者模式
状态模式
空对象模式
策略模式
模板模式
访问者模式
MVC 模式
业务代表模式
组合实体模式
数据访问对象模式
前端控制器模式
拦截过滤器模式
服务定位器模式
传输对象模式
解释器模式
星辰
2018-09-17
0
0
185
人
0
人评论
0
人举报
# 解释器模式 > 解释器模式(Interpreter),给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子  ## 描述 * Expression:抽象表达式,声明一个所有的具体表达式都需要实现的抽象接口;这个接口主要是一个interpret()方法,称做解释操作。 * Terminal Expression:终结符表达式,实现了抽象表达式所要求的接口;文法中的每一个终结符都有一个具体终结表达式与之相对应。比如公式R=R1+R2,R1和R2就是终结符,对应的解析R1和R2的解释器就是终结符表达式 * Nonterminal Expression:非终结符表达式,文法中的每一条规则都需要一个具体的非终结符表达式,非终结符表达式一般是文法中的运算符或者其他关键字,比如公式R=R1+R2中,“+"就是非终结符,解析“+”的解释器就是一个非终结符表达式 * Context:环境,它的任务一般是用来存放文法中各个终结符所对应的具体值,比如R=R1+R2,给R1赋值100,给R2赋值200,这些信息需要存放到环境中。 ## 意图 > 给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子 ## 主要解决 > 对于一些固定文法构建一个解释句子的解释器 ## 何时使用 > 如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题 ## 如何解决 > 构件语法树,定义终结符与非终结符 ## 优点 > * 1、可扩展性比较好,灵活。 * 2、增加了新的解释表达式的方式。 * 3、易于实现简单文法。 ## 缺点 > * 1、可利用场景比较少 * 2、对于复杂的文法比较难维护 * 3、解释器模式会引起类膨胀 * 4、解释器模式采用递归调用方法 ## 使用场景 > * 1、可以将一个需要解释执行的语言中的句子表示为一个抽象语法树。 * 2、一些重复出现的问题可以用一种简单的语言来进行表达。 * 3、一个简单语法需要解释的场景。 ## 实现 > 我们将创建一个接口 Expression 和实现了 Expression 接口的实体类。定义作为上下文中主要解释器的 TerminalExpression 类。其他的类 OrExpression、AndExpression 用于创建组合式表达式。InterpreterPatternDemo,我们的演示类使用 Expression 类创建规则和演示表达式的解析。  ## 案例代码 ``` package com.noteshare.designPatterns.interpreter.demo1; /** * 抽象表达式,声明一个所有的具体表达式都需要实现的抽象接口;这个接口主要是一个interpret()方法,称做解释操作 */ public interface Expression { /** * 解释器核心方法 * * @param context * @return */ public boolean interpret(String context); } package com.noteshare.designPatterns.interpreter.demo1; /** * 终结符表达式,实现了抽象表达式所要求的接口;文法中的每一个终结符都有一个具体终结表达式与之相对应。 * 比如公式R=R1+R2,R1和R2就是终结符,对应的解析R1和R2的解释器就是终结符表达式。 */ public class TerminalExpression implements Expression { private String data; public TerminalExpression(String data) { this.data = data; } @Override public boolean interpret(String context) { if (context.contains(data)) { return true; } return false; } } package com.noteshare.designPatterns.interpreter.demo1; /** * and表达式 */ public class AndExpression implements Expression { private Expression expr1 = null; private Expression expr2 = null; public AndExpression(Expression expr1, Expression expr2) { this.expr1 = expr1; this.expr2 = expr2; } @Override public boolean interpret(String context) { return expr1.interpret(context) && expr2.interpret(context); } } package com.noteshare.designPatterns.interpreter.demo1; /** * or表达式 */ public class OrExpression implements Expression { private Expression expr1 = null; private Expression expr2 = null; public OrExpression(Expression expr1, Expression expr2) { this.expr1 = expr1; this.expr2 = expr2; } @Override public boolean interpret(String context) { return expr1.interpret(context) || expr2.interpret(context); } } package com.noteshare.designPatterns.interpreter.demo1; public class InterpreterPatternDemo { // 规则:Robert 和 John 是男性 public static Expression getMaleExpression() { Expression robert = new TerminalExpression("Robert"); Expression john = new TerminalExpression("John"); return new OrExpression(robert, john); } // 规则:Julie 是一个已婚的女性 public static Expression getMarriedWomanExpression() { Expression julie = new TerminalExpression("Julie"); Expression married = new TerminalExpression("Married"); return new AndExpression(julie, married); } public static void main(String[] args) { Expression isMale = getMaleExpression(); Expression isMarriedWoman = getMarriedWomanExpression(); System.out.println("John is male? " + isMale.interpret("John")); System.out.println("Julie is a married women? " + isMarriedWoman.interpret("Married Julie")); } } ``` ## 使用场景思考 * 在一些规则算分的场景可以使用,如满足各种规则的计分公示然后得到不同的分数的情况,可以把各种计算方法定义为解释器,根据不同的规则公式expression来计算出结果。 ## 应用案例 > 首先输入一个加减或乘除的运算公式,比如a+b-c+a或a*b/c*a,再给每个参数赋值,最后根据公式完成运算并得到结果。  ### 部分实现代码 ``` package com.noteshare.designPatterns.interpreter.demo2; import java.util.HashMap; /** * 环境-准备计算环境,准备相关数据 */ public class Context { private HashMap
variableAndValue; public Context(HashMap
variableAndValue) { this.variableAndValue = variableAndValue; } public HashMap
getVariableAndValue() { return variableAndValue; } public void setVariableAndValue(HashMap
variableAndValue) { this.variableAndValue = variableAndValue; } public double getValue(String key) { return variableAndValue.get(key); } } package com.noteshare.designPatterns.interpreter.demo2; /** * 抽象表达式 */ public abstract class Expression { abstract double Interpret(Context context); } package com.noteshare.designPatterns.interpreter.demo2; /** * 变量,终结符表达式-获取计算变量 */ public class VariableExpression extends Expression { private String key; public VariableExpression(String key) { this.key = key; } @Override public double Interpret(Context context) { return context.getValue(this.key); } public String getKey() { return key; } public void setKey(String key) { this.key = key; } } package com.noteshare.designPatterns.interpreter.demo2; /** * 非终结符表达式 */ public abstract class OperatorExpression extends Expression { // 左操作数 private Expression left; // 右操作数 private Expression right; public OperatorExpression(Expression left,Expression right) { this.left = left; this.right = right; } public Expression getLeft() { return left; } public void setLeft(Expression left) { this.left = left; } public Expression getRight() { return right; } public void setRight(Expression right) { this.right = right; } } package com.noteshare.designPatterns.interpreter.demo2; /** * 非终结符表达式 */ public class AddExpression extends OperatorExpression{ public AddExpression(Expression left, Expression right) { super(left, right); } @Override double Interpret(Context context) { return this.getLeft().Interpret(context) + this.getRight().Interpret(context); } } package com.noteshare.designPatterns.interpreter.demo2; /** * 非终结符表达式 */ public class SubExpression extends OperatorExpression{ public SubExpression(Expression left, Expression right) { super(left, right); } @Override double Interpret(Context context) { return this.getLeft().Interpret(context) - this.getRight().Interpret(context); } } ```
所有评论列表
点我发表评论