解释器模式

作者: fancy_boy_石嘉成 | 来源:发表于2018-07-29 17:52 被阅读0次

    《大话设计模式》阅读笔记和总结。原书是C#编写的,本人用Java实现了一遍,包括每种设计模式的UML图实现和示例代码实现。
    目录:设计模式
    Github地址:DesignPattern

    说明

    定义:解释器模式(interpreter),给定一个语言,定义它的文法中的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。

    UML图:

    解释器模式UML图.png

    代码实现:

    AbstractExpression(抽象表达式),声明一个抽象的解释操作,这个接口为抽象语法树中所有的节点所共享

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

    TerminalExpression(终结符表达式),实现与文法中的终结符相关联的解释操作。实现抽象表表达式中所要求的接口,主要是一个interpret()方法。文法中每一个终结符都有一个具体终结表达式与之相对应。

    class TerminalExpression extends AbstractExpression{
    
        @Override
        public void Interpret(Context context) {
            System.out.println("终端解释器");
        }
    }
    

    NonterminalExpression(非终结符表达式),为文法中的非终结符实现解释器操作。对文法中每一条规则R1、R2……Rn都需要一个具体的非终结符表达式类。通过实现抽象表达式的interpret()方法实现解释操作。解释操作以递归方式调用上面所提到的代表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);
            }
        }
    }
    

    运行结果

    终端解释器
    非终端解释器
    终端解释器
    终端解释器
    

    示例

    例子:音乐解释器。在以前程序演奏音乐的时候有一套规则,规定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表示半拍,所有字母和数字都要使用半角空格分开,例如上海滩第一句“浪奔”,可以写成“O 2 E 0.5 G 0.5 A 3 ”,表示中音开始,演奏的是mi so la

    UML图:

    解释器模式示例UML图.png

    代码实现:

    表达式类(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+" ");
        }
    
    }
    

    演奏内容类,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());
            }
        }
    }
    

    运行结果

    上海滩
    快速 中音 3 5 6 3 5 2 3 5 6 高音 1 中音 6 5 1 3 2 
    

    相关文章

      网友评论

        本文标题:解释器模式

        本文链接:https://www.haomeiwen.com/subject/voctvftx.html