解釋器模式 - 明天考試,戳不輟進來你自己看著辦

1 介紹


Acey:考試臨近了,你復習的怎么樣啦?小白。

小白:??,word哥呀,真的好險呀,考了三門了,都是飄過的你造嘛!

Acey: 你這是考場老司機呀,專注60分一輩子,多一分就是浪費呀是吧?

小白:

Acey:好吧,不說你了,后面的科目可別掛了??。今天呢,我們來用解釋器模式來算算你一共考了多少分。

小白:那我用計算器算不就好了。,,???,,

Acey:那顯得多l(xiāng)ow呀,簡單的四則運算當然可以用計算器,但是當以后用到更復雜的運算時計算器就解決不了,所以為了以后,現(xiàn)在要好好的學。

小白:好啵。

解釋器模式:Interpreter 模式是行為模式的一種。簡單的說就是一種語法解釋器架構(gòu)。

Acey:說的通俗易懂一點。我們在使用計算器的時候,通常就是按下相應的數(shù)字運算符,然后結(jié)果就顯示出來了,整個被隱藏起來的運算過程就是對應的解釋器解釋過程。而對于我們要算的總成績也是一個道理,我們只需要將科目及對應的分數(shù)輸入,經(jīng)過解釋器的解釋,我們就可以得到我們想要的結(jié)果,這就是解釋器模式。

小白:這樣呀,那如果我們要進行規(guī)模比較大的運算,如 統(tǒng)計,預測之類的,使用解釋器模式會不會比較影響效率哇。??

Acey:會呢,因為我們是采用遞歸調(diào)用的方式,所以如果程序需要高效的話,建議就不要使用了。

2 實現(xiàn)


先,我們先來看看結(jié)構(gòu)類圖

類圖

其中

  • AbstractExpression 是一個抽象表達式類,具體的解釋任務由各個實現(xiàn)類完成。
  • TerminalExpression是終結(jié)符表達式類,實現(xiàn)相關的解釋操作(獲取當前科目分數(shù))
  • NonterminalExpression 是非終結(jié)符表達式類,每條規(guī)則對應于一個非終結(jié)表達式(相應的運算)
  • Context是上下文角色,用來存儲輸入的數(shù)據(jù)(科目及分數(shù))。

實現(xiàn)

一步:創(chuàng)建抽象表達式角色

Expression.class

//抽象表達式角色
public abstract class Expression {
    public abstract Integer result(Context context);
}

二步:創(chuàng)建上下文角色

Context.class

//上下文角色,使用HashMap來存儲變量及其對應的值
public class Context {
    //用于保存科目及相應的分數(shù)
    private Map<Subject,Integer> score = new HashMap<>();
    
    //為每門課填充分數(shù)
    public void addScore(Subject subject, Integer score){
        this.score.put(subject, score);
    }
    
    //獲取科目對應的分數(shù)
    public Integer getScore(Subject subject){
        return this.score.get(subject);
    }
    
}

三步:創(chuàng)建終結(jié)符角色

Subject.class


//終結(jié)符表達式角色
public class Subject extends Expression{

    //從context(Map)中獲取當前科目的分數(shù)
    @Override
    public Integer result(Context context) {
        return context.getScore(this);
    }

}

四步:創(chuàng)建非終結(jié)符角色

Add.class

//非終結(jié)者表達式角色
public class Add extends Expression{
    private Expression left;
    private Expression right;
    
    //傳入兩門科目名稱
    public Add(Expression left, Expression right) {
        this.left = left;
        this.right = right;
    }

    //計算結(jié)果
    @Override
    public Integer result(Context context) {
        return left.result(context) + right.result(context);
    }

}

五步:測試

Mainclass.class

public class MainClass {
    public static void main(String[] args) {
        //容器,存放科目及其對應分數(shù)
        Context context = new Context();
        
        //創(chuàng)建科目
        Subject math = new Subject();
        Subject chinese = new Subject();
        Subject english = new Subject();
        
        //保存分數(shù)
        context.addScore(math, 61);
        context.addScore(chinese, 60);
        context.addScore(english, 65);
        
        //迭代計算總分數(shù)
        Expression result = new Add(new Add(math, chinese), english) ;
        
        System.out.println("總分數(shù)為:" + result.result(context));
        
    }
}
運行結(jié)果

Acey:上述代碼中只實現(xiàn)了一個非終結(jié)符表達式,當然根據(jù)需求可以很輕易的添加,它的優(yōu)點就是拓展性強。但是缺點也是很明顯的,每條規(guī)則(運算符)都要對應一個非終結(jié)符表達式,當業(yè)務復雜時,存在大量的非終結(jié)符表達式,那維護起來就相當麻煩了。模式中使用了遞歸也是一個不容小覷的缺點,當運行解釋冗長、復雜的語句時效率往往是很低的,也不利于開發(fā)人的調(diào)試。所以在開發(fā)中解釋器模式一般也很少用到。

last

祝大家

喜歡的話戳一下喜歡唄。
有什么建議的話希望大家能在下方回復??
上一篇:《適配器模式 - 我有金卡,你有麼?》
下一篇:《中介者模式 - 聽說你還是單身dog》

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容