解釋器模式

解釋器是一種用的比較少的行為模式,其提供了一種解釋語(yǔ)言的語(yǔ)法,或者表達(dá)式的方式。該模式定義了一個(gè)表達(dá)式的接口

案例(3乘7乘5除以3)

  1. 抽象接口
/**
 * 抽象接口
 */
public interface Node {
     int interpret();
}
  1. 非終結(jié)符抽象接口
public  abstract class SymbolNode implements Node {
    protected Node left;
    protected Node right;

    public SymbolNode(Node left, Node right) {
        this.left = left;
        this.right = right;
    }
}
  1. 終結(jié)符
 *終結(jié)符
 */
public class ValueNode implements Node{
    private int value;

    public ValueNode(int value) {
        this.value = value;
    }

    @Override
    public int interpret() {
        return value;
    }
}
  1. 具體的計(jì)算操作交由子類去實(shí)現(xiàn)
//乘法的計(jì)算
public class MulNode extends SymbolNode {
    public MulNode(Node left, Node right) {
        super(left, right);
    }

    /**
     * 計(jì)算方法(乘法)
     * @return
     */
    @Override
    public int interpret() {
        return left.interpret()*right.interpret();
    }
}
//除法計(jì)算
public class DivNode extends SymbolNode{
    public DivNode(Node left, Node right) {
        super(left, right);
    }

    /**
     * 計(jì)算方法(除法)
     * @return
     */
    @Override
    public int interpret() {
        return left.interpret()/right.interpret();
    }
}
  1. 計(jì)算的過程
public class Caculator {
    public int build(String num){
        Node left=null;
        Node right=null;
        Node lastNode=null;
        String[] statemnts=num.split(" ");
        for(int i=0;i<statemnts.length;i++){
            if("*".equalsIgnoreCase(statemnts[i])){//乘法

                left=lastNode;
                int val=Integer.parseInt(statemnts[++i]);
                right=new ValueNode(val);
                lastNode=new MulNode(left,right);

            }else  if("/".equalsIgnoreCase(statemnts[i])){//除法
                left=lastNode;
                int val=Integer.parseInt(statemnts[++i]);
                right=new ValueNode(val);
                lastNode=new DivNode(left,right);

            }else  if("%".equalsIgnoreCase(statemnts[i])){
                left=lastNode;
                int val=Integer.parseInt(statemnts[++i]);
                right=new ValueNode(val);
                lastNode=new ModeNode(left,right);

            } else {
                lastNode=new ValueNode(Integer.parseInt(statemnts[i]));
            }
        }
        return lastNode.interpret();
    }
}
  1. 客戶端的調(diào)用
        String content="3 * 5 * 7 / 3 % 30";
        Caculator caculator=new Caculator();
        int num=caculator.build(content);
        System.out.print("最后的結(jié)果為:"+num);
  1. 結(jié)果
