[工作中的设计模式]解释器模式模式Interpreter

时间:2022-08-22 10:32:23

一、模式解析

  解释器模式是类的行为模式。给定一个语言之后,解释器模式可以定义出其文法的一种表示,并同时提供一个解释器。客户端可以使用这个解释器来解释这个语言中的句子。

[工作中的设计模式]解释器模式模式Interpreter

以上是解释器模式的类图,事实上我很少附上类图,但解释器模式确实比较抽象,为了便于理解还是放了上来,此模式的要点是:

1、客户端提供一个文本、表达式或者其他,约定解析格式

2、针对文本中可以分为终结符表达式非终结符表达式

3、终结符表达式无需进一步解析,但仍需要转化为抽象接口的实例

4、针对非终结表达式,没一种标示需要定义一种解析类,如果后续有扩展,则进一步扩展一种解析类,并修改解析分支即可完成扩展

二、模式代码

1、定义整体环境类,保存除了解析器外,其他全局信息

package interpreter.patten;

public class Context {
private String input;
private String output;
public String getInput() {
return input;
}
public void setInput(String input) {
this.input = input;
}
public String getOutput() {
return output;
}
public void setOutput(String output) {
this.output = output;
}
}

2、定义抽象解析器

package interpreter.patten;

public abstract class AbstractExpression {
public abstract void interpret(Context context);
}

3、定义终结符解析器

package interpreter.patten;

public class TerminalExpression extends AbstractExpression {

    @Override
public void interpret(Context context) {
System.out.println("终结符解析器");
}
}

4、定义非终结符表达式

package interpreter.patten;

public class UnTerminalExpression extends AbstractExpression {

    @Override
public void interpret(Context context) {
System.out.println("非终结符解析器");
}
}

5、定义客户端类

package interpreter.patten;

import java.util.ArrayList;
import java.util.List; public class Client {
public static void main(String[] args) {
Context context=new Context();
List<AbstractExpression> list=new ArrayList<AbstractExpression>();
list.add(new TerminalExpression());
list.add(new UnTerminalExpression());
list.add(new TerminalExpression());
list.add(new UnTerminalExpression());
list.add(new TerminalExpression());
list.add(new UnTerminalExpression());
for(AbstractExpression expression:list){
expression.interpret(context);
}
}
}

6、客户端执行结果

终结符解析器
非终结符解析器
终结符解析器
非终结符解析器
终结符解析器
非终结符解析器

三、应用场景

以上模式代码完整的实现了类图中的所有内容,并打印出了结果,但是又显得毫无意义,看起来比较蠢,这是因为在我们的实际使用中解释器模式使用非常稀少,他只有在做特定公式的解析或者语言解析才会用到,很不幸,目前我的工作中似乎没有可以完整的展示此模式的例子,但是为了加深印象,我们采用《java与模式》中的例子进行说明

aaarticlea/png;base64,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" alt="" width="865" height="478" />

此为java与模式中提供的相关例子,主要用于解析条件判断语句,例如:A and B,A or B ,not A等条件语句,表达式分为几类

1、终结符表达式-常量表达式,主要显示true或者false

2、终结符表达式=-变量表达式,主要是需要判断的条件

3、非终结符表达式-各种运算符,包括:与或非

四、场景代码

1、环境(Context)类定义出从变量到布尔值的一个映射

package interpreter.example;

import java.util.HashMap;
import java.util.Map; 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();
}
}

2、定义抽象表达式

package interpreter.example;
public abstract class Expression {
/**
* 以环境为准,本方法解释给定的任何一个表达式
*/
public abstract boolean interpret(Context ctx);
/**
* 检验两个表达式在结构上是否相同
*/
public abstract boolean equals(Object obj);
/**
* 返回表达式的hash code
*/
public abstract int hashCode();
/**
* 将表达式转换成字符串
*/
public abstract String toString();
}

3、定义常量表达式

package interpreter.example;
public class Constant extends Expression{ private boolean value; public Constant(boolean value){
this.value = value;
} @Override
public boolean equals(Object obj) { if(obj != null && obj instanceof Constant){
return this.value == ((Constant)obj).value;
}
return false;
} @Override
public int hashCode() {
return this.toString().hashCode();
} @Override
public boolean interpret(Context ctx) { return value;
} @Override
public String toString() {
return new Boolean(value).toString();
} }

4、定义变量表达式

package interpreter.example;
public class Variable extends Expression { private String name; public Variable(String name){
this.name = name;
}
@Override
public boolean equals(Object obj) { if(obj != null && obj instanceof Variable)
{
return this.name.equals(
((Variable)obj).name);
}
return false;
} @Override
public int hashCode() {
return this.toString().hashCode();
} @Override
public String toString() {
return name;
} @Override
public boolean interpret(Context ctx) {
return ctx.lookup(this);
} }

5、定义逻辑与

package interpreter.example;
public class And extends Expression { private Expression left,right; public And(Expression left , Expression right){
this.left = left;
this.right = right;
}
@Override
public boolean equals(Object obj) {
if(obj != null && obj instanceof And)
{
return left.equals(((And)obj).left) &&
right.equals(((And)obj).right);
}
return false;
} @Override
public int hashCode() {
return this.toString().hashCode();
} @Override
public boolean interpret(Context ctx) { return left.interpret(ctx) && right.interpret(ctx);
} @Override
public String toString() {
return "(" + left.toString() + " AND " + right.toString() + ")";
} }

6、定义逻辑或

package interpreter.example;
public class Or extends Expression {
private Expression left,right; public Or(Expression left , Expression right){
this.left = left;
this.right = right;
}
@Override
public 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;
} @Override
public int hashCode() {
return this.toString().hashCode();
} @Override
public boolean interpret(Context ctx) {
return left.interpret(ctx) || right.interpret(ctx);
} @Override
public String toString() {
return "(" + left.toString() + " OR " + right.toString() + ")";
} }

