// A simple Demeter/Java program for computing averages Container { traversal allWeights( // ordering of visitors is important // initial must be initalized before it is used // after methods are called in reverse order of appearance CheckingVisitor cV, SummingVisitor sV, InitialVisitor iV ) { to Weight;} (@ // traverse while counting and summing int checkCapacity() throws Exception { // adaptive specification of objects using parsing SummingVisitor sV = SummingVisitor.parse("0"); InitialVisitor iV = new InitialVisitor(null, new MyStack(), sV); CheckingVisitor cV = new CheckingVisitor(iV,new Integer(0)); this.allWeights(cV, sV, iV ); return (cV.get_violations().intValue()); } @) } SummingVisitor { before Weight (@ System.out.println("sum " + total.intValue()); total = new Integer(total.intValue() + host.get_i().intValue()); @) } CheckingVisitor { before Container (@ System.out.println(" start new container "); @) after Container (@ Integer initial = iV.get_initial(); int cap = host.get_capacity().get_i().intValue(); // violation of Law of Demeter // should use traversal int diff = iV.get_sV().get_total().intValue() - initial.intValue(); if (diff > cap) { this.set_violations(new Integer(get_violations().intValue() + 1)); System.out.println(" total weight " + diff + " but limit is = " + cap + " OVER CAPACITY "); }; System.out.println(" end container "); @) } InitialVisitor { // stack handling before Container (@ stack.push(sV.get_total()); @) after Container (@ initial = (Integer) stack.pop(); @) } Main { (@ static public void main(String args[]) throws Exception { Runtime rt = Runtime.getRuntime(); rt.traceMethodCalls(true); Container a = Container.parse(System.in); int result = a.checkCapacity(); if(result == 2) { System.out.println("SUCCESS"); } else { System.out.println("FAILURE"); } System.out.println("done "); } @) }