Monday, May 3, 2010

Interpreter Pattern

The Interpreter Pattern is a design pattern that defines a grammatical representation for a language along with an interpreter to interpret sentences in the language. The best example of an interpreted language is Java itself, which converts the English-written code to a byte code format, so that all the operating systems can understand it.
The UML class diagram of Interpreter design pattern can be shown as:

UML Class Diagram


In the given diagram, An abstract base class specifies the method interpret(). Each concrete subclass implements interpret() by accepting (as an argument) the current state of the language stream, and adding its contribution to the problem solving process. To make this thing clear, let’s take an example that can take the Sa, Re, Ga, Ma etc and produce the sounds for the frequencies. The “musical notes” is an Interpreted Language. The musicians read the notes, interpret them according to “Sa, Re, Ga, Ma…” or “Do, Re, Me… “, etc. For Sa, the frequency is 256 Hz, similarly, for Re, it is 288Hz and for Ga, it is 320 Hz and so on. In this case, we need these values set somewhere, so that when the system encounters any one of these messages, the related frequency can be sent to the instrument for playing the frequency. We can have it at one of the two places, one is a constants file, “token=value” and the other one being in a properties file. The properties file can give us more flexibility to change it later if required. This is how a properties file will look like: MusicalNotes.properties Sa=256
Re=288
Ga=320
Ma=352 . . . . .
After that we make a class NotesInterpreter.java to take an input from the key pressed by user and set those value as a global value. Then we make a method getFrequency for getting the frequency for the note input by the user e.g. if user enter Re, it will return 288.
NotesInterpreter.java

package bahavioral.interpreter; public class NotesInterpreter {

Private Note note;

public void getNoteFromKeys(Note note) {
Frequency freq = getFrequency(note);
sendNote(freq);
}
private Frequency getFrequency(Note note) {
return freq;
}
private void sendNote(Frequency freq) {
NotesProducer producer = new NotesProducer(); producer.playSound(freq);
}
}
Here we need to make another class in which the method produces the sound wave of the frequency it gets.

NotesProducer.java
package bahavioral.interpreter;
public class NotesProducer {
Private Frequency freq;
public NotesProducer() {
this.freq = freq;
}
public void playSound(Frequency freq) {
}
}
 The above example is the simplest way to understand the concept of interpreter pattern and know how it works. In case of Interpreter pattern we need to check for grammatical mistakes, which makes it very complex. Also,
care should be taken to make the interpreter as flexible as possible, so that the implementation can be changed at later stages without having tight coupling.

No comments:

Post a Comment