TEMPLATE - ANALYSIS: -------------------- return-type method-name(Traversal tr){ +--------------------+ // invoke the methodAcc: | acc <-- BASE-VALUE | +--------------------+ method-name-acc(Traversal tr, BASE-VALUE); } return-type method-name-acc(Traversal tr, return-type acc) ... tr.isEmpty() ... -- boolean ::PREDICATE if true: ... acc -- return-type ::BASE-VALUE if false: +---------------+ ...| tr.getFirst() | ... -- E ::CURRENT +---------------+ ... update(T, return-type) -- return-type ::UPDATE +----------------------------+ i.e.: ...| update(tr.getFirst(), acc) | ... +----------------------------+ +--------------+ ... | tr.getRest() | -- Traversal<T> ::ADVANCE +--------------+ ... method-name(tr.getRest(), return-type) -- return-type i.e.: ... method-name-acc(tr.getRest(), update(tr.getFirst(), acc))
Based on this analysis, we can now design a template for the entire problem — with the solution divided into three methods as follows:
COMPLETE METHOD TEMPLATE: ------------------------- <T> return-type method-name(Traversal<T> tr){ +------------+ method-name-acc(Traversal tr,| BASE-VALUE |); +------------+ } <T> return-type method-name(Traversal<T> tr, return-type acc){ +--------------+ if (| tr.isEmpty() |) +--------------+ return acc; else +--------------+ return method-name-acc(| tr.getRest() |, +--------------+ +----------------------------+ | update(tr.getFirst(), acc) |); +----------------------------+ } <T> return-type update(T t, return-type acc){ ... }