7、定义逻辑非

package interpreter.example;
public class Not extends Expression { private Expression exp; public Not(Expression exp){
this.exp = exp;
}
@Override
public boolean equals(Object obj) {
if(obj != null && obj instanceof Not)
{
return exp.equals(
((Not)obj).exp);
}
return false;
} @Override
public int hashCode() {
return this.toString().hashCode();
} @Override
public boolean interpret(Context ctx) {
return !exp.interpret(ctx);
} @Override
public String toString() {
return "(Not " + exp.toString() + ")";
} }

8、定义客户端代码

package interpreter.example;
public class Client { 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的更多相关文章

  1. &lbrack;工作中的设计模式&rsqb;享元模式模式FlyWeight

    一.模式解析 Flyweight在拳击比赛中指最轻量级,即“蝇量级”或“雨量级”,这里选择使用“享元模式”的意译,是因为这样更能反映模式的用意.享元模式是对象的结构模式.享元模式以共享的方式高效地支持 ...

  2. &lbrack;工作中的设计模式&rsqb;责任链模式chain

    一.模式解析 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求.发出这个请求的客户端并不知 ...

  3. &lbrack;工作中的设计模式&rsqb;原型模式prototype

    一.模式解析 提起prototype,最近看多了js相关的内容,第一印象首先是js的原型 var Person=function(name){ this.name=name; } Person.pro ...

  4. &lbrack;工作中的设计模式&rsqb;中介模式模式Mediator

    一.模式解析 用一个中介者对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使耦合松散,而且可以独立地改变它们之间的交互. 中介模式又叫调停者模式,他有如下特点: 1.有多个系统或者对 ...

  5. &lbrack;工作中的设计模式&rsqb;策略模式stategy

    一.模式解析 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它的客户而独立变化. 策略模式的关键点为: 1.多种算法存在 2.算法继承同样的接口 ...

  6. 在商城系统中使用设计模式----简单工厂模式之在springboot中使用简单工厂模式

    1.前言: 不了解简单工厂模式请先移步:在商城中使用简单工厂.在这里主要是对springboot中使用简单工厂模式进行解析. 2.问题: 什么是简单工厂:它的实现方式是由一个工厂类根据传入的参数,动态 ...

  7. &lbrack;工作中的设计模式&rsqb;迭代子模式Iterator

    一.模式解析 迭代子模式又叫游标(Cursor)模式,是对象的行为模式.迭代子模式可以顺序地访问一个聚集中的元素而不必暴露聚集的内部表象 1.迭代子模式一般用于对集合框架的访问,常用的集合框架为lis ...

  8. &lbrack;工作中的设计模式&rsqb;适配器模式adapter

    一.模式解析 适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作. 也就是说,如果已经写好了一个接口,但是又来了一种截然不同的接口,如 ...

  9. &lbrack;工作中的设计模式&rsqb;备忘录模式memento

    一.模式解析 备忘录对象是一个用来存储另外一个对象内部状态的快照的对象.备忘录模式的用意是在不破坏封装的条件下,将一个对象的状态捕捉(Capture)住,并外部化,存储起来,从而可以在将来合适的时候把 ...

随机推荐

  1. 用PS如何把图片调出时尚杂志色

    摘自:http://www.3lian.com/edu/2013/07-22/83061.html 01:打开图片,执行调整图层-色彩平衡;调整图层的标记-红色方框内图标. 02:色彩平衡-设置-点选 ...

  2. 将DLL放入到资源中,运行时自动加载

    今天在看到 一个小软件,考勤用的 AttendanceSheet_V_1_2,只有一个EXE文件,绿色的随便考到哪里都可以运行. 顺手反编译后发现,他将需要的DLL也放入到资源文件了,在启动的时候自动 ...

  3. 如果类的属性是copy的NSString类型 用set方法拦截时

    @property (nonatomic, copy) NSString *badgeValue; - (void)setBadgeValue:(NSString *)badgeValue { _ba ...

  4. HDU 5781 ATM Mechine 期望dp

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5781 ATM Mechine Time Limit: 6000/3000 MS (Java/Othe ...

  5. JQuery replace 替换全部

    天在做写个程序时遇到需要替换的功能,可是一开始用jquery的replace时,发现只替换到第一个.最后没办法,只好用正则表达式来例如下面   re = new RegExp("{thisc ...

  6. 关于异常&OpenCurlyDoubleQuote;The &&num;39&semi;Microsoft&period;ACE&period;OLEDB&period;12&period;0&&num;39&semi; provider is not registered on the local machine”的处理

    我们在利用SqlBlukcopy技术倒2010 或者2007格式的文件到SqlServer 数据库的时候,会发生如下错误: 原因如下: 1.在用SQL SERVER 2005访问.xlsx文件(off ...

  7. list 列表 和一些操作方法

    1. 什么是列表 定义: 能装对象的对象 在python中使用[]来描述列表, 内部元素用逗号隔开. 对数据类型没有要求 列表存在索引和切片. 和字符串是一样的. 2. 相关的增删改查操作(重点) 添 ...

  8. office2013密钥

    GYWDG-NMV9P-746HR-Y2VQW-YPXKK6HDB9-BNRGY-J3F83-CF43C-D67TXG9N3P-GRJK6-VM63J-F9M27-KHGXKX2YWD-NWJ42-3 ...

  9. nyoj1007——欧拉求和

    GCD 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 The greatest common divisor GCD(a,b) of two positive in ...

  10. TCP&sol;IP协议族-----15、传输控制协议(TCP)