文章目录

  • 引子
  • 解释器模式
  • 总结
    • 优点
    • 缺点
  • 后记

引子

小美最近被家里人催着相亲,家里亲戚介绍了好几个男生,小美都不满意。小美的要求高着呢:起码要有房吧?年收入不能低于20万吧?身高最低也要175cm吧?年龄也不能太大,不能超过30岁吧?学历么也要本科起步吧?

什么?你觉得我要求太高了?好说,如果你家里很有钱的话,其他条件也可以放宽嘛!

小美不愧是程序媛出身,她把自己的相亲条件列成了一条公式:

房子 >= 1 && 年收入 >= 20 && 身高 >= 175 && 年龄 < 30 && 学历 >= 4 || 财产 >= 1000

小美把这条公式交给了媒婆,并嘱咐一定要满足这条公式的男生才可以安排相亲哦。媒婆一看直接懵逼,怎么还有公式呀,姑娘,我只是个牵线的,又没学过数学,你这不是为难我吗?

小美说道:您不要急,套用了公式才能保证结果正确嘛,您听我细细道来,这个还得从解释器模式开始讲起…

媒婆:这我听不懂啊…

小美:不,您听得懂…

解释器模式

解释器模式:为某个语言定义它的语法(或者叫文法)表示,并定义一个解释器用来处理这个语法。(Interpreter pattern is used to defines a grammatical representation for a language and provides an interpreter to deal with this grammar.)

用大白话说就是:我们可以自己定义一些符号,然后我们给这些符号设定规则,解释权在我们自己手里。

比如一个表达式”1#2!3“,我们可以定义”#“表示”+“号,”!”表示“-”号,怎么解释我们自己说了算。

解释器模式的类图如下:

我用表达式a+b-c来套用一下:

  • AbstractExpression:抽象解释器,具体的解释任务由各个实现类完成,具体的解释器分别由TerminalExpression和NonterminalExpression完成。
  • TerminalExpression:终结符表达式,就是对应“a”,“b”,“c”。
  • NonterminalExpression:非终结符表达式,就是对应“+”,“-”符号。
  • Context:解释器之外的一些全局信息,在下面的例子中就是客户端中的Map。

针对相亲的表达式,采用了下图的结构:

说完,小美就抛出了一段代码:

这里我们假设“ >= ”,“<”符号的优先级比“&&”和“||”高,“&&”的优先级比“||”高。

表达式接口类:

/*** 表达式接口*/
public interface Expression {/*** 解释表达式* @param states* @return*/boolean interpret(Map<String, Integer> states);
}

大于等于表达式类:

/*** 大于等于表达式*/
public class GreaterOrEqualExpression implements Expression {private String key;private int value;public GreaterOrEqualExpression(String key, int value) {this.key = key;this.value = value;}public GreaterOrEqualExpression(String strExpression) {String[] elements = strExpression.trim().split("\\s+");if(elements.length != 3 || !elements[1].trim().equals(">=")) {throw new RuntimeException("Expression is invalid: " + strExpression);}this.key = elements[0].trim();this.value = Integer.parseInt(elements[2].trim());}/*** 解释大于等于表达式* @param states* @return*/@Overridepublic boolean interpret(Map<String, Integer> states) {if(!states.containsKey(key)) {return false;}int stateValue = states.get(key);return stateValue >= value;}
}

小于表达式类:

/*** 小于表达式*/
public class LessExpression implements Expression {private String key;private int value;public LessExpression(String key, int value) {this.key = key;this.value = value;}public LessExpression(String strExpression) {String[] elements = strExpression.trim().split("\\s+");if(elements.length != 3 || !elements[1].trim().equals("<")) {throw new RuntimeException("Expression is invalid: " + strExpression);}this.key = elements[0].trim();this.value = Integer.parseInt(elements[2].trim());}/*** 解释小于表达式* @param states* @return*/@Overridepublic boolean interpret(Map<String, Integer> states) {if(!states.containsKey(key)) {return false;}int stateValue = states.get(key);return stateValue < value;}
}

与表达式类:

