设计模式笔记之十五 (解释器模式)

解释器模式

解释器模式就是定义一种语言,并定义这个语言的解释器,解释器能够按照定义好的语法来将这种语言‘翻译’成使用者能理解的语言。

广泛上来讲,Java是一种定义的语言,JVM就是一种‘解释器’,而计算机就是最终的使用者。我们写一段Java代码,而计算机只认识0101的机器语言,JVM就是将Java代码解释成0101的机器语言让计算机能够理解并运行。

我们还是以我们实验室的实例来说明下这个模式。

最近我们实验室的兽人工厂拿到了老总的一个批示:


class LaoZong {
private String order = "MN1n2";

public String getOrder() {
return order;
}

public void setOrder(String order) {
this.order = order;
}

}

class ShouRenFactory {
public void readOrder() {
LaoZong lz = new LaoZong();
System.out.println(lz.getOrder());
}
}

public class Interpreter {
public static void main(String[] args) {
new ShouRenFactory().readOrder();
}
}

于是兽人工厂拿到老板的指令就是"MN1n2"。完全不明白要干什么,于是需要找老板秘书来解释下:


class ShouRenFactory {
public void readOrder() {
LaoZong lz = new LaoZong();
MiShu ms = new MiShu();

System.out.println(ms.translate(lz.getOrder()));
}
}

class MiShu {
public String translate(String order) {
//Black Box
String realWord = "生产男兽人1个女兽人2个";
return realWord;
}
}

现在我们兽人工厂终于知道了老总的命令:"生产男兽人1个女兽人2个",
但是秘书是怎么知道老总的命令的呢,如果兽人工厂也能知道秘书解析的过程,那就不用每次都麻烦秘书来解释了。毕竟秘书是老板用的,而不是兽人工厂用的。

请教秘书解析的方法:

秘书说她先判断每一个字幕或者数组是什么类型的命令,然后再用不同的解释方法解释不同的类型,比如说‘M’就是命令类的,‘Nn’是产品名称类的,数字就是数量类的。

于是兽人工厂就根据秘书的方法实现了自己的解析方式:


public class Interpreter {
public static void main(String[] args) {
new ShouRenFactory().readOrder();
}
}

class ShouRenFactory {
private String translate(String order) {
String realOrder = "";

//组装解释器
List<Expression> expressions = new ArrayList<Expression>();
expressions.add(new CommandExpression());
expressions.add(new ProductExpression());
expressions.add(new NumberExpression());

//挨个解释老总的命令
String[] codes = order.split("");
for (String code :codes) {
for (Expression expression : expressions) {
if (expression.matches(code)) {
realOrder += expression.excute(code);
break;
}
}
}

return realOrder;
}
public void readOrder() {
LaoZong lz = new LaoZong();

System.out.println(translate(lz.getOrder()));
}
}

abstract class Expression {
protected HashMap<String, String> map = new HashMap<String, String>();

private Set<String> getMarkers() {
return map.keySet();
}

public boolean matches(String code) {
return getMarkers().contains(code);
}

abstract public String excute(String code);
}

class CommandExpression extends Expression {

public CommandExpression() {
map.put("M", "创建");
map.put("D", "销毁");
map.put("E", "维修");
}

@Override
public String excute(String code) {
return map.get(code);
}
}

class ProductExpression extends Expression {

public ProductExpression() {
map.put("N", "男兽人");
map.put("n", "女兽人");
}

@Override
public String excute(String code) {
return map.get(code);
}
}

class NumberExpression extends Expression {

public NumberExpression() {
}

@Override
public boolean matches(String code) {
return code.matches("[0-9]");
}

@Override
public String excute(String code) {
return code + "个";
}
}

这样我们就实现了一个简单的解析器模式,在这种模式下,我们可以很简单的增加或者删除某种解析器。

解析器模式是一种易于理解但难于应用的模式。
除非在“一种特定类型的问题发生的频率足够高”的情况下,我们并不推荐使用此模式。因为当文法特别复杂时,会产生很多类,这对维护来说比较困难。总的来说在文法比较简单且发生频率很高的情况下才使用此模式。

时间: 2024-10-11 03:51:37

设计模式笔记之十五 (解释器模式)的相关文章

设计模式(二十)解释器模式(Interpreter)-行为型

解释器模式Interpreter 解释器模式在软件开发中应用的比较少,它主要用在底层的编程语言设计上,因此不太容易理解. 联想:传一个算数表达式,对加减乘除自动匹配,能够自动计算其结果. 原理图 解释器模式实现原理图 单个运算符的数学公式计算机可以用来理解这个解释器模式的使用. 参考文献 [1] 郭峰.深入浅出设计莫模式[M].中国铁道出版社,2013(1):415-423.

Java设计模式菜鸟系列(十五)建造者模式建模与实现

