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));
}
}

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

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