我试图理解Java中的Interpreter Design Pattern。我从Wikipedia获取以下代码。有书面
interface Expression {
public int interpret(Map<String,Expression> variables);
}
你能解释一下这里发生了什么关于Expression是Map的值,它位于Type of Expression的接口里面。这是递归调用吗?请解释一下。
答案 0 :(得分:2)
要回答您的问题,是同一个函数interpret()
会一次又一次地调用,但它们不属于同一类。因此它实际上不是递归函数。
使用维基代码解释解释器模式,但您需要来回浏览维基页面以了解整个图片,
http://en.wikipedia.org/wiki/Interpreter_pattern
解释器模式是将给定表达式中的每个变量和运算符表示为单独的类,然后在这些类的对象上进行评估的模式。
表达式 - class, expression - ((y+z)-x)
对于你指出的wiki示例,当你在main()
中调用Evaluator的构造函数时,只会构造表达式(再次是它的另一个Expression对象)并保存在{{1}中} Evaluator的引用变量。
通过表达式syntaxTree
x y z + -
将存储在x,y,z
变量expressionStack
时,+
会被推入(y+z)
expressionStack
令牌之后,-
表达式对象将位于((y+z)-x)
中(检查expressionStack
中运算符正在发生的推送和弹出)因此,一旦完成Evaluator的构造函数,您将拥有Expression对象,其实现又是表达为Evaluator
的表达式。
现在是((y+z)-x)
中有趣的部分,您使用main()
类替换变量(x,y,z)
的值,它按此顺序发生,
Number
main () sentence.interpret(variables);
Evaluator.syntaxTree.interpret(variables);
然后评估Variable.interpret(variables) // Here the actual values(5,10,42) gets substituted for x, y, z.
。
如果您看到Expression
类interpret()
,则使用传递的上下文获取相应的Variables
对象的位置略有不同。这是使用Number
中传递的上下文对象将变量实际替换为数字。这反过来调用main()
interpret()
只返回数字,操作发生在Number
。
通过使用此技术,您可以继续添加操作(加号,减号)而不会影响现有操作,并且一个操作独立于其他操作。它用于SQL查询和其他解释器。
谢谢, Prasanna V。
答案 1 :(得分:1)
接口定义了类具有接口时必须实现的方法。
class MathExpression implements Expression {
public int interpret(Map<String,Expression> variables) {
//insert code here
}
}
我不会将其描述为递归调用。准确的描述是接口在方法调用中自我引用。
Expression expression = new MathExpression();
expression.interpret(stringToExpressionMap);
这样做的好处是您可以在该类中定义行为,而无需知道该类的具体实现。