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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
public class Context { private String input; private int output; public Context(String input) { this.input = input; } public String getInput() { return input; } public void setInput(String input) { this.input = input; } public int getOutput() { return output; } public void setOutput(int output) { this.output = output; } } |
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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
public abstract class Expression { public void interpret(Context context) { if (context.getInput().length() == 0) return; if (context.getInput().startsWith(nine())) { context.setOutput(context.getOutput() + (9 * multiplier())); context.setInput(context.getInput().substring(2)); } else if (context.getInput().startsWith(four())) { context.setOutput(context.getOutput() + (4 * multiplier())); context.setInput(context.getInput().substring(2)); } else if (context.getInput().startsWith(five())) { context.setOutput(context.getOutput() + (5 * multiplier())); context.setInput(context.getInput().substring(1)); } while (context.getInput().startsWith(one())) { context.setOutput(context.getOutput() + (1 * multiplier())); context.setInput(context.getInput().substring(1)); } } public abstract String one(); public abstract String four(); public abstract String five(); public abstract String nine(); public abstract int multiplier(); } public class ThousandExpression extends Expression{ public String one() { return "M"; } public String four(){ return " "; } public String five(){ return " "; } public String nine(){ return " "; } public int multiplier() { return 1000; } } public class HundredExpression extends Expression{ public String one() { return "C"; } public String four(){ return "CD"; } public String five(){ return "D"; } public String nine(){ return "CM"; } public int multiplier() { return 100; } } public class TenExpression extends Expression{ public String one() { return "X"; } public String four(){ return "XL"; } public String five(){ return "L"; } public String nine(){ return "XC"; } public int multiplier() { return 10; } } public class OneExpression extends Expression{ public String one() { return "I"; } public String four(){ return "IV"; } public String five(){ return "V"; } public String nine(){ return "IX"; } public int multiplier() { return 1; } } |
Main: wykonawca interpretacji:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
public class MainInterpreter { /** * @param args */ public static void main(String[] args) { String roman = "MCMXXVIII"; Context context = new Context(roman); // Build the 'parse tree' ArrayList<Expression> tree = new ArrayList<Expression>(); tree.add(new ThousandExpression()); tree.add(new HundredExpression()); tree.add(new TenExpression()); tree.add(new OneExpression()); // Interpret for (Iterator it = tree.iterator(); it.hasNext();) { Expression exp = (Expression)it.next(); exp.interpret(context); } System.out.println(roman + " = " + Integer.toString(context.getOutput())); } } |
Diagram wzorca: