祝大家新年快樂,萬事如意,在新的一年里,步步高升,財(cái)源滾滾。
設(shè)計(jì)模式中有六大原則和二十三設(shè)計(jì)模式。
其中六大原則分別為:?jiǎn)我宦氊?zé)原則、開閉原則、里氏替換原則、依賴倒置原則、接口隔離原則、迪米特原則。
二十三設(shè)計(jì)模式:?jiǎn)卫J?、Builder 模式、原型模式、工廠方法模式、抽象工廠模式、策略模式、狀態(tài)模式、責(zé)任鏈模式、解釋器模式、命令模式、觀察者模式、備忘錄模式、迭代器模式、模版方法模式、訪問者模式、中介模式、代理模式、組合模式、適配器模式、裝飾模式、享元模式、外觀模式、橋接模式。
解釋器模式,是我們平常很少用到的一種設(shè)計(jì)模式,也是我認(rèn)為最難的一種設(shè)計(jì)模式,書看了一遍,沒怎么懂,看看例子,一遍一遍的琢磨,才懂那么一點(diǎn)點(diǎn)。
解釋器可以理解為對(duì) 上下文(Context)或者說是最終輸入的內(nèi)容的解釋。
比如在 java 中String 類型內(nèi)寫運(yùn)算公式(如:"12 + 3 + 4"),它是不能直接運(yùn)算的,需要我們對(duì)他解析才能得到結(jié)果,這就需要我們對(duì)它進(jìn)行解釋,算出最后結(jié)果;
還比如已經(jīng)提前錄入了姓名和性別,在最終輸入姓名和性別,就可以篩選出這個(gè)人的姓名和性別是否相匹配。
定義
定義了一個(gè)解釋器,來解釋給定語言和文法的句子。其實(shí)質(zhì)是把語言中的每個(gè)符號(hào)定義成一個(gè)(對(duì)象)類,從而把每個(gè)程序轉(zhuǎn)換成一個(gè)具體的對(duì)象樹。
使用場(chǎng)景
- 可以將一個(gè)需要解釋執(zhí)行的語言中的句子表示為一個(gè)抽象語法樹
- 一些重復(fù)出現(xiàn)的問題可以用一種簡(jiǎn)單的語言來進(jìn)行表達(dá)
- 一個(gè)簡(jiǎn)單語法需要解釋的場(chǎng)景
優(yōu)缺點(diǎn)[1]
優(yōu)點(diǎn)
- 可擴(kuò)展性比較好,靈活。
- 增加了新的解釋表達(dá)式的方式。
- 易于實(shí)現(xiàn)簡(jiǎn)單文法。
缺點(diǎn)
- 可利用場(chǎng)景比較少。
- 對(duì)于復(fù)雜的文法比較難維護(hù)。
- 解釋器模式會(huì)引起類膨脹。
- 解釋器模式采用遞歸調(diào)用方法。
UML圖

- AbstractExpression:抽象表達(dá)式
- TerminalExpression:終結(jié)符表達(dá)式
- NonterminalExpression:非終結(jié)符表達(dá)式。實(shí)現(xiàn)文法中與非終結(jié)符有關(guān)的解釋操作
- Context:上下文環(huán)境類。包含解釋器之外全局信息
- Client:客戶類。實(shí)際使用類
代碼實(shí)現(xiàn)
- 抽象表達(dá)式
/**
* 抽象表達(dá)式
* 為所有解釋器的基礎(chǔ)類
*/
public interface AbstractExpression1 {
boolean interpret(String context);
}
- 終結(jié)符表達(dá)式
/**
* 終結(jié)符表達(dá)式
*/
public class TerminalExpression implements AbstractExpression1 {
private String data;
public TerminalExpression(String data) {
this.data = data;
}
public boolean interpret(String context) {
return context.contains(this.data);
}
}
- 非終結(jié)符表達(dá)式
/**
* 非終結(jié)符表達(dá)式(組合式表達(dá)式)-- 或操作
*/
public class OrExpression implements AbstractExpression1 {
private AbstractExpression1 expressionA;
private AbstractExpression1 expressionB;
public OrExpression(AbstractExpression1 expressionA, AbstractExpression1 expressionB) {
this.expressionA = expressionA;
this.expressionB = expressionB;
}
@Override
public boolean interpret(String context) {
return this.expressionA.interpret(context) || this.expressionB.interpret(context);
}
}
- 執(zhí)行
public class ClientOne {
//規(guī)則:Robert 和 John 是男性
public static AbstractExpression1 getMaleExpression(){
AbstractExpression1 robert = new TerminalExpression("Robert");
AbstractExpression1 john = new TerminalExpression("John");
return new OrExpression(robert, john);
}
//規(guī)則:Julie 是一個(gè)已婚的女性
public static AbstractExpression1 getMarriedWomanExpression(){
AbstractExpression1 julie = new TerminalExpression("Julie");
AbstractExpression1 married = new TerminalExpression("Married");
return new AndExpression(julie, married);
}
public static void main(String[] args) {
AbstractExpression1 isMale = getMaleExpression();
AbstractExpression1 isMarriedWoman = getMarriedWomanExpression();
boolean isMan1 = isMale.interpret("John");
boolean isMan2 = isMale.interpret("Robert");
boolean isMan3 = isMale.interpret("Bill");
boolean isMarriedWomen = isMarriedWoman.interpret("Married Julie");
System.out.println("John is male? \n"+(isMan1?"Yes":"no"));
System.out.println("Robert is male? \n"+(isMan2?"Yes":"no"));
System.out.println("Bill is male? \n"+(isMan3?"Yes":"no"));
System.out.println("Julie is a married women? \n"+(isMarriedWomen?"Yes":"no"));
}
}
- 結(jié)果
John is male?
Yes
Robert is male?
Yes
Bill is male?
no
Julie is a married women?
Yes
總結(jié)
解釋器模式,它是真的難,理解起來也不是很容易,在平常的開發(fā)中,我們很少使用到。以上就是我看書和博客中了解到的內(nèi)容,在DEMO 中也寫了另一個(gè)例子(字符串中運(yùn)算而計(jì)算結(jié)果)。
DEMO
參考:《Android 源碼設(shè)計(jì)模式解析與實(shí)踐》、解釋器模式-菜鳥教程