美文网首页
解析器模式 与 免费公交卡

解析器模式 与 免费公交卡

作者: 程就人生 | 来源:发表于2022-05-02 21:52 被阅读0次

    解析器模式,它能用在什么地方呢?

    解析器模式,它是如何解析的?

    解析器模式,它有哪些关键要素?

    解析器模式(Interpreter Pattern),给被分析对象定义一个语言,再设计一个解析器来解析语言中的句子。

    解释器模式常用于对简单语言的编译或分析。其中涉及到几个关键要素:文法、句子、语法树。

    “文法”指语言的语法规则,“句子”是语言集中的元素。

    关键代码涉及到四种角色:解析器接口、终结符、非终结符、上下文。

    看完上面定义,你是否和我一样一脸迷惑?不懂,不懂,还是看类图吧!

    下面看UML类图:


    类图说明:IExpression是解析器接口;TerminalExpression实现IExpression接口,是终结符类;AndExpression和OrExpression实现了IExpression接口,是非终结符类,且聚合了多个IExpression接口;context是上下文,定义了语法规则,在创建时聚合了多个IExpression接口的实现类。

    下面看代码实现步骤:
    1.解析器接口;

    /**
     * 1.抽象表达式接口(解析器接口)
     * @author 程就人生
     * @Date
     */
    public interface IExpression {
        // 解析内容
      public boolean interpret(String info);
    }
    

    2.非终结符表达式;

    /**
     * 2.1 具体实现类,非终结符表达式1
     * @author 程就人生
     * @Date
     */
    public class AndExpression implements IExpression {
    
      private IExpression terminalExpression1;
      
      private IExpression terminalExpression2;
      
      public AndExpression(IExpression terminalExpression1, IExpression terminalExpression2){
        this.terminalExpression1 = terminalExpression1;
        this.terminalExpression2 = terminalExpression2;
      }
      
      @Override
      public boolean interpret(String info) {
        return terminalExpression1.interpret(info) && terminalExpression2.interpret(info);
      }
    }
    
    /**
     * 2.2 具体实现类,非终结符表达式2
     * @author 程就人生
     * @Date
     */
    public class OrExpression implements IExpression {
      
      private IExpression terminalExpression1;
      
      private IExpression terminalExpression2;
      
      public OrExpression(IExpression terminalExpression1, IExpression terminalExpression2){
        this.terminalExpression1 = terminalExpression1;
        this.terminalExpression2 = terminalExpression2;
      }
    
      @Override
      public boolean interpret(String info) {
        return terminalExpression1.interpret(info) || terminalExpression2.interpret(info);
      }
    }
    

    3. 终结符表达式;

    /**
     * 2.3 具体实现类,终结符表达式
     * @author 程就人生
     * @Date
     */
    public class TerminalExperssion implements IExpression{
      // 结束符
        private String data;
        
        public TerminalExperssion(String data){
          this.data = data;
        }
        
      @Override
      public boolean interpret(String info) {
        // 包含时返回true
        if(info.contains(data)){
          return true;
        }
        return false;
      }
    }
    

    4.上下文环境类;

    /**
     * 4.上下文环境类
     * @author 程就人生
     * @Date
     */
    public class Context {
      
      private static String citys = "苏州";
      
      private static String oldPersion = "老人";
      
      private static String student = "学生";
      
      private IExpression cityPerson;
    
      public Context(){
        // 终端字符
        IExpression termianlExpression1 = new TerminalExperssion(oldPersion);
        IExpression termianlExpression2 = new TerminalExperssion(student);    
        // 是否为免费人群
        IExpression  termianlExpression3 = new OrExpression(termianlExpression1, termianlExpression2);
        // 城市是否为苏州
        IExpression termianlExpression4 = new TerminalExperssion(citys);
        cityPerson = new AndExpression(termianlExpression3, termianlExpression4);
      }
      
      public void opertion(String info){    
        if(cityPerson.interpret(info)){
          System.out.println(info + ":免费乘车");
        }else{
          System.out.println(info + ":支付车费2元");
        }
      }
    }
    

    测试代码:

    public static void main(String[] argo){
        Context context = new Context();
        context.opertion("苏州老人");
        
        context.opertion("苏州学生");
        
        context.opertion("上海老人");
        
        context.opertion("苏州成年人");
      }
    

    测试结果:

    苏州老人:免费乘车
    苏州学生:免费乘车
    上海老人:支付车费2元
    苏州成年人:支付车费2元
    

    这段代码的意思是:刷公交卡乘车,如果是苏州的老人、学生均可免费乘车,其他的都需要支付2元车费。

    在上下文Context类中定义了免费乘车的规则,并且使用终结符类、非终结符类来计算满足条件的乘客。终结符可以理解为关键条件,非终结符可以理解为关键条件之间的关系,这两者都继承自解析器接口,而这几个类都被上下文聚合。

    在实际使用时,直接输入一句话,即可解析句子并得出是否可以免费乘车的结果。这就是解析器模式的简单使用。

    最后总结
    解析器模式采用了“编译原理”来解释句子,其中涉及四种角色:解析器接口、终结符、非终结符、上下文,还涉及到一些概念:文法、句子,语法树等。

    思考题:
    除了纸上说的那些场景,检测一段文字中是否包含敏感字符,能否用解析器模式呢?

    参考文档:
    https://blog.csdn.net/d303577562/article/details/119040804

    相关文章

      网友评论

          本文标题:解析器模式 与 免费公交卡

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