/*** 与表达式*/
public class AndExpression implements Expression {private List<Expression> expressions = new ArrayList<>();public AndExpression(List<Expression> expressions) {this.expressions = expressions;}public AndExpression(String strAndExpression) {String[] strExpressions = strAndExpression.split("&&");for(String strExpr : strExpressions) {if(strExpr.contains(">=")) {expressions.add(new GreaterOrEqualExpression(strExpr));} else if(strExpr.contains("<")) {expressions.add(new LessExpression(strExpr));} else {throw new RuntimeException("Expression is invalid: " + strAndExpression);}}}/*** 解释与表达式** @param states* @return*/@Overridepublic boolean interpret(Map<String, Integer> states) {for(Expression expr : expressions) {if(!expr.interpret(states)) {return false;}}return true;}
}

或表达式类:

/*** 或表达式*/
public class OrExpression implements Expression {private List<Expression> expressions = new ArrayList<>();public OrExpression(List<Expression> expressions) {this.expressions = expressions;}public OrExpression(String strOrExpression) {String[] andExpressions = strOrExpression.split("\\|\\|");for(String andExpr : andExpressions) {// &&表达式的优先级比||表达式高,计算||表达式之前要先计算&&表达式// 这里复用&&表达式expressions.add(new AndExpression(andExpr));}}/*** 解释或表达式** @param states* @return*/@Overridepublic boolean interpret(Map<String, Integer> states) {for(Expression expr : expressions) {if(expr.interpret(states)) {return true;}}return false;}
}

相亲表达式解析类:

/*** 相亲表达式解析*/
public class BlindDateRuleInterpreter {private Expression expression;/*** 先从或表达式开始解析* @param ruleExpression*/public BlindDateRuleInterpreter(String ruleExpression) {this.expression = new OrExpression(ruleExpression);}public boolean interpret(Map<String, Integer> states) {return expression.interpret(states);}
}

客户端测试类:

/*** 客户端测试类*/
public class ClientTest {public static void main(String[] args) {// 为了更贴近生活,这里的key就用中文了String rule = "房子 >= 1 && 年收入 >= 20 && 身高 >= 175 && 年龄 < 30 && 学历 >= 4 || 财产 >= 1000";BlindDateRuleInterpreter interpreter = new BlindDateRuleInterpreter(rule);Map<String, Integer> states = new HashMap<>();states.put("房子", 1);states.put("年收入", 20);states.put("身高", 176);states.put("年龄", 28);states.put("学历", 4);states.put("财产", 100);// 根据表达式判断相亲条件boolean qualified = interpreter.interpret(states);if(qualified) {System.out.println("兄弟,恭喜你符合条件啦!");} else {System.out.println("兄弟,还需继续努力!");}}
}

输出:

兄弟,恭喜你符合条件啦!

总结

解释器模式描述了如何为简单的语言定义一个文法,如何在该语言中表示一个句子,以及如何解释这些句子。

解释器的核心就是将语法解析的工作拆分到各个小类中,以此来避免大而全的解析类。一般的做法是,将语法规则拆分成一些小的独立的单元,然后对每个单元进行解析,最终合并为对整个语法规则的解析。

优点

  • 解释器是一个简单语法分析工具,它最显著的优点就是扩展性,修改语法规则只要修改相应的非终结符表达式就可以了,若扩展语法,则只要增加非终结符类就可以了。

缺点

  • 解释器模式会引起类膨胀,每个语法都要产生一个非终结符表达式,语法规则比较复杂时,就可能产生大量的类文件,为维护带来了很多麻烦。
  • 解释器模式可能会使用大量的循环和递归,效率是一个不容忽视的问题,特别是用于解析复杂、冗长的语法时,效率比较低。

后记

小美:阿姨您好,这都三个月过去了,您怎么一个男生也没给我介绍啊?

媒婆:哎呀,这不是没有合适的嘛!我把十几个男生的条件套进公式只有一个符合条件的,然后对方又觉得你的条件不够好啦。别急,我再给你找找。

小美:额…那我不要公式了,只要人品好、价值观正就行,品性好最重要,其他的见了面再说吧。

媒婆:那好,这就好办了嘛,我给你留意留意。

解释器模式--相亲的公式相关推荐

  1. 设计模式之禅【解释器模式】

    真刀实枪之解释器模式 从模型公式说起 需求,输入一个模型公式,然后输入模型中的参数,运算出结果 设计要求 公式可以运行时编辑 高扩展性 效率可以暂不考虑 分析下这个需求,还是比较简单的,就是有一套模板 ...

  2. python设计模式(十三):解释器模式

