设计模式(11):解释器模式

1、定义

    给定一个语言,定义一个文法的一种表示, 并定义一个解释器, 这个解释器使用该表示来解释语言中的句子。

    如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子,这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题。

  就比如正则表达式,它就是解释器模型的一种应用,解释器为正则表达式定义了一个文法,如何表示一个特定的正则表达式,以及如何解释这个正则表达式。

2、使用场景

2.1、当有一个语言需要解释执行,并且你可将该语言中的句子表示为一个抽象语法树,可以使用解释器模式。而当存在以下情况时该模式效果最好

2.2、该文法的类层次结构变得庞大而无法管理。此时语法分析程序生成器这样的工具是最好的选择。他们无需构建抽象语法树即可解释表达式,这样可以节省空间而且还可能节省时间。

2.3、效率不是一个关键问题,最高效的解释器通常不是通过直接解释语法分析树实现的,而是首先将他们装换成另一种形式,例如,正则表达式通常被装换成状态机,即使在这种情况下,转换器仍可用解释器模式实现,该模式仍是有用的。

3、优缺点

3.1、优点:

3.1.1、 可以很容易地改变和扩展方法, 因为该模式使用类来表示方法规则, 你可以使用继承来改变或扩展该方法。

3.1.2、也比较容易实现方法, 因为定义抽象语法树总各个节点的类的实现大体类似, 这些类都易于直接编写。

3.1.3、解释器模式就是将一句话,转变为实际的命令程序执行而已。 而不用解释器模式本身也可以分析, 但通过继承抽象表达式的方式, 由于依赖转置原则, 使得文法的扩展和维护都带来的方便。

3.2、缺点:

    解释器模式为方法中的每一条规则至少定义了一个类, 因此包含许多规则的方法可能难以管理和维护。 因此当方法非常复杂时, 使用其他的技术如 语法分析程序 或 编译器生成器来处理。

4、应用实例

  • 编译器
  • 运算表达式计算、正则表达式
  • 机器人

5、实现

5.1、抽象表达式

/**
 * desc: 抽象表达式是生成语法集合(语法树)的关键,每个语法集合完成指定语法解析任务,
 *          它是通过递归调用的方式,最终由最小的语法单元进行解析完成。
 *
 * @author xuebin3765@163.com
 * @version 1.0
 * @date 2020/06/15 10:01
 */
public abstract class AbstractExpression {
	public abstract boolean interpret(String context);
}

 5.2、验证表达式

/**
 * desc: 条件验证,验证表达式
 *
 * @author xuebin3765@163.com
 * @version 1.0
 * @date 2020/06/15 10:02
 */
public class TerminalExpression extends AbstractExpression {

	/**
	 * 指定字符串
	 */
	private String data;

	public TerminalExpression(String data) {
		this.data = data;
	}

	/**
	 * 验证表达式是否包含指定字符串
	 * @param context 表达式
	 * @return true or false
	 */
	@Override
	public boolean interpret(String context) {
		if (context.contains(data)){
			return true;
		}else {
			return false;
		}
	}
}

5.3、and条件表达式

/**
 * desc: and条件表达式
 *
 * @author xuebin3765@163.com
 * @version 1.0
 * @date 2020/06/15 10:47
 */
public class AndExpression extends AbstractExpression {

	private AbstractExpression exp1;
	private AbstractExpression exp2;

	public AndExpression(AbstractExpression exp1, AbstractExpression exp2) {
		this.exp1 = exp1;
		this.exp2 = exp2;
	}

	@Override
	public boolean interpret(String context) {
		return exp1.interpret(context) && exp2.interpret(context);
	}
}

5.4、或条件表达式

/**
 * desc: 或条件表达式
 *
 * @author xuebin3765@163.com
 * @version 1.0
 * @date 2020/06/15 10:45
 */
public class OrExpression extends AbstractExpression {

	private AbstractExpression exp1;
	private AbstractExpression exp2;

	public OrExpression(AbstractExpression exp1, AbstractExpression exp2) {
		this.exp1 = exp1;
		this.exp2 = exp2;
	}

	@Override
	public boolean interpret(String context) {
		return exp1.interpret(context) || exp2.interpret(context);
	}
}

5.5、测试

/**
 * desc: 测试
 *
 * @author xuebin3765@163.com
 * @version 1.0
 * @date 2020/06/15 10:31
 */
public class ClientTest {

	// 小明和张三是男性
	public static AbstractExpression getMaleExpression(){
		AbstractExpression xm = new TerminalExpression("小明");
		AbstractExpression zs = new TerminalExpression("张三");
		return new OrExpression(xm, zs);
	}

	//规则:妲己 是一个已婚的女性
	public static AbstractExpression getMarredExpression(){
		AbstractExpression julie = new TerminalExpression("妲己");
		AbstractExpression married = new TerminalExpression("已婚");
		return new AndExpression(julie, married);
	}

	public static void main(String[] args) {
		AbstractExpression isMale = getMaleExpression();
		AbstractExpression isMarredWoman = getMarredExpression();

		System.out.println("小明是男性:" + isMale.interpret("小明"));
		System.out.println("李四是男性:" + isMale.interpret("李四"));
		System.out.println("妲己是已婚女性:"+ isMarredWoman.interpret("妲己已婚"));
		System.out.println("武则天是已婚女性:"+ isMarredWoman.interpret("武则天已婚"));
	}
}

5.6、运行结果

小明是男性:true
李四是男性:false
妲己是已婚女性:true
武则天是已婚女性:false

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值