解釋器模式

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

說明

定義:解釋器模式(interpreter),給定一個語言颤绕,定義它的文法中的一種表示幸海,并定義一個解釋器祟身,這個解釋器使用該表示來解釋語言中的句子。

UML圖:

解釋器模式UML圖.png

代碼實現(xiàn):

AbstractExpression(抽象表達式),聲明一個抽象的解釋操作物独,這個接口為抽象語法樹中所有的節(jié)點所共享

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

TerminalExpression(終結(jié)符表達式)袜硫,實現(xiàn)與文法中的終結(jié)符相關(guān)聯(lián)的解釋操作。實現(xiàn)抽象表表達式中所要求的接口议纯,主要是一個interpret()方法父款。文法中每一個終結(jié)符都有一個具體終結(jié)表達式與之相對應。

class TerminalExpression extends AbstractExpression{

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

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

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);
        }
    }
}

運行結(jié)果

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

示例

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

UML圖:

解釋器模式示例UML圖.png

代碼實現(xiàn):

表達式類(AbstractExpression)

/**
 * 表達式類(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時,實例化音階
                        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();// 實例化音符
                        break;
                    default:
                        break;
                }
                expression.Interpret(context);
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}

運行結(jié)果

上海灘
快速 中音 3 5 6 3 5 2 3 5 6 高音 1 中音 6 5 1 3 2 
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市况既,隨后出現(xiàn)的幾起案子屋群,更是在濱河造成了極大的恐慌,老刑警劉巖坏挠,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件芍躏,死亡現(xiàn)場離奇詭異,居然都是意外死亡降狠,警方通過查閱死者的電腦和手機对竣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進店門庇楞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人否纬,你說我怎么就攤上這事吕晌。” “怎么了临燃?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵睛驳,是天一觀的道長。 經(jīng)常有香客問我膜廊,道長乏沸,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任爪瓜,我火速辦了婚禮蹬跃,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘铆铆。我一直安慰自己蝶缀,他們只是感情好,可當我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布薄货。 她就那樣靜靜地躺著翁都,像睡著了一般。 火紅的嫁衣襯著肌膚如雪谅猾。 梳的紋絲不亂的頭發(fā)上柄慰,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天,我揣著相機與錄音赊瞬,去河邊找鬼。 笑死贼涩,一個胖子當著我的面吹牛巧涧,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播遥倦,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼谤绳,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了袒哥?” 一聲冷哼從身側(cè)響起缩筛,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎堡称,沒想到半個月后瞎抛,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡却紧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年桐臊,在試婚紗的時候發(fā)現(xiàn)自己被綠了胎撤。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡断凶,死狀恐怖伤提,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情认烁,我是刑警寧澤肿男,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站却嗡,受9級特大地震影響舶沛,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜稽穆,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一冠王、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧舌镶,春花似錦柱彻、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至否灾,卻和暖如春卖擅,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背墨技。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工惩阶, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人扣汪。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓断楷,卻偏偏與公主長得像,于是被迫代替她去往敵國和親崭别。 傳聞我的和親對象是個殘疾皇子冬筒,可洞房花燭夜當晚...
    茶點故事閱讀 44,779評論 2 354

推薦閱讀更多精彩內(nèi)容