国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

解析Java的設計模式編程之解釋器模式的運用

2019-11-26 14:33:42
字體:
來源:轉載
供稿:網友

定義:給定一種語言,定義他的文法的一種表示,并定義一個解釋器,該解釋器使用該表示來解釋語言中句子。
類型:行為類模式
類圖:

2016217111905971.jpg (583×309)

解釋器模式是一個比較少用的模式,本人之前也沒有用過這個模式。下面我們就來一起看一下解釋器模式。
 
解釋器模式的結構
抽象解釋器:聲明一個所有具體表達式都要實現的抽象接口(或者抽象類),接口中主要是一個interpret()方法,稱為解釋操作。具體解釋任務由它的各個實現類來完成,具體的解釋器分別由終結符解釋器TerminalExpression和非終結符解釋器NonterminalExpression完成。
終結符表達式:實現與文法中的元素相關聯的解釋操作,通常一個解釋器模式中只有一個終結符表達式,但有多個實例,對應不同的終結符。終結符一半是文法中的運算單元,比如有一個簡單的公式R=R1+R2,在里面R1和R2就是終結符,對應的解析R1和R2的解釋器就是終結符表達式。                               
非終結符表達式:文法中的每條規則對應于一個非終結符表達式,非終結符表達式一般是文法中的運算符或者其他關鍵字,比如公式R=R1+R2中,+就是非終結符,解析+的解釋器就是一個非終結符表達式。非終結符表達式根據邏輯的復雜程度而增加,原則上每個文法規則都對應一個非終結符表達式。
環境角色:這個角色的任務一般是用來存放文法中各個終結符所對應的具體值,比如R=R1+R2,我們給R1賦值100,給R2賦值200。這些信息需要存放到環境角色中,很多情況下我們使用Map來充當環境角色就足夠了。

例子
來舉一個加減乘除的例子吧,實現思路來自于《java與模式》中的例子。每個角色的功能按照上面提到的規范來實現。

//上下文(環境)角色,使用HashMap來存儲變量對應的數值  class Context  {      private Map valueMap = new HashMap();      public void addValue(Variable x , int y)      {         Integer yi = new Integer(y);         valueMap.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));      }  } 

解釋器模式的優缺點
        解釋器是一個簡單的語法分析工具,它最顯著的優點就是擴展性,修改語法規則只需要修改相應的非終結符就可以了,若擴展語法,只需要增加非終結符類就可以了。
        但是,解釋器模式會引起類的膨脹,每個語法都需要產生一個非終結符表達式,語法規則比較復雜時,就可能產生大量的類文件,為維護帶來非常多的麻煩。同時,由于采用遞歸調用方法,每個非終結符表達式只關心與自己相關的表達式,每個表達式需要知道最終的結果,必須通過遞歸方式,無論是面向對象的語言還是面向過程的語言,遞歸都是一個不推薦的方式。由于使用了大量的循環和遞歸,效率是一個不容忽視的問題。特別是用于解釋一個解析復雜、冗長的語法時,效率是難以忍受的。
 
解釋器模式的適用場景
        在以下情況下可以使用解釋器模式:
有一個簡單的語法規則,比如一個sql語句,如果我們需要根據sql語句進行rm轉換,就可以使用解釋器模式來對語句進行解釋。
一些重復發生的問題,比如加減乘除四則運算,但是公式每次都不同,有時是a+b-c*d,有時是a*b+c-d,等等等等個,公式千變萬化,但是都是由加減乘除四個非終結符來連接的,這時我們就可以使用解釋器模式。


注意事項
       解釋器模式真的是一個比較少用的模式,因為對它的維護實在是太麻煩了,想象一下,一坨一坨的非終結符解釋器,假如不是事先對文法的規則了如指掌,或者是文法特別簡單,則很難讀懂它的邏輯。解釋器模式在實際的系統開發中使用的很少,因為他會引起效率、性能以及維護等問題。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 博罗县| 博爱县| 明溪县| 黄龙县| 怀远县| 巫山县| 北辰区| 六安市| 广饶县| 甘肃省| 南昌县| 夏邑县| 东城区| 拉孜县| 南漳县| 望奎县| 右玉县| 呼图壁县| 马关县| 临颍县| 景东| 达孜县| 阳信县| 和平区| 宁阳县| 武安市| 福贡县| 军事| 七台河市| 金溪县| 新乡县| 兴义市| 洪湖市| 临夏县| 衢州市| 积石山| 天等县| 磐石市| 米易县| 赞皇县| 松滋市|