设计模式(二十一)---解释器模式

来源:互联网 发布:office of mac免费版本 编辑:程序博客网 时间:2024/05/16 18:17
  定义:给定一门语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。

  现在的设计模式很少用到该模式。

一般模式


  AbstractExpression 抽象解释器
  ---|具体的解释任务由各个实现类完成,具体的解释器分别由TerminalExpression和
  NonterminalExpression完成。
  TerminalExpression 终结符表达式
  ---|实现与文法中的元素相关联的解释操作,通常一个解释器模式中只有一个终结符表达式。
  但由很多个实例,对应不同的终结符。
  NonterminalExpression非终结符表达式
  ---|文法中每条规则对应于一个非终结符表达式。非终结符表达式根据逻辑的复杂程度而增加,
  原则上每个文法规则都对应一个非终结符表达式
  Context环境角色

  ---|具体到我们的例子中是采用HashMap代替。

public class ExpressionTest{public static void main(String[] args) {Context con = new Context();//通常定义一个语法容器,容纳一个具体的表达式Stack<AbstractExpression> stack = new Stack<AbstractExpression>();AbstractExpression exp = stack.pop();//具体元素进入场景exp.interPreter(con);}}/** * 抽象的解释器类 * 每个表达式都有一个解析任务 * @author Administrator */abstract class AbstractExpression{//每个表达式必须有一个解析任务public abstract Object interPreter(Context con);}/** * 终结符表达式类, * @author Administrator */class TerminalExpression extends AbstractExpression{@Overridepublic Object interPreter(Context con) {// TODO Auto-generated method stubreturn null;}}/** * 非终结符表达式类 * @author Administrator */class NorerminalExpression extends AbstractExpression{//每个非终结符表达式都会对其他表达式产生依赖public NorerminalExpression(Expression ...expressions) {}@Overridepublic Object interPreter(Context con) {// TODO Auto-generated method stubreturn null;}}class Context{}

一个例子:

  公司实现一个建模的数学模型。要求输入一个表达式例如:a+b-c.然后按照输入顺序依次输入数据,便能得到结果。
  a=100,b==200,c==100.结果为200。
  利用解释器模式来完成这个设计,并能够有很好的扩展性。


public class ExpressionT {public static void main(String[] args) throws IOException {//输入String expstr = getExpstr();//获取map集合HashMap<String, Integer> map = getValues(expstr);//进入计算Calculator cal = new Calculator(expstr);System.out.println("计算结果是:"+expstr+"="+cal.run(map));}//输入public static String getExpstr() throws IOException{System.out.println("请输入表达式");return (new BufferedReader(new InputStreamReader(System.in))).readLine();}//转换成mappublic static HashMap<String, Integer> getValues(String expstr) throws IOException{HashMap<String, Integer> map = new HashMap<String,Integer>();for(char c : expstr.toCharArray()){if(c!='+'&&c!='-'){//解决参数重复问题if(!map.containsKey(String.valueOf(c))){System.out.println("请输入"+c+"的值:"); String in = (new BufferedReader(new InputStreamReader(System.in))).readLine();map.put(String.valueOf(c), Integer.valueOf(in));}}}return map;}}/** * 抽象公式的表达式。 * 所有子类都要实现该方法 * @author Administrator * */abstract class Expression{//解析公式和数值,其中var中的key值是公式中的参数,value值是具体的数字。public abstract int interpreter(HashMap<String, Integer> var);}/** * 变量解析器 * @author Administrator */class VarExpression extends Expression{private String key;public VarExpression(String key) {this.key = key;}//从map中取出@Overridepublic int interpreter(HashMap<String, Integer> var) {return var.get(key);}}/** * 抽象符号解析器 * 包括左表达式和右表达式。 * 所有的解析公式都应该只关心自己左右两个表达式的结果 * @author Administrator */abstract class SymbolExpression extends Expression{//左表达式protected Expression left;//右表达式protected Expression right;public SymbolExpression(Expression left,Expression right) {this.left = left;this.right = right;}}/** * 加法表达式的计算 * @author Administrator * */class AddExpression extends SymbolExpression{public AddExpression(Expression left, Expression right) {super(left, right);}@Overridepublic int interpreter(HashMap<String, Integer> var) {return super.left.interpreter(var) + super.right.interpreter(var);}}/** * 减法表达式的计算 * @author Administrator * */class SubExpression extends SymbolExpression{public SubExpression(Expression left, Expression right) {super(left, right);}@Overridepublic int interpreter(HashMap<String, Integer> var) {return super.left.interpreter(var)-super.right.interpreter(var);}}/** * 解析器封装类 * @author Administrator * */class Calculator{//定义表达式private Expression expression;//构造函数传参并解析public Calculator(String expStr) {//定义一个栈,设置先后顺序Stack<Expression> stack = new Stack<Expression>();Expression left = null;Expression right = null;//转换成char数组char[] charArray = expStr.toCharArray();for(int i=0;i<charArray.length;i++){switch (charArray[i]) {//例如:a+bcase '+'://让左表达式出栈left = stack.pop(); //找到左表达式right = new VarExpression(String.valueOf(charArray[++i]));//将表达式放入到加法运算中stack.push(new AddExpression(left, right));break;case '-'://让左表达式出栈left = stack.pop(); //找到左表达式right = new VarExpression(String.valueOf(charArray[++i]));//将表达式放入到减法运算中stack.push(new SubExpression(left, right));break;default: //公式中的变量stack.push(new VarExpression(String.valueOf(charArray[i])));break;}}//将表达式结果抛出来this.expression = stack.pop();}//开始运算public int run(HashMap<String, Integer> var){return this.expression.interpreter(var);}}
书上说,解释器模式现在很少用到了。我也是不太明白,只是惊叹这个模式很饶人。只是稍微了解一些。



0 0
原创粉丝点击