科技时代新浪首页 > 科技时代 > 软件 > 菜鸟Java入门手册专题 > 正文

深入浅出基于Java的解释器设计模式(2)


http://www.sina.com.cn 2005年01月10日 10:09 天极yesky

  文/Ai92

  三、举例

  来举一个加减乘除的例子吧,实现思路来自于《java与模式》中的例子。每个角色的功能按照上面提到的规范来实现。

//上下文(环境)角色,使用HashMap来存储变量对应的数值

class Context
{
 private Map valueMap = new HashMap();
 public void addValue(Variable x , int y)
 {
  Integer yi = new Integer(y);
  va
lueMap.put(x , yi);
 }

 public int LookupValue(Variable x)
 {
  int i = ((Integer)valueMap.get(x)).intValue();
  return i ;
 }
}

//抽象表达式角色,也可以用接口来实现

abstract class Expression
{
 public abstract int interpret(Context con);
}

//终结符表达式角色

class Constant extends Expression
{
 private int i ;
 public Constant(int i)
 {
  this.i = i;
 }

 public int interpret(Context con)
 {
  return i ;
 }
}

class Variable extends Expression
{
 public int interpret(Context con)
 {
  //this为调用interpret方法的Variable对象
  return con.LookupValue(this);
 }
}

//非终结符表达式角色

class Add extends Expression
{
 private Expression left ,right ;
 public Add(Expression left , Expression right)
 {
  this.left = left ;
  this.right= right ;
 }

 public int interpret(Context con)
 {
  return left.interpret(con) + right.interpret(con);
 }
}

class Subtract extends Expression
{
 private Expression left , right ;
 public Subtract(Expression left , Expression right)
 {
  this.left = left ;
  this.right= right ;
 }

 public int interpret(Context con)
 {
  return left.interpret(con) - right.interpret(con);
 }

}

class Multiply extends Expression
{
 private Expression left , right ;
 public Multiply(Expression left , Expression right)
 {
  this.left = left ;
  this.right= right ;
 }
 public int interpret(Context con)
 {
  return left.interpret(con) * right.interpret(con);
 }
}

class Division extends Expression
{
 private Expression left , right ;
 public Division(Expression left , Expression right)
 {
  this.left = left ;
  this.right= right ;
 }

 public int interpret(Context con)
 {
  try{
   return left.interpret(con) / right.interpret(con);
  }catch(ArithmeticException ae)
  {
   System.out.println("被除数为0!");
   return -11111;
  }
 }
}

//测试程序,计算 (a*b)/(a-b+2)

public class Test
{
 private static Expression ex ;
 private static Context con ;
 public static void main(String[] args)
 {
  con = new Context();
  //设置变量、常量
  Variable a = new Variable();
  Variable b = new Variable();
  Constant c = new Constant(2);
  //为变量赋值
  con.addValue(a , 5);
  con.addValue(b , 7);
  //运算,对句子的结构由我们自己来分析,构造
  ex = new Division(new Multiply(a , b), new Add(new Subtract(a , b) , c));
  System.out.println("运算结果为:"+ex.interpret(con));
 }
}

  解释器模式并没有说明如何创建一个抽象语法树,因此它的实现可以多种多样,在上面我们是直接在Test中提供的,当然还有更好、更专业的实现方式。

  对于终结符,GOF建议采用享元模式来共享它们的拷贝,因为它们要多次重复出现。但是考虑到享元模式的使用局限性,我建议还是当你的系统中终结符重复的足够多的时候再考虑享元模式。

  四、优缺点

  解释器模式提供了一个简单的方式来执行语法,而且容易修改或者扩展语法。一般系统中很多类使用相似的语法,可以使用一个解释器来代替为每一个规则实现一个解释器。而且在解释器中不同的规则是由不同的类来实现的,这样使得添加一个新的语法规则变得简单。

  但是解释器模式对于复杂文法难以维护。可以想象一下,每一个规则要对应一个处理类,而且这些类还要递归调用抽象表达式角色,多如乱麻的类交织在一起是多么恐怖的一件事啊!

  五、总结

  这样对解释器模式应该有了些大体的认识了吧,由于这个模式使用的案例匮乏,所以本文大部分观点直接来自于GOF的原著。只是实例代码是亲自实现并调试通过的。

[上一页]  [1]  [2]


  点击此处查询全部Java新闻 全部编程语言新闻

评论】【应用软件】【推荐】【 】【打印】【下载点点通】【关闭
 

 
新 闻 查 询
关键词



热 点 专 题
印度洋地震海啸
部分大豆色拉油不合格
杨振宁登记结婚
意甲在线足球经理游戏
2005新春购车完全手册
岁末年初汽车降价一览
2005年新春购房指南
2004地产网络营销盘点
天堂II 玩转港澳指南

 
 



科技时代意见反馈留言板 电话:010-82628888-5828   欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 会员注册 | 产品答疑

Copyright © 1996 - 2005 SINA Inc. All Rights Reserved

版权所有 新浪网