• 学习设计模式之解释器模式


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

    类结构图
    在这里插入图片描述
    Context
    包含解释之外的一些全局信息。
    AbstractExpression
    声明一个抽象的解释操作,这个接口为抽象语法树中所有的节点所共享。
    TerminalExpression
    终结符表达式,实现与文法中的终结符相关联的解释操作。
    NonterminalExpression
    非终结符表达式,为文法中的非终结符实现解释操作。

    代码示例
    乐谱大家都见过,那么我们来自定义一下 O 表示音阶、C D E F G A B 表示 Do-Re-Mi-Fa-So-La-Ti。

    public class Context {
        private String playText;
    
        public String getPlayText() {
            return playText;
        }
    
        public void setPlayText(String playText) {
            this.playText = playText;
        }
    }
    
    public abstract class Expression {
        abstract void excute(String key, String value);
    
        public void interpret(Context context) {
            if (null == context.getPlayText() || "".equals(context.getPlayText())) {
                return;
            }
            // 解析的字符串例如 O 3 E 0.5
            String playKey = context.getPlayText().substring(0, 1);
            context.setPlayText(context.getPlayText().substring(2));
            String value = context.getPlayText().substring(0, context.getPlayText().indexOf(" "));
            context.setPlayText(context.getPlayText().substring(context.getPlayText().indexOf(" ") + 1));
            excute(playKey, value);
        }
    }
    
    public class Note extends Expression {
        @Override
        void excute(String key, String 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 + "	");
        }
    }
    
    public class Scale extends Expression {
        @Override
        void excute(String key, String value) {
            String scale = "";
            switch (Integer.parseInt(value)) {
                case 1:
                    scale = "低音";
                    break;
                case 2:
                    scale = "中音";
                    break;
                case 3:
                    scale = "高音";
                    break;
            }
            System.out.print(scale + "	");
        }
    }
    

    客户端示例

    public class ExpressionClient {
        public static void main(String[] args) {
            Context context = new Context();
            context.setPlayText(
                    "O 2 E null G null A 3 E null G null D 3 E null G null A null O 3 C 1 O 2 A null G 1 C null E null E 3 ");
            Expression expression = null;
            while (context.getPlayText().length() > 0) {
                String str = context.getPlayText().substring(0, 1);
                switch (str) {
                    case "O":
                        expression = new Scale();
                        break;
                    case "C":
                    case "D":
                    case "E":
                    case "F":
                    case "G":
                    case "A":
                    case "B":
                    case "P":
                        expression = new Note();
                        break;
                }
                expression.interpret(context);
            }
        }
    }
    

    运行结果

    中音	3	5	6	3	5	2	3	5	6	高音	1	中音	6	5	1	3	3	
    Process finished with exit code 0
    

    优点
    可以比较方便的修改和扩展语法规则。

    缺点
    几乎针对每一个规则都定义了一个类,所以如果一个语法的规则比较多,那对于语法的维护工作也会变得非常困难。

  • 相关阅读:
    servlet多线程同步问题
    servlet之request
    servlet方法
    非静态内部类不能有静态成员
    接口与抽象类的区别
    枚举
    Install CUDA 6.0 on Ubuntu 14.04 LTS
    Introduction to Deep Learning Algorithms
    codeblocks 使用汇总
    矩阵奇异值分解(SVD)及其应用
  • 原文地址:https://www.cnblogs.com/liufeichn/p/11961631.html
Copyright © 2020-2023  润新知