解释器模式--相亲的公式
文章目录
- 引子
- 解释器模式
- 总结
- 优点
- 缺点
- 后记
引子
小美最近被家里人催着相亲,家里亲戚介绍了好几个男生,小美都不满意。小美的要求高着呢:起码要有房吧?年收入不能低于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("兄弟,还需继续努力!");}}
}
输出:
兄弟,恭喜你符合条件啦!
总结
解释器模式描述了如何为简单的语言定义一个文法,如何在该语言中表示一个句子,以及如何解释这些句子。
解释器的核心就是将语法解析的工作拆分到各个小类中,以此来避免大而全的解析类。一般的做法是,将语法规则拆分成一些小的独立的单元,然后对每个单元进行解析,最终合并为对整个语法规则的解析。
优点
- 解释器是一个简单语法分析工具,它最显著的优点就是扩展性,修改语法规则只要修改相应的非终结符表达式就可以了,若扩展语法,则只要增加非终结符类就可以了。
缺点
- 解释器模式会引起类膨胀,每个语法都要产生一个非终结符表达式,语法规则比较复杂时,就可能产生大量的类文件,为维护带来了很多麻烦。
- 解释器模式可能会使用大量的循环和递归,效率是一个不容忽视的问题,特别是用于解析复杂、冗长的语法时,效率比较低。
后记
小美:阿姨您好,这都三个月过去了,您怎么一个男生也没给我介绍啊?
媒婆:哎呀,这不是没有合适的嘛!我把十几个男生的条件套进公式只有一个符合条件的,然后对方又觉得你的条件不够好啦。别急,我再给你找找。
小美:额…那我不要公式了,只要人品好、价值观正就行,品性好最重要,其他的见了面再说吧。
媒婆:那好,这就好办了嘛,我给你留意留意。
解释器模式--相亲的公式相关推荐
- 设计模式之禅【解释器模式】
真刀实枪之解释器模式 从模型公式说起 需求,输入一个模型公式,然后输入模型中的参数,运算出结果 设计要求 公式可以运行时编辑 高扩展性 效率可以暂不考虑 分析下这个需求,还是比较简单的,就是有一套模板 ...
- python设计模式(十三):解释器模式
此前已经将创造型模式.结构性模式分享了,后面将分享模式设计中的另一种典型模式:行为型模式. 创造型模式是解决实体的生成问题.结构性模式是为了解决实体的组合.搭配问题 ,而行为型设计模式的出现是为了解决 ...
- 第19章 解释器模式(Interpreter Pattern)
原文 第19章 解释器模式(Interpreter Pattern) 解释器模式 导读:解释器模式,平常用的比较的少,所以在写这个模式之前在博客园搜索了一番,看完之后那叫一个头大.篇幅很长,我鼓足了劲 ...
- 设计模式 — 行为型模式 — 解释器模式
目录 文章目录 目录 解释器模式 应用场景 代码示例 解释器模式 解释器模式,开发者自定义一种 "有内涵" 的语言(或者叫字符串),并设定相关的解释规则,输入该字符串后可以输出公认 ...
- Java设计模式之行为型:解释器模式
一.什么是解释器模式: 解释器模式,就是定义语言的文法,并建立一个解释器来解释该语言中的句子,通过构建解释器,解决某一频繁发生的特定类型问题实例. 这里我们将语言理解成使用规定格式和语 ...
- 23种设计模式之解释器模式
为什么80%的码农都做不了架构师?>>> 定义:给定一种语言,定义他的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中句子. 类型:行为类模式 类图: 解释器模 ...
- 设计模式:解释器模式(Interpreter)
欢迎支持笔者新作:<深入理解Kafka:核心设计与实践原理>和<RabbitMQ实战指南>,同时欢迎关注笔者的微信公众号:朱小厮的博客. 欢迎跳转到本文的原文链接:https: ...
- Android设计模式之——解释器模式
一.介绍 解释器模式(Interpreter Pattern)是一种用的比较少的行为型模式,其提供了一种解释语言的语法或表达式的方式,该模式定义了一个表达式接口,通过该接口解释一个特定的上下文.在这么 ...
- 解释器android,Android的设计模式-解释器模式
前言 Android的设计模式系列文章介绍,欢迎关注,持续更新中: 1.定义 给定一门语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子. 2.介绍 解释器模式属于行 ...
最新文章
- 04使用模板显示内容
- 二十万字C/C++、嵌入式软开面试题全集宝典七
- VC++ 创建Windows服务
- 数字信号处理笔记1-信号与常见操作
- JAVA进阶教学之(StringBuider进行字符串拼接)
- 打印机(Brother MFC-7860DN)一直提示更换墨盒
- php安装make报错信息及解决方法
- 数据挖掘的技术都有哪些?
- Ubuntu16.04关闭笔记本触摸板
- 什么?小白也可以拥有PLS回归系数(Beta系数图)!
- 在线正则表达式大全测试
- 测量计算方位角万能通用公式及VB、VBA源代码
- 英文文献检索网站(转)
- 利用Excel函数对 重复数据进行编号解决方法
- 由113号元素鉨114号元素夫115号元素镆元素汞银金等元素构成的超导体
- MFC如何在单文档下添加背景图片
- 用DIV+CSS技术设计的餐饮美食网页与实现制作(web前端网页制作课作业)HTML+CSS+JavaScript美食汇响应式美食菜谱网站模板
- [转载]总结-七大人生工具_李晓瑞_廊坊师范提高班十五期_新浪博客
- 福布斯:加密货币和区块链正在如何帮助电竞实现突破
- 【mxGraph】源码学习:(5)mxGraph
热门文章
- 专访第一代车间程序员:ET工业大脑数学博士夏分
- 如何成为一个积极主动的项目经理
- 哈工大SCIR情感回复系统Babbling
- 计算机软件著作权登记证书申请流程有哪些
- 中间件:Nginx工作使用记录(反向代理)
- 【微信小程序全栈开发课程】课程目录(mpvue+koa2+mysql)
- 身为Python程序员的你,有了这个,再也不怕“成语接龙红包“抢不到了
- MCS-51单片机外部引脚及总线接口/答疑
- window7安装oracle9i,win 7安装oracle11g企业版
- 平面设计如何做出空间创意作品