設(shè)計(jì)模式之解釋器模式(Interpreter pattern)

祝大家新年快樂,萬事如意,在新的一年里,步步高升,財(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圖

解釋器模式.png
  • 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í)踐》、解釋器模式-菜鳥教程

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

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

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