定义
解释器模式(Interpreter Pattern):定义一个语言的文法,并且建立一个解释器来解释该语言中的句子,这里的“语言”是指使用规定格式和语法的代码。
通俗理解
现在的人工智(zhi)能(zhang)越来越厉害了,只要你和它讲一句话,它就会回复你。之前在网上有一个很火的视频,说的是小爱同学让天猫精灵放个屁[1],然后天猫精灵真的放了一个屁,真是求天猫精灵的心理阴影面积了。
玩笑归玩笑,其实这其中存在着很不公平的事情,就是对于小爱同学来讲,它是有一个叫“训练”的概念,只需要你进入训练的页面,在训练的关键词里面写上任何的内容以及小爱同学的回复,小爱同学就会根据你的关键词来回复你。例如,输入“世界上谁最帅?”,可能一开始小爱同学会说“世界上吴彦祖最帅!”,但是如果你在训练计划里面写上“世界上最帅的人是吴思成!”,那么以后当你问起小爱同学这个问题的时候,她就会回答你说:“世界上最帅的人是吴思成!”,哈哈😆,真是完美。
回归到编程上面来讲,我们需要透过这种现象去看到他的本质,这是怎么实现的呢?不谈神经网络之类复杂的东西,就讲简单的。有一个方案是把每一种情况都写出来,然后把他们的回答都写上,有什么输入,就在这一个键值对里面寻找答案,这会面临两个问题,第一是我的输入和回答都是固定的,输入“世界上谁最帅”,回答永远都是“世界上吴彦祖最帅!”,而不是“世界上最帅的人是吴思成!”;第二个问题是,没有扩展性,如果只有“世界上谁最帅”这个问题,那如果我需要新加一个“世界上谁最美”的问题却添加不了,很简单,程序写死了嘛。
那么要怎么解决这个问题呢?很简单,程序不写死,输入和输出都是用户定义的,输入写什么,输出写什么定义好,然后用户第二次输入的时候,就从这个这个池子里面去拿输出的数据,就能解决好这个问题了。这个就是解释器模式,通过输入变量,然后对这个变量进行解释,并得到相应的结果,就是解释器模式的根本所在。
当然,小爱同学的训练计划可没有那么简单,具体的就不了解了,但是可以模仿小爱同学,去写一个小成同学的人工智障。
示例
业务为小成同学的人工智障。
渣渣程序
小成同学
public class Xiaocheng {
private Map<String, String> questionAnswer = new HashMap<>(3);
public Xiaocheng() {
questionAnswer.put("您好", "您好,我是小成同学");
questionAnswer.put("世界上谁最帅?", "世界上吴彦祖最帅");
questionAnswer.put("打开飞行模式", "好的,已打开飞行模式");
}
public void answer(String question) {
String answer = questionAnswer.get(question);
if(answer == null) {
System.out.println("找不到问题:"+question);
return;
}
System.out.println(questionAnswer.get(question));
}
}
主入口
public class Main {
public static void main(String[] args) {
Xiaocheng xiaocheng = new Xiaocheng();
xiaocheng.answer("世界上谁最帅?");
}
}
//世界上吴彦祖最帅
优化
类图
程序
小成同学接口
public interface IXiaocheng {
String answer(Context context);
}
问题
public class Question implements IXiaocheng {
private String key;
public Question(String key) {
this.key = key;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String answer(Context context) {
return key;
}
}
答案
public class Answer implements IXiaocheng {
private IXiaocheng xiaocheng;
private static Map<String, String> answer1 = new HashMap<>(3);
private static Map<String, String> answer2 = new HashMap<>(1);
private String key2;
static {
answer1.put("您好", "您好,我是小成同学");
answer1.put("世界上谁最帅", "世界上吴彦祖最帅");
answer1.put("打开飞行模式", "好的,已打开飞行模式");
answer2.put("世界上谁最帅", "世界上吴思成最帅");
}
public Answer(IXiaocheng xiaocheng, String key2) {
this.xiaocheng = xiaocheng;
this.key2 = key2;
}
public String getKey2() {
return key2;
}
public void setKey2(String key2) {
this.key2 = key2;
}
@Override
public String answer(Context context) {
return getAnswer(key2).get(xiaocheng.answer(context));
}
private Map<String, String> getAnswer(String key) {
switch (key){
case "1":return answer1;
case "2":return answer2;
default:return answer1;
}
}
}
主入口
public class Main {
public static void main(String[] args) {
Context context = new Context();
context.translator("世界上谁最帅|2");
}
}
//世界上吴思成最帅
优点
- 容易改变和扩展语法;
- 实现文法,通过语法树进行解析。
缺点
- 一个规则需要定义一个类;
- 文法复杂的时候,不要用,用语法分析程序;
- 大量的循环和递归,效率不高。
应用场景
- 语言需要解析执行;
- 复杂的文法,层次会变得庞大而无法管理;
- 性能不是问题。
程序
吐槽
看来真的是一个难度大,而且还不常用的设计模式呀!
简单来讲,就是输入一句话,然后采用语法树进行解析,再做处理,解释器模式的精髓就在这个树上。
就没看明白是怎么一回事。
https://www.jianshu.com/p/8296146075b7
网友评论