转载请注明出处:http://blog.csdn.net/lhy_ycu/article/details/39856435 建造者模式(Builder):工厂类模式提供的是创建单个类的模式,而建造者模式则是将各种产品集中起来进行管理.简单起见,就拿之前的工厂方法模式进行修改一下就可以得到建造者模式. 一.uml建模: 二.代码实现 /** * 示例:建造者模式 * * 与工厂模式的区别:工厂类模式提供的是创建单个类,而建造者模式则是将各种产品集中起来进行管理 */ interface Sende

设计模式笔记(十)------ 模板方法模式

在实际工作中,有时需要编写很多重复性的代码,这样的代码不易维护更容易出错.在小型项目中,有个模式非常适用此类情况. 模板方法模式:定义一个操作中的算法的骨架,而将步骤延迟到子类中.模板方法使得子类可以不改变一个算法的结构即可重定义算法的某些特定步骤. 类图如下: 由此看出,是不是非常简单.类图中只有两个角色: 1.抽象类(AbstractClass):实现了模板方法,定义了算法的骨架.2.具体类(ConcreteClass):实现抽象类中的抽象方法,已完成完整的算法. 模版方法模式的结构 模版方

Android学习笔记(十五)——碎片的生命周期(附源码)

碎片的生命周期 点击下载源码 与活动类似,碎片具有自己的生命周期.理解了碎片的生命周期后,我们可以在碎片被销毁时正确地保存其实例,在碎片被重建时将其还原到前一个状态. 1.使用上一篇的项目Fragments,在Fragment1.java文件中添加如下代码: package net.zenail.Fragments; import android.app.Activity; import android.os.Bundle; import android.support.v4.app.Fragm

马哥学习笔记二十五——ISCSI协议,架构及其安装配置

ISCSI监听在tcp/3260端口 iSCSI Target:iscsi-target-utils 客户端认正方式: 1.基于IP 2.基于用户,CHAP tgtadm:命令行工具,模式化命令 --mode 常用模式:target,logicalunit,account target --op new.delete.show.update.bind.unbind logicalunit --op new.delete account --op new.delete.bind.unbind --

一个怂女婿的成长笔记【十五】

2014-08-16 大部分人不是没有选择生活方式的权利,而是没有勇气去做出改变罢了. 我们经常在抱怨现在的生活不是自己想要的,但是当我们自问什么生活才是自己想要的时候,我们又偏偏答不出来,或者觉得太虚幻.所以,我们经常抱怨上天,抱怨公司,抱怨体制的时候,有没有想过,不是我们改变不了现在的生活,而是我们没有勇气去改变,而找了一些借口罢了. 记得一年前,我看过一篇<降级论>的文章,作者之前也是一名程序员,后来选择了其他行业,过上了自己想要的生活.但是我这里的意思不是觉得程序员的职业不好,或者没前

15、蛤蟆的数据结构笔记之十五栈的应用之栈与递归之八皇后问题

15.蛤蟆的数据结构笔记之十五栈的应用之栈与递归之八皇后问题 本篇名言:"人的一生应当这样度过:当回忆往事的时候,他不致于因为虚度年华而痛悔,也不致于因为过去的碌碌无为而羞愧:在临死的时候,他能够说:"我的整个生命和全部精力,都已经献给世界上最壮丽的事业--为人类的解放而斗争." 继续递归问题,本次是经典的八皇后问题: 欢迎转载,转载请标明出处: 1.  八皇后问题 八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例.该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出

35. 蛤蟆的数据结构笔记之三十五遍历二叉树

35. 蛤蟆的数据结构笔记之三十五遍历二叉树 本篇名言:"冬天已经到来,春天还会远吗? --雪莱" 我们来看徐璈如何遍历二叉树. 欢迎转载,转载请标明出处: 1.  二叉树遍历 二叉树的遍历有三种方式,如下: (1)前序遍历(DLR),首先访问根结点,然后遍历左子树,最后遍历右子树.简记根-左-右. (2)中序遍历(LDR),首先遍历左子树,然后访问根结点,最后遍历右子树.简记左-根-右. (3)后序遍历(LRD),首先遍历左子树,然后遍历右子树,最后访问根结点.简记左-右-根. 2.

VSTO学习笔记(十五)Office 2013 初体验

原文:VSTO学习笔记(十五)Office 2013 初体验 Office 2013 近期发布了首个面向消费者的预览版本,我也于第一时间进行了更新试用.从此开始VSTO系列全面转向Office 2013平台,即VSTO 5.0. 本系列所有测试代码均在Visual Studio 2012 Ultimate RC + Office 2013 Professional Plus x64 Preview 上测试通过 为了配合Windows 8,微软的很多软件风格都逐渐Metro化,Office作为拳头