Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Applied Java™ Patterns - Stephen Stelting, Olav Maassen.pdf
Скачиваний:
202
Добавлен:
24.05.2014
Размер:
2.84 Mб
Скачать

Suppose the values are 4, 2 and 3 respectively— result is 2. Now, how do you know that? First, you mentally associated a with 4, b with 2, and c with 3. Next you added a and b, resulting in the value 6, which you then divided by c (3).

Solving the problem using Interpreter pattern involves a very similar set of steps. Each of the variables (a, b, and c) is an operand, as is each intermediate value (the value that is the result of some calculation).

The grammar rules (like + for adding and / for dividing) are operations or operators. Each grammar rule is implemented as a separate class, and each value to the right of that rule (the values are also called operands) becomes an instance variable.

Implementation

Figure 2.6 shows the Interpreter pattern class diagram.

Figure 2.6. Interpreter class diagram

The Interpreter pattern needs:

Expression – The interface through which the client interacts with the expressions.

TerminalExpression – Implementation of the Expression interface intended for terminal nodes in the grammar and the syntax tree.

NonterminalExpression – The other implementation of the Expression interface, intended for the nonterminal nodes in the grammar and syntax tree. It keeps a reference to the next Expression (s) and invokes the interpret method on each of its children.

Context – Container for the information that is needed in several places in the interpreter. It can serve as a communication channel among several Expression instances.

Client – Either builds or receives an instance of an abstract syntax tree. This syntax tree is composed of instances of TerminalExpressions and NonterminalExpressions to model a specific sentence. The client invokes the interpret method with the appropriate context where necessary.

Benefits and Drawbacks

Benefits and drawbacks include the following:

The interpreter can be very easily changed to reflect changes in the grammar. To add a rule, create another class that implements the Expression interface. This class implements the new rule in the interpret method.

You can easily change a rule by extending the old class and overriding the interpret method.

The Interpreter pattern is inappropriate when the grammar is large. (Does this means that the Interpreter will start yelling loudly and breaking things and eventually have to be escorted out of your program? It’s even worse.) The Interpreter can result in a large number of classes being produced if there are many rules in your language. Every rule you add to your language requires one or more classes in the interpreter. As the grammar gets larger, the number of classes used increases. This can eventually result in testing and maintenance problems.

47