• 设计模式之解释器模式


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

    解释器模式需要解决的是,如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的例子。这样就可以构建一个解释器,该解释器通过解释这些句子来解决问题。

    用了解释器模式,就意味着可以很容易地改变和扩展语法,因为该模式使用类来表示文法规则,你可以使用继承来改变或扩展该文法。解释器的不足之处是,该模式为文法中的每条规则至少定义了一个类,因此包含许多规则的文法难以管理和维护,所以当文法非常复杂时,建议使用其他技术如语法分析程序或编译器生成器来处理。

    一个简单的音乐解释器实现:

    public class PlayContext {
        private String text;
    
        public String getText() {
            return text;
        }
    
        public void setText(String text) {
            this.text = text;
        }
        
    }
    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.parseDouble(context.getText().substring(0, context.getText().indexOf(" ")));
                context.setText(context.getText().substring(context.getText().indexOf(" ") + 1));
                execute(playKey, playValue);
            }
        }
        public abstract void execute(String key, double value);
    }
    public class Note extends Expression{
    
        @Override
        public void execute(String key, double value) {
            // TODO Auto-generated method stub
            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
        public void execute(String key, double value) {
            // TODO Auto-generated method stub
            String scale = "";
            int val = (int) value;
            switch(val){
                case 1: scale = "低音"; break;
                case 2: scale = "中音"; break;
                case 3: scale = "高音"; break;
            }
            System.out.print(scale + " ");
        }
    
    }
    public class Test1 {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            PlayContext context = new PlayContext();
            System.out.println("上海滩: ");
            context.setText("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 str = context.getText().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);
                }
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    
    }

    这个例子不能代表解释器模式的全貌,因为它只有终结符表达式,而没有非终结符的表达式,要想真正理解解释器模式,还得研究其他例子。

  • 相关阅读:
    scrapy的自动限速(AutoThrottle)扩展
    js可以控制文件上传的速度吗?
    用DataReader 分页与几种传统的分页方法的比较
    jdbc分页查询
    几种分页方式分析.
    mybatis下的分页,支持所有的数据库
    java 物理分页和逻辑分页
    IBatis的分页研究
    JDBC分页
    用Java实现异构数据库的高效通用分页查询功能
  • 原文地址:https://www.cnblogs.com/shicaiyou/p/9364612.html
Copyright © 2020-2023  润新知