001package composite.three; 002 003public class ExprFactory2 { 004 private ExprFactory2() {} 005 static public Expr newConst(int v) { 006 return new Const(v); 007 } 008 static public Expr newPlus(Expr l, Expr r) { 009 return new PlusOp(l, r); 010 } 011// static public Expr newMinus(Expr l, Expr r) { 012// return new BinOp(l, new OpSub(), r); 013// } 014// static public Expr newMult(Expr l, Expr r) { 015// return new BinOp(l, new OpMul(), r); 016// } 017// static public Expr newQuot(Expr l, Expr r) { 018// return new BinOp(l, new OpDiv(), r); 019// } 020 021 private static final class Const implements Expr { 022 private final int v; 023 public Const(int v) { 024 this.v = v; 025 } 026 public int eval() { 027 return v; 028 } 029 public String toString() { 030 return Integer.toString(v); 031 } 032 } 033 034 private static abstract class BinOp implements Expr { 035 private final Expr l; 036 private final Expr r; 037 private final String opString; 038 public BinOp(Expr l, String opString, Expr r) { 039 if ((l == null) || (r == null)) { 040 throw new IllegalArgumentException(); 041 } 042 this.l = l; 043 this.r = r; 044 this.opString = opString; 045 } 046 protected abstract int run (int x, int y); 047 // to be template method, there must a template method 048 // template method = method of abstract class, that calls an abstract method 049 public int eval() { 050 return this.run(l.eval(), r.eval()); 051 } 052 public String toString() { 053 return l.toString() + " " + r.toString() + " " + opString; 054 } 055 } 056 private static final class PlusOp extends BinOp { 057 public PlusOp(Expr l, Expr r) { super (l, "+", r); } 058 public int run(int x, int y) { return x+y; } 059 } 060} 061