1 介紹
Acey:考試臨近了窍箍,你復(fù)習(xí)的怎么樣啦?小白丽旅。
小白:??椰棘,word哥呀,真的好險(xiǎn)呀榄笙,考了三門了邪狞,都是飄過(guò)的你造嘛!
Acey: 你這是考場(chǎng)老司機(jī)呀茅撞,專注60分一輩子帆卓,多一分就是浪費(fèi)呀是吧?
小白:
Acey:好吧米丘,不說(shuō)你了鳞疲,后面的科目可別掛了??。今天呢蠕蚜,我們來(lái)用解釋器模式來(lái)算算你一共考了多少分。
小白:那我用計(jì)算器算不就好了悔橄。,,???,,
Acey:那顯得多l(xiāng)ow呀靶累,簡(jiǎn)單的四則運(yùn)算當(dāng)然可以用計(jì)算器,但是當(dāng)以后用到更復(fù)雜的運(yùn)算時(shí)計(jì)算器就解決不了癣疟,所以為了以后挣柬,現(xiàn)在要好好的學(xué)。
小白:好啵睛挚。
解釋器模式:Interpreter 模式是行為模式的一種邪蛔。簡(jiǎn)單的說(shuō)就是一種語(yǔ)法解釋器架構(gòu)。
Acey:說(shuō)的通俗易懂一點(diǎn)扎狱。我們?cè)谑褂糜?jì)算器的時(shí)候侧到,通常就是按下相應(yīng)的數(shù)字和運(yùn)算符勃教,然后結(jié)果就顯示出來(lái)了,整個(gè)被隱藏起來(lái)的運(yùn)算過(guò)程就是對(duì)應(yīng)的解釋器的解釋過(guò)程匠抗。而對(duì)于我們要算的總成績(jī)也是一個(gè)道理故源,我們只需要將科目及對(duì)應(yīng)的分?jǐn)?shù)輸入,經(jīng)過(guò)解釋器的解釋汞贸,我們就可以得到我們想要的結(jié)果绳军,這就是解釋器模式。
小白:這樣呀矢腻,那如果我們要進(jìn)行規(guī)模比較大的運(yùn)算门驾,如 統(tǒng)計(jì),預(yù)測(cè)之類的多柑,使用解釋器模式會(huì)不會(huì)比較影響效率哇奶是。??
Acey:會(huì)呢,因?yàn)槲覀兪遣捎眠f歸調(diào)用的方式顷蟆,所以如果程序需要高效的話诫隅,建議就不要使用了。
2 實(shí)現(xiàn)
首先帐偎,我們先來(lái)看看結(jié)構(gòu)類圖
其中
- AbstractExpression 是一個(gè)抽象表達(dá)式類逐纬,具體的解釋任務(wù)由各個(gè)實(shí)現(xiàn)類完成。
- TerminalExpression是終結(jié)符表達(dá)式類削樊,實(shí)現(xiàn)相關(guān)的解釋操作(獲取當(dāng)前科目分?jǐn)?shù))
- NonterminalExpression 是非終結(jié)符表達(dá)式類豁生,每條規(guī)則對(duì)應(yīng)于一個(gè)非終結(jié)表達(dá)式(相應(yīng)的運(yùn)算)
- Context是上下文角色,用來(lái)存儲(chǔ)輸入的數(shù)據(jù)(科目及分?jǐn)?shù))漫贞。
實(shí)現(xiàn)
第一步:創(chuàng)建抽象表達(dá)式角色
Expression.class
//抽象表達(dá)式角色
public abstract class Expression {
public abstract Integer result(Context context);
}
第二步:創(chuàng)建上下文角色
Context.class
//上下文角色甸箱,使用HashMap來(lái)存儲(chǔ)變量及其對(duì)應(yīng)的值
public class Context {
//用于保存科目及相應(yīng)的分?jǐn)?shù)
private Map<Subject,Integer> score = new HashMap<>();
//為每門課填充分?jǐn)?shù)
public void addScore(Subject subject, Integer score){
this.score.put(subject, score);
}
//獲取科目對(duì)應(yīng)的分?jǐn)?shù)
public Integer getScore(Subject subject){
return this.score.get(subject);
}
}
第三步:創(chuàng)建終結(jié)符角色
Subject.class
//終結(jié)符表達(dá)式角色
public class Subject extends Expression{
//從context(Map)中獲取當(dāng)前科目的分?jǐn)?shù)
@Override
public Integer result(Context context) {
return context.getScore(this);
}
}
第四步:創(chuàng)建非終結(jié)符角色
Add.class
//非終結(jié)者表達(dá)式角色
public class Add extends Expression{
private Expression left;
private Expression right;
//傳入兩門科目名稱
public Add(Expression left, Expression right) {
this.left = left;
this.right = right;
}
//計(jì)算結(jié)果
@Override
public Integer result(Context context) {
return left.result(context) + right.result(context);
}
}
第五步:測(cè)試
Mainclass.class
public class MainClass {
public static void main(String[] args) {
//容器,存放科目及其對(duì)應(yīng)分?jǐn)?shù)
Context context = new Context();
//創(chuàng)建科目
Subject math = new Subject();
Subject chinese = new Subject();
Subject english = new Subject();
//保存分?jǐn)?shù)
context.addScore(math, 61);
context.addScore(chinese, 60);
context.addScore(english, 65);
//迭代計(jì)算總分?jǐn)?shù)
Expression result = new Add(new Add(math, chinese), english) ;
System.out.println("總分?jǐn)?shù)為:" + result.result(context));
}
}
Acey:上述代碼中只實(shí)現(xiàn)了一個(gè)非終結(jié)符表達(dá)式迅脐,當(dāng)然根據(jù)需求可以很輕易的添加芍殖,它的優(yōu)點(diǎn)就是拓展性強(qiáng)。但是缺點(diǎn)也是很明顯的谴蔑,每條規(guī)則(運(yùn)算符)都要對(duì)應(yīng)一個(gè)非終結(jié)符表達(dá)式豌骏,當(dāng)業(yè)務(wù)復(fù)雜時(shí),存在大量的非終結(jié)符表達(dá)式隐锭,那維護(hù)起來(lái)就相當(dāng)麻煩了窃躲。模式中使用了遞歸也是一個(gè)不容小覷的缺點(diǎn),當(dāng)運(yùn)行解釋冗長(zhǎng)钦睡、復(fù)雜的語(yǔ)句時(shí)效率往往是很低的蒂窒,也不利于開(kāi)發(fā)人的調(diào)試。所以在開(kāi)發(fā)中解釋器模式一般也很少用到。
last
祝大家
喜歡的話戳一下喜歡唄洒琢。
有什么建議的話希望大家能在下方回復(fù)??
上一篇:《適配器模式 - 我有金卡秧秉,你有麼?》
下一篇:《中介者模式 - 聽(tīng)說(shuō)你還是單身dog》