设计模式-16-解释器模式
个人github地址:HibisciDai
设计模式系列项目源码:HibisciDai/DesignPattern-LearningNotes-HibisciDai
processon在线UML类图:processon
[TOC]
设计模式-16-解释器模式 解释器模式(Interprter Pattern) 意图 给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
given a language,define a representation for its grammer along with an interpreter that uses the representation to interpet sentences in the language.
主要解决 对于一些固定文法构建一个解释句子的解释器。
何时使用 如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题。
关键代码 构件环境类,包含解释器之外的一些全局信息,一般是 HashMap。
如何解决 构件语法树,定义终结符与非终结符。
应用实例 编译器、运算表达式计算。
优点
可扩展性比较好,灵活。
增加了新的解释表达式的方式。
易于实现简单文法。
缺点
可利用场景比较少。
对于复杂的文法比较难维护。
解释器模式会引起类膨胀。
解释器模式采用递归调用方法。
使用场景
可以将一个需要解释执行的语言中的句子表示为一个抽象语法树。
一些重复出现的问题可以用一种简单的语言来进行表达。
一个简单语法需要解释的场景。
注意事项 可利用场景比较少,JAVA 中如果碰到可以用 expression4J 代替。
案例1 乐章有乐调和谱子,计算机存储用数字对应音符
in music notation. we define 01 for L0,02 for MID,03 for HI. “do re mo fa sol la xi” used to represent 1 2 3 4 5 6 7 use the representation to interpret this sentence:“0 1 3 1 2 3 1 2 3 5 3”
类图
代码 pattern16.interprter.demo1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 public abstract class NotationInterpreter { abstract void Interpreter (Context context) ; } public class Context { String myNumNotation; String myScale; } public class NumberNotation extends NotationInterpreter { Hashtable<String, String> nns = new Hashtable <String, String>(); NumberNotation() { nns.put("1" , "do" ); nns.put("2" , "re" ); nns.put("3" , "mi" ); nns.put("4" , "fa" ); nns.put("5" , "sol" ); nns.put("6" , "la" ); nns.put("7" , "xi" ); } @Override void Interpreter (Context context) { String s = context.myNumNotation; for (int i = 0 ; i < s.length(); i++) { String subs = s.substring(i, i + 1 ); String r = nns.get(subs).toString(); System.out.println(r); System.out.println("" ); } } } public class Scale extends NotationInterpreter { @Override void Interpreter (Context context) { String scale = context.myScale; switch (scale) { case "01" : System.out.println("L0" ); break ; case "02" : System.out.println("MID" ); break ; case "03" : System.out.println("HI" ); break ; } } }
测试输出 1 2 3 4 5 6 7 8 9 10 11 12 13 public class Main { public static void main (String[] args) { Context c = new Context (); c.myNumNotation = "312312353" ; c.myScale = "01" ; Scale s = new Scale (); s.Interpreter(c); NumberNotation nn = new NumberNotation (); nn.Interpreter(c); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 L0 mi do re mi do re mi sol mi
案例2 【菜鸟教程】我们将创建一个接口 Expression 和实现了 Expression 接口的实体类。定义作为上下文中主要解释器的 TerminalExpression 类。其他的类 OrExpression、AndExpression 用于创建组合式表达式。
类图 11766