解释器模式
模式说明
结构
代码演示
package com.yukiyama.pattern.behavior;
import java.util.HashSet;
import java.util.Set;
/**
* 解释器模式
*/
public class InterpreterDemo {
public static void main(String[] args) {
// 声明一个上下文实例
Context context = new Context();
// 合法表达式,输出“true”
System.out.println(context.interpret("a"));
// 合法表达式,输出“true”
System.out.println(context.interpret("A+b"));
// 合法表达式,输出“true”
System.out.println(context.interpret("A+b-a+a-B"));
// 非法表达式,输出“false”
System.out.println(context.interpret("C+a"));
// 非法表达式,输出“false”
System.out.println(context.interpret("b+a*B"));
// 非法表达式,输出“false”
System.out.println(context.interpret("3"));
}
}
/**
* 抽象表达式类
* 定义一个抽象解释方法interpret(String expression)。
*/
abstract class AbstractExpression{
public abstract boolean interpret(String expression);
}
/**
* 终结符表达式类
* 继承抽象表达式类。持有一个Set<String>泛型的终结符集合。并通过有参构造器
* 初始化。实现抽象表达式类的抽象解释方法interpret。解释过程很简单,判断该
* 传入的expression是否包含在其持有的终结符集合里,包含则true,否则false。
*/
class TerminalExpression extends AbstractExpression{
private Set<String> terminals = new HashSet<>();
public TerminalExpression(String[] terminals) {
for (int i = 0; i < terminals.length; i++) {
this.terminals.add(terminals[i]);
}
}
public Set<String> getTerminals() {
return terminals;
}
public void setTerminals(Set<String> terminals) {
this.terminals = terminals;
}
@Override
public boolean interpret(String expression) {
return terminals.contains(expression);
}
}
/**
* 非终结表达式类
* 继承抽象表达式。持有所有终结符(以AbstractExpress类型),并通过有参构造器
* 传入终结符集合来初始化。本示例定义两种终结符,小写字母"a"和"b"是一种,大写
* 字母"A"和"B是另一种。所以本例的非终结符表达式持有两个终结符表达式lowerExp
* 和upperExp,通过构造器传入lowerExp和upperExp来初始化。
* 实现抽象表达式类中的抽象解释方法interpret。借助已知的合法的运算符号("+","-")
* 通过字符串的split方法将原始表达式分割成一个终结符和一个非终结符,对终结符调用
* 终结符表达式类的interpret判断,一旦非法立即返回false。对非终结符,递归调用
* 非终结符表达式的interpret。
*/
class NonterminalExpression extends AbstractExpression{
private AbstractExpression lowerExp;
private AbstractExpression upperExp;
public NonterminalExpression(AbstractExpression lowerExp, AbstractExpression upperExp) {
this.lowerExp = lowerExp;
this.upperExp = upperExp;
}
@Override
public boolean interpret(String exp) {
boolean isLegal;
// exp多于1个字符时
if(exp.length() > 1) {
// 将表达式分割为两部分,elements[0]为第一个合法运算符号左边的1个字符
// elements[1]为第一个合法运算符号右边的部分
String[] elements = exp.split("\\+|\\-", 2);
// 判断(解释)elements[0]是否合法
isLegal = lowerExp.interpret(elements[0]) || upperExp.interpret(elements[0]);
// lements[0]不合法直接返回false
if(!isLegal){
return isLegal;
}
// 递归调用当前非终结表达式实例的interpret方法判断右边部分
return this.interpret(elements[1]);
} else {
// 若表达式exp等于或少于一个字符时,调用终结符的interpret返回解释结果
return lowerExp.interpret(exp) || upperExp.interpret(exp);
}
}
}
/**
* 环境类(上下文类)
* 持有所有种类的终结符集合(以String数组类型),持有一个非终结符实例
* (以AbstractExpression类型)。无参构造器中初始化非终结符实例,方法如下:
* 先通过两个String数组实例化两种终结符,再向非终结符构造参数中传入这两个
* 终结符实例。
* 维护一个interpret方法,调用非终结符的interpret方法返回解释结果。
*/
class Context{
private String[] lowers = {"a", "b"};
private String[] uppers = {"A", "B"};
private AbstractExpression exp;
public Context() {
AbstractExpression lowerExp = new TerminalExpression(lowers);
AbstractExpression upperExp = new TerminalExpression(uppers);
exp = new NonterminalExpression(lowerExp, upperExp);
}
public boolean interpret(String expression) {
return this.exp.interpret(expression);
}
}Last updated