大話設計模式學習筆記(27)——解釋器模式

源碼git地址 https://github.com/dlovetco/designMode
有時候我們會遇到這樣的一個問題:客戶端能夠提供的參數並不是我們所需要的。在調用正確的api之前,我們需要先把客戶端傳進來的參數解析成我們所需要的格式。

問題的提出

音樂簡譜中描繪樂曲用的是1234567,而實際發出的聲音卻是“哆瑞咪發嗦啦西”。實現一個簡譜到音樂的轉譯系統。

解釋器模式

給定一個語言,定義它的文法的一種表示,並定義一個解釋器,這個解釋器使用該表示來解釋語言中的句子。

package interpretermode;

import java.util.Arrays;

public class InterpreterMode {
    public static void main(String[] args) {
        Context context = new Context();
        context.setText("1 2 3 4 5 6 7");
        Expression note = new Note();
        note.execute(context);
    }
}

/**
 * 文法表達式接口
 */
interface Expression {
    void execute(Context context);
}

/**
 * 音符類 進行具體的音符轉換
 */
class Note implements Expression {

    @Override
    public void execute(Context context) {
        String[] keys = context.getText().split(" ");
        Arrays.stream(keys).forEach(key -> {
            switch (key) {
                case "1":
                    System.out.println("do");
                    break;
                case "2":
                    System.out.println("re");
                    break;
                case "3":
                    System.out.println("mi");
                    break;
                case "4":
                    System.out.println("fa");
                    break;
                case "5":
                    System.out.println("so");
                    break;
                case "6":
                    System.out.println("la");
                    break;
                case "7":
                    System.out.println("xi");
                    break;
            }
        });
    }
}

/**
 * 待解釋的文本
 */
class Context {
    private String text;

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }
}

我這邊寫的例子比較簡單,解釋器的子類只寫了一個。複雜一點的話可以寫多個文法解釋類,然後在客戶端根據條件實例化不同的子類進行解釋。

使用瞭解釋器模式就意味着可以很容易地改變和擴展文法,因爲該模式使用類來表示文法規則,你可使用繼承來改變或擴展該文法。

解釋器模式不足的地方在於:解釋器模式爲文法中的每一條規則至少定義了一個類,因此包含許多規則的文法可能難以管理和維護。

plantuml

@startuml
interface Expression{
{abstract}execute(Context context)
}
Expression <|.. Note
class Note{
execute(Context context)
} 
Context <.. Expression
class Context{
string text
}
@enduml

這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章