最后的結(jié)果為:5
  1. 總結(jié):
    應(yīng)用場(chǎng)景:
    1. 簡(jiǎn)單的語(yǔ)言需要解釋執(zhí)行而且可以將該語(yǔ)言中的語(yǔ)句表示一個(gè)抽象的語(yǔ)法樹
    2. 對(duì)于某個(gè)特定的領(lǐng)域出現(xiàn)的不斷重復(fù)的問題扰藕,可以轉(zhuǎn)換成一種語(yǔ)法規(guī)則下的語(yǔ)句
    ** 優(yōu)缺點(diǎn):**
    優(yōu)點(diǎn): 每個(gè)語(yǔ)法都要產(chǎn)生一個(gè)非終結(jié)符表達(dá)式槽奕,語(yǔ)法規(guī)則比較復(fù)雜時(shí),就可能產(chǎn)生大量的類文件败晴,為維護(hù)帶來了非常多的麻煩浓冒。
    缺點(diǎn):
    1. 解釋器模式采用遞歸調(diào)用方法 每個(gè)非終結(jié)符表達(dá)式只關(guān)心與自己有關(guān)的表達(dá)式,每個(gè)表達(dá)式需要知道最終的結(jié)果尖坤,必須一層一層地剝繭稳懒,無論是面向過程的語(yǔ)言還是面向?qū)ο蟮恼Z(yǔ)言,遞歸都是在必要條件下使用的慢味,它導(dǎo)致調(diào)試非常復(fù)雜场梆。想想看墅冷,如果要排查一個(gè)語(yǔ)法錯(cuò)誤,我們是不是要一個(gè)一個(gè)斷點(diǎn)的調(diào)試下去或油,直到最小的語(yǔ)法單元寞忿。
    2. 解釋器模式由于使用了大量的循環(huán)和遞歸,效率是個(gè)不容忽視的問題顶岸,特別是用于解析復(fù)雜罐脊、冗長(zhǎng)的語(yǔ)法時(shí),效率是難以忍受的蜕琴。
    最后:
    解釋器模式在實(shí)際的開發(fā)中使用的非常少萍桌,因?yàn)樗鼤?huì)引起效率、性能以及維護(hù)等問題凌简,一般在大中型的框架型項(xiàng)目能夠找到它的身影上炎,比如一些數(shù)據(jù)分析工具、報(bào)表設(shè)計(jì)工具雏搂、科學(xué)計(jì)算工具等等藕施,若你確實(shí)遇到“一種特定類型的問題發(fā)生的頻率足夠高”的情況,準(zhǔn)備使用解釋器模式時(shí)凸郑,可以考慮一下Expression4J裳食、MESP(Math Expression String Parser)、Jep等開源的解析工具包
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末芙沥,一起剝皮案震驚了整個(gè)濱河市诲祸,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌而昨,老刑警劉巖救氯,帶你破解...
    沈念sama閱讀 210,914評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異歌憨,居然都是意外死亡着憨,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門务嫡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來甲抖,“玉大人,你說我怎么就攤上這事心铃∽佳瑁” “怎么了?”我有些...
    開封第一講書人閱讀 156,531評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵于个,是天一觀的道長(zhǎng)氛魁。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么秀存? 我笑而不...
    開封第一講書人閱讀 56,309評(píng)論 1 282
  • 正文 為了忘掉前任捶码,我火速辦了婚禮,結(jié)果婚禮上或链,老公的妹妹穿的比我還像新娘惫恼。我一直安慰自己,他們只是感情好澳盐,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評(píng)論 5 384
  • 文/花漫 我一把揭開白布祈纯。 她就那樣靜靜地躺著,像睡著了一般叼耙。 火紅的嫁衣襯著肌膚如雪腕窥。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,730評(píng)論 1 289
  • 那天筛婉,我揣著相機(jī)與錄音簇爆,去河邊找鬼。 笑死爽撒,一個(gè)胖子當(dāng)著我的面吹牛入蛆,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播硕勿,決...
    沈念sama閱讀 38,882評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼哨毁,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了源武?” 一聲冷哼從身側(cè)響起扼褪,我...
    開封第一講書人閱讀 37,643評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎软能,沒想到半個(gè)月后迎捺,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體举畸,經(jīng)...
    沈念sama閱讀 44,095評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡查排,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了抄沮。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片跋核。...
    茶點(diǎn)故事閱讀 38,566評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖叛买,靈堂內(nèi)的尸體忽然破棺而出砂代,到底是詐尸還是另有隱情,我是刑警寧澤率挣,帶...
    沈念sama閱讀 34,253評(píng)論 4 328
  • 正文 年R本政府宣布刻伊,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏捶箱。R本人自食惡果不足惜智什,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望丁屎。 院中可真熱鬧荠锭,春花似錦、人聲如沸晨川。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)共虑。三九已至愧怜,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間妈拌,已是汗流浹背叫搁。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評(píng)論 1 264
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留供炎,地道東北人渴逻。 一個(gè)月前我還...
    沈念sama閱讀 46,248評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像音诫,于是被迫代替她去往敵國(guó)和親惨奕。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容