设计模式-解释器模式

一、解释器模式的核心思想

解释器是一种特殊的设计模式,它建立一个解释器,对于特定的计算机程序设计语言而言,用来解释预先定义的文法。简单地说,解释器模式是一种简单的语法解释器构架。

解释器模式包括如下3类对象。

  • 上下文环境类 Context:用来存储解释器的上下文环境,比如需要解释的文法等。
  • 解释器接口Expression:定义了语法解释器的接口。
  • 解释器具体实现类:对各种语法进行解释的具体实现,如加法Plus、减法Minus、乘法Multiply、除法 Devide。

其结构图如图所示
在这里插入图片描述
图中我们设计了4个解释器的实现,用来计算 Context 中两个数字的加、减、乘、除。下面来看具体的实现。

(1) 文法上下文 Context.java用来保存文法的上下文参数,我们这里需要保存两个计算的数值。

package behavior.interpreter;

public class Context {

	private int num1;
	private int num2;

	public Context(int num1, int num2) {
		this.num1 = num1;
		this.num2 = num2;
	}
	
	public int getNum1() {
		return num1;
	}
	
	publie void setNum1(int num1) {
		this.num1 = num1;
	}
	
	public int getNum2() {
		return num2;
	}
	
	publie void setNum2(int num2) {
		this.num2 = num2;
	}
}

(2) 解释器接口 Expression.java 定义了一个根据 Context 上下文进行解释的接口,返回值为整型。

package behavior.interpreter;

public interface Expression {

	public int interpret(Context context);
}

(3) 加法解释器 Plus.java实现了Expression接口,用来计算 Context 上下文中两个数值的和。

package behavior.interpreter;

public class Plus implements Expression {

	public int interpret(Context context){
		return context.getNum1() + context.getNum2();
	}

}

(4) 减法解释器 Minus.java实现了 Expression接口,用来计算 Context上下文中两个数值的差。

package behavior.interpreter;

public class Minus implements Expression {

	public int interpret(Context context){
		return context.getNum1() - context.getNum2();
	}

}

(5) 乘法解释器 Multiply.java 实现了 Expression 接口,用来计算 Context 上下文中两个数值的积。

package behavior.interpreter;

public class Multiply implements Expression {

	public int interpret(Context context){
		return context.getNum1() * context.getNum2();
	}

}

(6) 除法解释器 Devide.java实现了Expression接口,用来计算 Context上下文中两个数值的商。

package behavior.interpreter;

public class Devide implements Expression {

	public int interpret(Context context){
		return context.getNum1() / context.getNum2();
	}

}

接下来我们就可以使用以上的解释器类来计算下面的表达式:

(10+5-3)*2/6 = 4

该表达式要求先计算加、减,再计算乘、除,因此需要按照如下4步进行:

  • 先构造10和5的上下文对象,使用Plus.java进行解释得到和。
  • 构造上面的和与3的上下文对象,使用Minus.java进行解释得到差。
  • 构造上面的差与2的上下文对象,使用Multiply.java进行解释得到积。
  • 构造上面的积与3的上下文对象,使用Devide.java进行解释得到商。

其源代码如下程序所示。

package behavior.interpreter;

public class Test {

	public static void main(String[] args) {
		// 计算:(10+5-3)*2/6=4
		int result =
		new Devide().interpret(new Context(
			new Multiply().interpret(new Context(
				new Minus().interpret(new Context(
					new Plus().interpret(new Context( 10, 5))
				3)),
			2)),
		6));
		System.out.printIn("(10+ 5 - 3)* 2 / 6 = " + result);
	}

}

运行该程序的结果如下:

(10+5-3)*2/6 = 4

以上程序只是演示了解释器模式进行文法解释的思路,在实际的开发中,则可以灵活运用,丰富它们的功能。

二、何时使用解释器模式

解释器模式描述了如何构成一个简单的语言解释器,主要应用在使用面向对象语言开发编译器中。在实际应用中,我们可能很少碰到去构造一个语言的文法的情况。因此,解释器模式的适用面比较窄。

三、Java中的应用–Java 正则表达式解释器 Pattern

在编写处理字符串的程序时,经常会有查找符合某些复杂规则的字符串的需要。正则表达式就是用于描述这些规则的工具,也是用来进行文本匹配的工具。比如,你可以编写一个正则表达式,用来查找所有以0开头,后面跟着2~3个数字,然后是一个连字号“-”,最后是7或8位数字的电话号码,比如010-12345678或020-7654321。

JDK 的正则表达式库 java.util.reg 提供了两个类 Pattemn 和 Matcher,用来进行正则表达式的匹配和查找功能。

Pattemn 为字符串的正则表达式,可以直接根据一个正则表达式创建一个 Pattern 实例:

Pattern p = Pattern.compile("a*b"); //正则表达式

然后使用 Pattern 对象获得 Matcher 匹配器对象,创建匹配器后,可以使用它执行3种不同的匹配操作:

  • matches()方法尝试将整个输入序列与该模式匹配。
  • lookingAt()尝试将输入序列从头开始与该模式匹配。
  • find()方法扫描输入序列以查找与该模式匹配的下一个子序列。

每个方法都返回一个表示成功或失败的布尔值。因此,典型的调用顺序是:

Pattern p = Pattern.compile("a*b");  //正则表达式
Matcher m = p.matcher("aaaaab");     //匹配对象
boolean b = m.matches();             //匹配

在仅使用一次正则表达式时,可以方便地通过此类定义matches()方法。此方法编译表达式并在单个调用中将输入序列与其匹配。例如:

boolean b = Pattern.matches("a*b", "aaaaab");

它等效于上面的3个语句,尽管对于重复的匹配而言它效率不高,因为它不允许重用已编译的模式。

相关推荐

  1. 设计模式——解释模式

    2024-07-11 08:38:05       37 阅读
  2. 设计模式解释模式

    2024-07-11 08:38:05       20 阅读
  3. 设计模式解释模式

    2024-07-11 08:38:05       15 阅读
  4. 设计模式-解释模式

    2024-07-11 08:38:05       13 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-11 08:38:05       7 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-11 08:38:05       7 阅读
  3. 在Django里面运行非项目文件

    2024-07-11 08:38:05       6 阅读
  4. Python语言-面向对象

    2024-07-11 08:38:05       9 阅读

热门阅读

  1. mybatis动态SQL常用语法总结

    2024-07-11 08:38:05       10 阅读
  2. Stable Diffusion / huggingface 相关配置问题汇总

    2024-07-11 08:38:05       11 阅读
  3. PyCharm\VsCode——Python第三方库下载换源

    2024-07-11 08:38:05       10 阅读
  4. c++三国小游戏(喜欢请一键三连)

    2024-07-11 08:38:05       9 阅读
  5. Go语言特点

    2024-07-11 08:38:05       10 阅读
  6. 深度学习探秘:Transformer模型跨框架实现大比拼

    2024-07-11 08:38:05       11 阅读
  7. Postman API网络:连接API开发的桥梁

    2024-07-11 08:38:05       10 阅读
  8. 探索AI数字人的开源解决方案

    2024-07-11 08:38:05       8 阅读
  9. GraphQL在Postman中:释放API查询的强大潜能

    2024-07-11 08:38:05       10 阅读
  10. iCloud数据宝库:全方位掌握笔记应用数据存储

    2024-07-11 08:38:05       9 阅读
  11. 开源项目有哪些机遇与挑战?

    2024-07-11 08:38:05       10 阅读
  12. Autogen和LangGraph对比

    2024-07-11 08:38:05       8 阅读