程序员人生 网站导航

浅谈设计模式:解释器模式(Interpreter Pattern)

栏目:框架设计时间:2015-04-25 09:17:22

酷爱生活、享受文娱、专注技术,欢迎关注微信公众号QGer,我们1起见证成长!
这里写图片描述
甚么是解释器模式?

官方解释:to define a representation of grammar of a given language, along with an interpreter that uses this representation to interpret sentences in the language。
定义1个给定语言的语法表达式,并用该表达式作为1个解释器来解释语言中的句子。

通俗解释:给定1种语言及相干语法,根据这些语法定义1个语法表达式的解释器,客户端可使用这个解释器来解释这个语言中句子。

为何使用解释器模式?

  • 语法表达式进行抽象封装,易于修改及拓展,当这个语言新增了某种特性,可以通过继承抽象表达式类来实现新的语言特性。

  • 每条语法都可以表示为1个表达式类,实现起来比较容易。

PS:该模式由于其结构特性,对复杂语法很难保护,履行效力比较低,因此实际开发中几近不适用这个模式,但是其本身的结构和思想还是可以学习鉴戒1下的。

如何使用解释器模式?
UML图以下:
这里写图片描述

各个组件解释:

  • AbstractExpression(抽象表达式):声明1个抽象的解释操作interpreter,这个接口为所有具体表达式角色(抽象语法树中的节点)都要实现的。

  • TerminalExpression(终结表达式):实现了抽象表达式角色所要求的接口,主要是1个interpret()方法;文法中的每个终结符都有1个具体终结表达式与之相对应。比如有1个简单的公式R=R1+R2,在里面R1和R2就是终结符,对应的解析R1和R2的解释器就是终结符表达式。

  • NonTerminalExpression(非终结表达式):文法中的每条规则都需要1个具体的非终结符表达式,非终结符表达式1般是文法中的运算符或其他关键字,比如公式R=R1+R2中,“+”就是非终结符,解析“+”的解释器就是1个非终结符表达式。

  • Client(客户端):使用解释器的角色。

  • Context(上下文):这个角色的任务1般是用来寄存文法中各个终结符所对应的具体值,比如R=R1+R2,我们给R1赋值100,给R2赋值200。这些信息需要寄存到环境角色中,很多情况下我们使用1个映照(Map)来充当环境角色就足够了。

利用实例:
有这么1个简单的需求,给予1个字符,让你判断是不是是数字字符(‘0’-‘9’),可以这么实现:

1、定义1个抽象表达式

interface AbstractExpression { boolean interpret(Character character); }

2、定义终结表达式,即直接判断字符是不是是数字字符

public class TerminalExpression implements AbstractExpression { @Override public boolean interpret(Character character) { //是不是是数字字符 return character.isDigit(character); } }

3、定义简单的非终结表达式,and 、not 、or

public class AndExpression implements AbstractExpression { private AbstractExpression leftExpression; private AbstractExpression rightExpression; public AndExpression(AbstractExpression leftExpression, AbstractExpression rightExpression) { this.leftExpression = leftExpression; this.rightExpression = rightExpression; } @Override public boolean interpret(Character character) { return leftExpression.interpret(character) && rightExpression.interpret(character); } } public class NotExpression implements AbstractExpression { private AbstractExpression expression; public NotExpression(AbstractExpression expression) { this.expression = expression; } @Override public boolean interpret(Character character) { return !expression.interpret(character); } } public class OrExpression implements AbstractExpression { private AbstractExpression leftExpression; private AbstractExpression rightExpression; public OrExpression(AbstractExpression leftExpression, AbstractExpression rightExpression) { this.leftExpression = leftExpression; this.rightExpression = rightExpression; } @Override public boolean interpret(Character character) { return leftExpression.interpret(character) || rightExpression.interpret(character); } }

4、客户端使用,这里由于相对简单,不需要使用context组件:

public class Client { public static void main(String[] args) { Character digitCharacter = new Character('1'); Character notdigitCharacter = new Character('l'); AbstractExpression terminalExpression = new TerminalExpression(); AbstractExpression notExpression = new NotExpression(terminalExpression); AbstractExpression andExpression = new AndExpression(terminalExpression, notExpression); AbstractExpression orExpression = new OrExpression(terminalExpression, notExpression); System.out.println(andExpression.interpret(digitCharacter)); System.out.println(andExpression.interpret(notdigitCharacter)); System.out.println(orExpression.interpret(digitCharacter)); System.out.println(orExpression.interpret(notdigitCharacter)); } }
------分隔线----------------------------
------分隔线----------------------------

最新技术推荐