Wzorce projektowe: Interpreter
Interpreter jest wzorcem projektowym, którego zadaniem jest interpretacja poleceń innego języka. Dany język rokładany jest na części gramatyczne i potem na zorientowaną obiektowo hierarchię. Interpreter nie jest właściwie niczym innym jak wzorcem Kompozyt, tylko że ma trochę inną rolę – reprezentuje reguły gramatyczne. W niektórych przypadkach wzorzec Interpreter może zwiększyć funkcjonalność wzorca Kompozyt. Częstym przypadkiem używania wzorca jest interpretacja zasad.
Interpreter składa się :
Context: który przetrzymuje dane, które powinny poddać się interpretacji,
Abstract Expression: klasa abstrakcyjna która interpretuje polecenia,
…. Expression – konkretne klasy, które interpretują treść Contextu dla poszczególnych przypadków.
Abstract Expression i konkretne implementacje tworza wzorzec Template Method.
Main (albo inaczej Client)
Program do interpretacji liczby rzymskiej (znaleziony gdzieś na notatkach, ale nie mojego autorstwa):
Context: przechowuje treść tekstu do interpretacji:
1 public class Context { 2 3 private String input; 4 private int output; 5 6 public Context(String input) { 7 this.input = input; 8 } 9 10 public String getInput() { 11 return input; 12 } 13 14 public void setInput(String input) { 15 this.input = input; 16 } 17 18 public int getOutput() { 19 return output; 20 } 21 22 public void setOutput(int output) { 23 this.output = output; 24 } 25 26 } 27
Expression: interpretuje fragment cyfry rzymksiej jako decymalny odpowiednik, expression jest implemntowany przez cztery podklasy: Thousand…, Hundred…, Ten…, i OneExpression które interpretują poszczególne części cyfry.
1 public abstract class Expression { 2 3 public void interpret(Context context) { 4 if (context.getInput().length() == 0) 5 return; 6 7 if (context.getInput().startsWith(nine())) { 8 context.setOutput(context.getOutput() + (9 * multiplier())); 9 context.setInput(context.getInput().substring(2)); 10 } else if (context.getInput().startsWith(four())) { 11 context.setOutput(context.getOutput() + (4 * multiplier())); 12 context.setInput(context.getInput().substring(2)); 13 } else if (context.getInput().startsWith(five())) { 14 context.setOutput(context.getOutput() + (5 * multiplier())); 15 context.setInput(context.getInput().substring(1)); 16 } 17 18 while (context.getInput().startsWith(one())) { 19 context.setOutput(context.getOutput() + (1 * multiplier())); 20 context.setInput(context.getInput().substring(1)); 21 } 22 } 23 24 public abstract String one(); 25 26 public abstract String four(); 27 28 public abstract String five(); 29 30 public abstract String nine(); 31 32 public abstract int multiplier(); 33 34 }
1 public class ThousandExpression extends Expression{ 2 3 public String one() { return "M"; } 4 public String four(){ return " "; } 5 public String five(){ return " "; } 6 public String nine(){ return " "; } 7 public int multiplier() { return 1000; } 8 }
1 public class HundredExpression extends Expression{ 2 public String one() { return "C"; } 3 public String four(){ return "CD"; } 4 public String five(){ return "D"; } 5 public String nine(){ return "CM"; } 6 public int multiplier() { return 100; } 7 }
1 public class TenExpression extends Expression{ 2 public String one() { return "X"; } 3 public String four(){ return "XL"; } 4 public String five(){ return "L"; } 5 public String nine(){ return "XC"; } 6 public int multiplier() { return 10; } 7 }
1 public class OneExpression extends Expression{ 2 public String one() { return "I"; } 3 public String four(){ return "IV"; } 4 public String five(){ return "V"; } 5 public String nine(){ return "IX"; } 6 public int multiplier() { return 1; } 7 }
Main: wykonawca interpretacji:
1 public class MainInterpreter { 2 3 /** 4 * @param args 5 */ 6 public static void main(String[] args) { 7 8 String roman = "MCMXXVIII"; 9 Context context = new Context(roman); 10 11 // Build the 'parse tree' 12 ArrayList<Expression> tree = new ArrayList<Expression>(); 13 tree.add(new ThousandExpression()); 14 tree.add(new HundredExpression()); 15 tree.add(new TenExpression()); 16 tree.add(new OneExpression()); 17 18 // Interpret 19 for (Iterator it = tree.iterator(); it.hasNext();) 20 { 21 Expression exp = (Expression)it.next(); 22 exp.interpret(context); 23 } 24 25 System.out.println(roman + " = " + Integer.toString(context.getOutput())); 26 } 27 } 28
Diagram wzorca:

