一、模式介绍
解释器模式,定义一个解释器,用来解释“特定的文法表示”,通常是计算或运行出结果。
如果某类有共性问题频繁发生,如:有三个变量假设未a、b、c,需求经常需要计算和或差,如a+b+c/a-b+c/
a+b-c/a-b-c,等等它们的种类可能会很多且不可预知(可能由输入决定),观察发现他们他们的共性在于:有两种元素:运算逻辑(+/-)和参数单元(a/b/c/其它),运算逻辑依赖左右两个参数单元可运算出结果,参数单元没有其它依赖,于此,可抽象出两类表达式,一类是运算表达式,一类是参数表达式,由于运算符合和参数单元需要动态确定,故需要剥离其实质进一步抽象,统一为:表达式。
解释器模式的应用,首先必须要定义“文法基础”,即“表达式语法”,然后按照此语法写出的文法语句,可以通过解析得到一系列可执行的接口指令,最终,指令按照预先的文法输入执行,以满足一类业务需求。
通常解释器模式的实施,会不可避免的涉及两类表达式:终结表达式、非终结表达式。终结表达式是指令执行的基础单元(如变量),非终结表达式则是基于终结表达式进行可配置的业务流程(如运算符)。
二、原理图
三、示例代码
import java.util.*; class Calculator { Expression expression; Context context; void initAlg(String alg) { // Stack stack = new Stack();//线程安全 Deque<Expression> stack = new ArrayDeque<Expression>();//官方建议的Stack替代用法 char[] s = alg.toCharArray(); for (int i = 0; i < s.length; i++) { char c = s[i]; switch (c) { case '+': stack.push(new PlusExpression(stack.pop(), new VariableExpression(s[++i]))); break; case '-': stack.push(new MinusExpression(stack.pop(), new VariableExpression(s[++i]))); break; default: stack.push(new VariableExpression(c)); } } expression = stack.pop(); } int run(final Map<Character, Integer> values) { return expression.explain(new Context() { @Override public int getValue(char key) { return values.get(key); } }); } } interface Context { int getValue(char key); } interface Expression { int explain(Context context); } abstract class CalculateExpression implements Expression { Expression left; Expression right; public CalculateExpression(Expression left, Expression right) { this.left = left; this.right = right; } } class PlusExpression extends CalculateExpression { public PlusExpression(Expression left, Expression right) { super(left, right); } @Override public int explain(Context context) { return left.explain(context) + right.explain(context); } } class MinusExpression extends CalculateExpression { public MinusExpression(Expression left, Expression right) { super(left, right); } @Override public int explain(Context context) { return left.explain(context) - right.explain(context); } } class VariableExpression implements Expression { char key; public VariableExpression(char key) { this.key = key; } @Override public int explain(Context context) { return context.getValue(key); } } public class T { public static void main(String[] args) { Calculator calculator = new Calculator(); String alg = "a+b-c+d"; calculator.initAlg(alg); Map<Character, Integer> valueMap = new HashMap<Character, Integer>(); valueMap.put('a', 1); valueMap.put('b', 2); valueMap.put('c', 3); valueMap.put('d', 5); int result = calculator.run(valueMap); System.out.println("表达式:" + alg); System.out.println("变量值:" + valueMap); System.out.println("计算结果:" + result); } }
输出:
表达式:a+b-c+d 变量值:{d=5, b=2, c=3, a=1} 计算结果:5
另一个示例:
package test; import java.util.*; /** * 文法模版定义:(((str1)sub3(str2)repeat2)reverse,str3)add * sub3:表示截取前3个 * repeat2:表示重复两遍 * reverse:反转字符串 * add: 拼接 字符串 * 本示例,省去了解析“模版”得到“解释器”的过程,直接手动new *Expression(*)建立 */ class Context { Map<Object, String> values = new HashMap<Object, String>(); void addResult(Object key, String result) { values.put(key, result); } String getResult(Object key) { return values.get(key); } } interface Expression { String explain(Context context); } class SubExpression implements Expression { Expression target; int count; public SubExpression(int count, Expression target) { this.count = count; this.target = target; } @Override public String explain(Context context) { String result = target.explain(context); return result.substring(0, count); } } class RepeatExpression implements Expression { Expression target; int count; public RepeatExpression(int count, Expression target) { this.count = count; this.target = target; } @Override public String explain(Context context) { String result = target.explain(context); StringBuilder stringBuilder = new StringBuilder(result); for (int i = 0; i < count; i++) { stringBuilder.append(result); } return stringBuilder.toString(); } } class ReverseExpression implements Expression { Expression target; public ReverseExpression(Expression target) { this.target = target; } @Override public String explain(Context context) { String result = target.explain(context); StringBuilder stringBuilder = new StringBuilder(result); return stringBuilder.reverse().toString(); } } class AddExpression implements Expression { Expression left; Expression right; public AddExpression(Expression left, Expression right) { this.left = left; this.right = right; } @Override public String explain(Context context) { return left.explain(context) + right.explain(context); } } class NopExpression implements Expression { Object key; public NopExpression(Object key) { this.key = key; } @Override public String explain(Context context) { return context.getResult(key); } } public class Main { public static void main(String[] args) { Object o1 = "a"; Object o2 = "b"; Context context = new Context(); context.addResult(o1, "abcde"); context.addResult(o2, "new"); Expression e = new AddExpression( // 4.将3得到的字符串+o2 new ReverseExpression( // 3.将2得到的字符串反转 new RepeatExpression(1, // 2.将1得到的字符串重复一遍 new SubExpression(3, // 1.截取o1的前三个 new NopExpression(o1)))), new NopExpression(o2)); System.out.println(e.explain(context)); } }
http://www.cnblogs.com/cbf4life/archive/2009/12/17/1626125.html