Friday, January 31, 2014

Behaviroal DP : Interpreter Design Pattern



This pattern involves implementing a expression interface which tells to interpret a particular context This pattern is used in SQL parsing, symbol processing engine etc.
THIS DESIGN PATTERN NOT USED MOSTLY J just used in compilers
 As per GOF Definition “Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language.” 


The best example you can get for this is Java itself which is an interpreted language. It converts the code written in English to a byte code format so as to make possible for all the operating systems to understand it.


Example 1 :  We're going to create an interface Expression and concrete classes implementing the Expression interface. A class TerminalExpression is defined which acts as a main interpreter of context in question.  



1:  //Create an expression interface.  
2:  public interface Expression {  
3:        public boolean interpret(String context);  
4:  }  

 

1:  //Create concrete classes implementing the above interface.  
2:  public class TerminalExpression implements Expression {  
3:       private String data;  
4:       public TerminalExpression(String data){  
5:          this.data = data;   
6:         }  
7:       @Override  
8:         public boolean interpret(String context) {  
9:            //contains so if some part is matched then it will return true   
10:          if(context.contains(data)){  
11:            return true;  
12:          }  
13:          return false;  
14:         }  
15:  }  
sdsds

1:  public class AndExpression implements Expression {  
2:       private Expression expr1 = null; private Expression expr2 = null;  
3:       public AndExpression(Expression expr1, Expression expr2) {  
4:            this.expr1 = expr1;  
5:            this.expr2 = expr2;  
6:       }  
7:       @Override  
8:       public boolean interpret(String context) {  
9:            return expr1.interpret(context) && expr2.interpret(context);  
10:       }  
11:  }  


1:  public class OrExpression implements Expression {  
2:        private Expression expr1 = null;  private Expression expr2 = null;  
3:         public OrExpression(Expression expr1, Expression expr2) {   
4:          this.expr1 = expr1;  
5:          this.expr2 = expr2;  
6:         }  
7:         @Override  
8:         public boolean interpret(String context) {            
9:          return expr1.interpret(context) || expr2.interpret(context);  
10:         }  
11:  }  

1:  //InterpreterPatternDemo uses Expression class to create rules and then parse them.  
2:  public class InterpreterPatternDemo {  
3:        //Rule: Robert and John are male  
4:         public static Expression getMaleExpression(){  
5:             //robert entity will get created and get stored in robert   
6:          Expression robert = new TerminalExpression("Robert");   
7:         //John entity will get created and get stored in john   
8:          Expression john = new TerminalExpression("John2");   
9:          return new OrExpression(robert, john);            
10:         }  
11:         //Rule: Julie is a married women  
12:         public static Expression getMarriedWomanExpression(){  
13:             //julie entity will get created and get stored in Julie   
14:          Expression julie = new TerminalExpression("Julie");  
15:         //married entity will get created and get stored in Married   
16:          Expression married = new TerminalExpression("Married");  
17:          return new AndExpression(julie, married);            
18:         }  
19:         public static void main(String[] args) {  
20:          Expression isMale = getMaleExpression();  
21:          Expression isMarriedWoman = getMarriedWomanExpression();  
22:          System.out.println("John is male? " + isMale.interpret("John2"));  
23:          //we are passing word Married Julie so it check for some part of word get matched  
24:          System.out.println("Julie is a married women? " + isMarriedWoman.interpret("Married Julie"));  
25:         }  
26:       }  




Output of the program as below

John is male? true
Julie is a married women? true


Conclusion

The Interpreter pattern has a limited area where it can be applied. We can discuss the Interpreter pattern only in terms of formal grammars but in this area there are better solutions and this is the reason why this pattern is not so frequently used. This pattern can be applied for parssing light expressions defined in simple grammars and sometimes in simple rule engines.

Applicability & Examples

The Template Method pattern should be used:
- The Interpreter pattern is used exhaustively in defining grammars, tokenize input and store it.
- A specific area where Interpreter can be used are the rules engines.
- The Interpreter pattern can be used to add functionality to the composite pattern.

 

 Watch Out for the Downsides

Efficiency is a big concern for any implementation of this pattern. Introducing your own grammar requires extensive error checking, which will be time consuming for the programmer to implement, and needs careful design in order to run efficiently at runtime. Also, as the grammar becomes more complicated, the maintenance effort is increased. 

No comments: