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

解析器模式 与 免费公交卡

作者: 程就人生 | 来源:发表于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