小白谈谈解释器模式

概念

解释器模式就是按照给定的语法,进行解析。给定一个语言, 定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。

实现

案例:小明饭店举行了一个促销活动,凡是到店的顾客名字包含“明”字,或者
籍贯为广州的都可以享受半价优惠,每当顾客进店都需要到门口的电脑上进行身份登记,输入格式为:深圳,阿花

直接上代码:
首先我们定义一个抽象表达式类:

public interface AbstractExpression {
    public boolean interpret(String info);    //解释方法
}

然后对抽象表达式进行具体实现,我们输入的字符串中,逗号是不需要进行解析的,所以我们把逗号之前,与逗号之后的字段分隔开,包含逗号时,改字符串为非终结符表达式类:

//非终结符表达式类
public class AndExpression implements AbstractExpression {

    private AbstractExpression city = null;

    private AbstractExpression name = null;

    public AndExpression(AbstractExpression city, AbstractExpression name) {
        this.city = city;
        this.name = name;
    }

    @Override
    public boolean interpret(String info) {

        //把输入的字符串切分成两份,以逗号分隔开
        String str[] = info.split(",");

        //判断籍贯是否为广州
        boolean IsCity = city.interpret(str[0]);

        //判断名字是否包含明
        boolean IsName = name.interpret(str[1]);

        if(IsCity || IsName){
            return true;
        }
        return false;
    }
}

切分完两段终结符表达式后,我们得到两段终结符表达式:

//终结符表达式类
public class TerminalExpression implements AbstractExpression {

    private String key;

    public TerminalExpression(String key) {
        this.key = key;
    }

    @Override
    public boolean interpret(String info) {

        if(key.contains(info)){
            return true;
        }
        return false;
    }
}

准备工作已经做好了,那么就需要定义一个环境类,填入需要的关键词:

//环境类
public class Context {

    //定义籍贯关键词
    private String cityKey = "广州";

    //定义名字关键词
    private String key = "明";

    private AbstractExpression city;

    private AbstractExpression name;

    private AbstractExpression rule;

    public Context(){
        city = new TerminalExpression(cityKey);
        name = new TerminalExpression(key);
        rule = new AndExpression(city,name);
    }

    //判断顾客是否能享受半价
    public void IsHalf(String info){

        //对输入信息进行判断
        boolean result = rule.interpret(info);

        if(result){
            System.out.println("恭喜您,获得半价优惠!");
        }else{
            System.out.println("很遗憾,你与本次优惠条件不符ㄒoㄒ");
        }
    }
}

最后就是我们的测试类:

public class Main {

    public static void main(String[] args) {

        //实例环境类
        Context context = new Context();

        String p1 = "深圳,阿花";
        String p2 = "北京,康熙";
        String p3 = "上海,乾隆";
        String p4 = "广州,郭明强";
        String p5 = "新疆,尔明";
        String p6 = "广州,二百五";

        context.IsHalf(p1);
        context.IsHalf(p2);
        context.IsHalf(p3);
        context.IsHalf(p4);
        context.IsHalf(p5);
        context.IsHalf(p6);
    }
}

测试结果:
在这里插入图片描述

优点:有较好的扩展性,修改语法规则只要修改相应的非终结符表达式就可以了,若扩展语法,则只要增加非终结符类就可以了

缺点:容易产生类膨胀,使维护变得复杂, 其次,解释器模式采用递归调用方法。每个非终结符表达式只关心与自己有关的表达式,每个表达式需要知道终的结果,必须一层一层的剥茧,无论是面向过程的语言还是面向对象的语言,递归都是在必要条件下使用的,它导致调试非常复杂,用于解析复杂、冗长的语法时,效率是难以忍受的


本文参考:《设计模式之禅》
本文的代码:https://pan.baidu.com/s/1nVvYZaqoNUT700LRLFQrkg
提取码:vx8y

发布了48 篇原创文章 · 获赞 0 · 访问量 650

猜你喜欢

转载自blog.csdn.net/weixin_44943485/article/details/105359407
今日推荐