解釋器模式

《大話設(shè)計(jì)模式》閱讀筆記和總結(jié)。原書是C#編寫的,本人用Java實(shí)現(xiàn)了一遍,包括每種設(shè)計(jì)模式的UML圖實(shí)現(xiàn)和示例代碼實(shí)現(xiàn)。
目錄:設(shè)計(jì)模式
Github地址:DesignPattern

說明

定義:解釋器模式(interpreter),給定一個(gè)語(yǔ)言,定義它的文法中的一種表示,并定義一個(gè)解釋器,這個(gè)解釋器使用該表示來解釋語(yǔ)言中的句子。

UML圖:

解釋器模式UML圖.png

代碼實(shí)現(xiàn):

AbstractExpression(抽象表達(dá)式),聲明一個(gè)抽象的解釋操作,這個(gè)接口為抽象語(yǔ)法樹中所有的節(jié)點(diǎn)所共享

abstract class AbstractExpression{
    public abstract void Interpret(Context context);
}

TerminalExpression(終結(jié)符表達(dá)式),實(shí)現(xiàn)與文法中的終結(jié)符相關(guān)聯(lián)的解釋操作。實(shí)現(xiàn)抽象表表達(dá)式中所要求的接口,主要是一個(gè)interpret()方法。文法中每一個(gè)終結(jié)符都有一個(gè)具體終結(jié)表達(dá)式與之相對(duì)應(yīng)。

class TerminalExpression extends AbstractExpression{

    @Override
    public void Interpret(Context context) {
        System.out.println("終端解釋器");
    }
}

NonterminalExpression(非終結(jié)符表達(dá)式),為文法中的非終結(jié)符實(shí)現(xiàn)解釋器操作。對(duì)文法中每一條規(guī)則R1、R2……Rn都需要一個(gè)具體的非終結(jié)符表達(dá)式類。通過實(shí)現(xiàn)抽象表達(dá)式的interpret()方法實(shí)現(xiàn)解釋操作。解釋操作以遞歸方式調(diào)用上面所提到的代表R1、R2……Rn中各個(gè)符號(hào)的實(shí)例變量

class NonterminalExpression extends AbstractExpression{

    @Override
    public void Interpret(Context context) {
        System.out.println("非終端解釋器");
    }
}

Context,包含解釋器之外的一些全局信息

class Context {
    private String input;
    private String output;

    public String getInput() {
        return input;
    }

    public void setInput(String input) {
        this.input = input;
    }

    public String getOutput() {
        return output;
    }

    public void setOutput(String output) {
        this.output = output;
    }
}

客戶端代碼

public class InterpreterPattern {
    public static void main(String[] args){
        Context context = new Context();
        List<AbstractExpression> list = new ArrayList<>();
        list.add(new TerminalExpression());
        list.add(new NonterminalExpression());
        list.add(new TerminalExpression());
        list.add(new TerminalExpression());

        for (AbstractExpression expression : list) {
            expression.Interpret(context);
        }
    }
}

運(yùn)行結(jié)果

終端解釋器
非終端解釋器
終端解釋器
終端解釋器

示例

例子:音樂解釋器。在以前程序演奏音樂的時(shí)候有一套規(guī)則,規(guī)定O表示音階,O 1表示低音,O 2表示中音,O 3表示高音,“P ”表示休止符,"C D E F G A B "表示“Do-Re-Mi-Fa-So-La-Ti”,音符長(zhǎng)度1表示一拍,2表示2拍,0.25表示四分之一拍,0.5表示半拍,所有字母和數(shù)字都要使用半角空格分開,例如上海灘第一句“浪奔”,可以寫成“O 2 E 0.5 G 0.5 A 3 ”,表示中音開始,演奏的是mi so la

UML圖:

解釋器模式示例UML圖.png

代碼實(shí)現(xiàn):

表達(dá)式類(AbstractExpression)

/**
 * 表達(dá)式類(AbstractExpression)
 */
public abstract class Expression {

    public void Interpret(PlayContext context) {
        if (context.getText().length() == 0) {
            return;
        } else {
            String playKey = context.getText().substring(0, 1);
            context.setText(context.getText().substring(2));
            double playValue = Double.valueOf(context.getText().substring(0, 1).trim());
            context.setText(context.getText().substring(context.getText().indexOf(" ") + 1));
            Excute(playKey, playValue);
        }

    }

    public abstract void Excute(String key, double value);
}

音符類(TerminalExpression)

public class Note extends Expression {
    @Override
    public void Excute(String key, double value) {
        String note = "";
        switch (key){
            case "C":
                note = "1";
                break;
            case "D":
                note = "2";
                break;
            case "E":
                note = "3";
                break;
            case "F":
                note = "4";
                break;
            case "G":
                note = "5";
                break;
            case "A":
                note = "6";
                break;
            case "B":
                note = "7";
                break;

        }

        System.out.print(note+" ");
    }
}

音階類(TerminalExpression)

public class Scale extends Expression {
    @Override
    public void Excute(String key, double value) {
        String scale = "";
        switch ((int) value){
            case 1:
                scale = "低音";
                break;
            case 2:
                scale = "中音";
                break;
            case 3:
                scale = "高音";
                break;

        }

        System.out.print(scale+" ");
    }
}

音速類(TerminalExpression)

public class Speed extends Expression{

    @Override
    public void Excute(String key, double value) {
        String speed;
        if(value<500){
            speed="快速";
        }else if(value>=1000){
            speed="慢速";
        }else{
            speed="中速";
        }
        System.out.print(speed+" ");
    }

}

演奏內(nèi)容類,Context

public class PlayContext {

    private String text;

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

    public String getText() {
        return text;
    }
}

客戶端代碼

public class Main {
    public static void main(String[] args){
        PlayContext context = new PlayContext();

        System.out.println("上海灘");

        context.setText("T 500 O 2 E 0.5 G 0.5 A 3 E 0.5 G 0.5 D 3 E 0.5 G 0.5 A 0.5 O 3 C 1 O 2 A 0.5 G 1 C 0.5 E 0.5 D 3 ");
        Expression expression = null;
        try {
            while (context.getText().length() > 0) {
                String string = context.getText().substring(0, 1);
                switch (string) {
                    case "O":
                        expression = new Scale();// 為O時(shí),實(shí)例化音階
                        break;
                    case "T":
                        expression = new Speed();
                        break;
                    case "C":
                    case "D":
                    case "E":
                    case "F":
                    case "G":
                    case "A":
                    case "B":
                    case "P":
                        expression = new Note();// 實(shí)例化音符
                        break;
                    default:
                        break;
                }
                expression.Interpret(context);
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}

運(yùn)行結(jié)果

上海灘
快速 中音 3 5 6 3 5 2 3 5 6 高音 1 中音 6 5 1 3 2 
最后編輯于
?著作權(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)容