设计模式之解释器模式

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

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

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

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

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

}

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

 

posted @ 2018-07-25 10:41  Ericyshi  阅读(117)  评论(0编辑  收藏  举报