    此前已经将创造型模式.结构性模式分享了,后面将分享模式设计中的另一种典型模式:行为型模式. 创造型模式是解决实体的生成问题.结构性模式是为了解决实体的组合.搭配问题 ,而行为型设计模式的出现是为了解决 ...

  3. 第19章 解释器模式(Interpreter Pattern)

    原文 第19章 解释器模式(Interpreter Pattern) 解释器模式 导读:解释器模式,平常用的比较的少,所以在写这个模式之前在博客园搜索了一番,看完之后那叫一个头大.篇幅很长,我鼓足了劲 ...

  4. 设计模式 — 行为型模式 — 解释器模式

    目录 文章目录 目录 解释器模式 应用场景 代码示例 解释器模式 解释器模式,开发者自定义一种 "有内涵" 的语言(或者叫字符串),并设定相关的解释规则,输入该字符串后可以输出公认 ...

  5. Java设计模式之行为型:解释器模式

    一.什么是解释器模式:         解释器模式,就是定义语言的文法,并建立一个解释器来解释该语言中的句子,通过构建解释器,解决某一频繁发生的特定类型问题实例. 这里我们将语言理解成使用规定格式和语 ...

  6. 23种设计模式之解释器模式

    为什么80%的码农都做不了架构师?>>>    定义:给定一种语言,定义他的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中句子. 类型:行为类模式 类图: 解释器模 ...

  7. 设计模式:解释器模式(Interpreter)

    欢迎支持笔者新作:<深入理解Kafka:核心设计与实践原理>和<RabbitMQ实战指南>,同时欢迎关注笔者的微信公众号:朱小厮的博客. 欢迎跳转到本文的原文链接:https: ...

  8. Android设计模式之——解释器模式

    一.介绍 解释器模式(Interpreter Pattern)是一种用的比较少的行为型模式,其提供了一种解释语言的语法或表达式的方式,该模式定义了一个表达式接口,通过该接口解释一个特定的上下文.在这么 ...

  9. 解释器android,Android的设计模式-解释器模式

    前言 Android的设计模式系列文章介绍,欢迎关注,持续更新中: 1.定义 给定一门语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子. 2.介绍 解释器模式属于行 ...

最新文章

  1. 04使用模板显示内容
  2. 二十万字C/C++、嵌入式软开面试题全集宝典七
  3. VC++ 创建Windows服务
  4. 数字信号处理笔记1-信号与常见操作
  5. JAVA进阶教学之(StringBuider进行字符串拼接)
  6. 打印机(Brother MFC-7860DN)一直提示更换墨盒
  7. php安装make报错信息及解决方法
  8. 数据挖掘的技术都有哪些?
  9. Ubuntu16.04关闭笔记本触摸板
  10. 什么?小白也可以拥有PLS回归系数(Beta系数图)!
  11. 在线正则表达式大全测试
  12. 测量计算方位角万能通用公式及VB、VBA源代码
  13. 英文文献检索网站(转)
  14. 利用Excel函数对 重复数据进行编号解决方法
  15. 由113号元素鉨114号元素夫115号元素镆元素汞银金等元素构成的超导体
  16. MFC如何在单文档下添加背景图片
  17. 用DIV+CSS技术设计的餐饮美食网页与实现制作(web前端网页制作课作业)HTML+CSS+JavaScript美食汇响应式美食菜谱网站模板
  18. [转载]总结-七大人生工具_李晓瑞_廊坊师范提高班十五期_新浪博客
  19. 福布斯:加密货币和区块链正在如何帮助电竞实现突破
  20. 【mxGraph】源码学习:(5)mxGraph

热门文章

  1. 专访第一代车间程序员:ET工业大脑数学博士夏分
  2. 如何成为一个积极主动的项目经理
  3. 哈工大SCIR情感回复系统Babbling
  4. 计算机软件著作权登记证书申请流程有哪些
  5. 中间件:Nginx工作使用记录(反向代理)
  6. 【微信小程序全栈开发课程】课程目录(mpvue+koa2+mysql)
  7. 身为Python程序员的你,有了这个,再也不怕“成语接龙红包“抢不到了
  8. MCS-51单片机外部引脚及总线接口/答疑
  9. window7安装oracle9i,win 7安装oracle11g企业版
  10. 平面设计如何做出空间创意作品