解释器模式:
定义一个语言的文法,而且创建一个解释器来解释该语言中的句子,这里的“语言”是指使用规定格式和语法的代码。
解释器模式是一种类行为型模式。 因为表达式可分为终结符表达式和非终结符表达式,
所以解释器模式的结构与组合模式的结构有些相似,但在解释器模式中包含更多的组成元素。java
结构图:
express
示例类图:
markdown
示例代码:ide
// Expression
public interface Expression {
public void interpret(Context context);
}
// AbstractExpression
public abstract class AbstractExpression implements Expression {
protected static List<String> table;
public AbstractExpression() {
if (null == table) {
initTable();
}
}
public void initTable() {
table = new ArrayList<String>();
table.add("一");
table.add("二");
table.add("三");
table.add("四");
table.add("五");
table.add("六");
table.add("七");
table.add("八");
table.add("九");
}
public void interpret(Context context) {
String statement = context.getStatement();
System.out.println(statement);
if (null == statement || statement.isEmpty())
return;
for (int i = 0; i < table.size(); i++) {
String tail = table.get(i) + this.getPostfix();
// 从低位往高位分析,即从右往左
if (statement.endsWith(tail)) {
int newData = context.getData() + (i + 1) * this.multiplier();
context.setData(newData);
context.setStatement(statement.substring(0, statement.length() - tail.length()));
}
if (statement.endsWith("零")) {
context.setStatement(statement.substring(0, statement.length() - "零".length()));
}
}
}
// 表达式的后缀是以什么表示的 十,百,千...
public abstract String getPostfix();
// 表达式的数量级
public abstract int multiplier();
}
// TerminalExpression 个位数解释器
public class ExpressionGe extends AbstractExpression {
@Override
public String getPostfix() {
return "";
}
@Override
public int multiplier() {
return 1;
}
}
// TerminalExpression 十位数解释器
public class ExpressionShi extends AbstractExpression {
@Override
public String getPostfix() {
return "十";
}
@Override
public int multiplier() {
return 10;
}
}
// TerminalExpression 百位数解释器
public class ExpressionBai extends AbstractExpression {
@Override
public String getPostfix() {
return "百";
}
@Override
public int multiplier() {
return 100;
}
}
// TerminalExpression 千位数解释器
public class ExpressionQian extends AbstractExpression {
@Override
public String getPostfix() {
return "千";
}
@Override
public int multiplier() {
return 1000;
}
}
// NonterminalExpression 万位数解释器
public class ExpressionWan extends AbstractExpression {
private static List<Expression> expressions = new ArrayList<Expression>();
public ExpressionWan() {
if (expressions.isEmpty()) {
expressions.add(new ExpressionGe());
expressions.add(new ExpressionShi());
expressions.add(new ExpressionBai());
expressions.add(new ExpressionQian());
}
}
@Override
public void interpret(Context context) {
String statement = context.getStatement();
if (null == statement || statement.isEmpty())
return;
if (statement.endsWith(this.getPostfix())) {
context.setStatement(statement.substring(0, statement.length() - getPostfix().length()));
int data = context.getData();
context.setData(0);// 置零
for (Expression expression : expressions) {
expression.interpret(context);
}
context.setData(data + this.multiplier() * context.getData());
}
}
@Override
public String getPostfix() {
return "万";
}
@Override
public int multiplier() {
return 10000;
}
}
// 将中文数字串由低位向高位方向不断转化
public class Convertor {
private static List<Expression> expressions = new ArrayList<Expression>();
public Convertor() {
if (expressions.isEmpty()) {
expressions.add(new ExpressionGe());
expressions.add(new ExpressionShi());
expressions.add(new ExpressionBai());
expressions.add(new ExpressionQian());
expressions.add(new ExpressionWan());
}
}
public int convert(String chineseNum) {
Context context = new Context(chineseNum);
for (Expression expression : expressions) {
expression.interpret(context);
}
return context.getData();
}
}
// 测试
public class ExpressionTest {
public static void main(String[] args) {
String chineseNum = "六百三十七万八千二百零一";// 6378201
Convertor convertor = new Convertor();
System.out.println(chineseNum);
System.out.println(convertor.convert(chineseNum));
System.out.println(convertor.convert("五百万"));
}
}
Context:上下文,一般包含各个解释器须要的数据或是公共的功能。
这个Context在解释器模式中起着很是重要的做用。
通常用来传递被全部解释器共享的数据,后面的解释器能够从这里获取这些值。测试
AbstractExpression: 定义解释器的接口/抽象类,约定解释器的解释操做。
其中的Interpret接口,正如其名字那样,它是专门用来解释该解释器所要实现的功能。
(如加法解释器中的Interpret接口就是完成两个操做数的相加功能)。this
TerminalExpression: 终结符解释器,用来实现语法规则中和终结符相关的操做,
再也不包含其余的解释器,若是用组合模式来构建抽象语法树的话,
就至关于组合模式中的叶子对象,能够有多种终结符解释器。spa
NonterminalExpression: 非终结符解释器,用来实现语法规则中非终结符相关的操做,
一般一个解释器对应一个语法规则,能够包含其余解释器,若是用组合模式构建抽象语法树的话,
就至关于组合模式中的组合对象。能够有多种非终结符解释器。调试
执行效率较低。因为在解释器模式中使用了大量的循环和递归调用,
所以在解释较为复杂的句子时其速度很慢,并且代码的调试过程也比较麻烦。code
对于复杂文法难以维护。在解释器模式中,每一条规则至少须要定义一个类,
所以若是一个语言包含太多文法规则,类的个数将会急剧增长,致使系统难以管理和维护,
此时能够考虑使用语法分析程序等方式来取代解释器模式。对象