Download presentation
Presentation is loading. Please wait.
1
copyright © 2002, David A. Hall Writing and Using Java TM Programming Language-Based Predicates ('Java Predicates') David Hall
2
copyright © 2002, David A. Hall Functor Functor: an Object that represents a function Evaluated as function: passed runtime arguments Functors can be passed as arguments Instantiated at runtime based on configuration Serialized or Persisted
3
copyright © 2002, David A. Hall Functors vs. Method Objects public void evaluate(Method m) { Object[] args = { arg1, arg2, etc }; try { Object val = m.invoke(args); } catch(IllegalAccessException x) {... } catch(IllegalArgumentException x) {... } catch(InvocationTargetException x) {... } } Number, types of arguments known in advance Compiler cannot check method's signature
4
copyright © 2002, David A. Hall Functors vs. Method Objects Functors can be nested Methods are not dependent on each other Functors are open for examination Methods are opaque (no way to examine code) Functors can be assembled at runtime Methods must written prior to compilation
5
copyright © 2002, David A. Hall Unary and Binary Functor Unary Functor public interface UnaryFunctor { public Object fn(Object arg); } BinaryFunctor public interface BinaryFunctor { public Object fn(Object arg1, Object arg2); } Trinary, etc. are possible
6
copyright © 2002, David A. Hall Predicate Predicate: a Functor that returns a Boolean UnaryPredicate public interface UnaryPredicate { public Boolean p(Object arg); } BinaryPredicate public interface BinaryPredicate { public Boolean p(Object arg1, Object arg2) ; }
7
copyright © 2002, David A. Hall Prolog grandmother(G,S) :- parent(P,S), mother(G,P). mother(sarah,issac). parent(issac, jacob). ?- grandmother(sarah, jacob) yes ?- grandmother(sarah, issac) no
8
copyright © 2002, David A. Hall STL Part of C++ Standard Library Contains a number of template based collections classes and common algorithms Functors/Predicates used as arguments for many of the algorithms count_if(InputIterator first, InputIterator last, Predicate pred);
9
copyright © 2002, David A. Hall STL Arithmetic Plus(x, y) Minus(x, y) Multiplies(x, y) Divides(x, y) Modulus(x, y) Negate(x) Comparison min(x, y) max(x, y) EqualTo(x, y) NotEqualTo(x, y) Less(x, y) LessEqual(x, y) Greater(x, y) GreaterEqual(x, y) Logical LogicalAnd(x, y) LogicalOr(x, y) LogicalNot(x, y) Construction Identity(x) ConstantUnary(x) ConstantBinary(x,y) Bind1st(x) Bind2nd(x) UnaryCompose(x) BinaryCompose(x) Project1st(x, y) Project2nd(x, y)
10
copyright © 2002, David A. Hall jgl Adaptation of STL in Java Originally created by ObjectSpace, inc Now owned by Recursion Software, Inc http://www.recursionsw.com/
11
copyright © 2002, David A. Hall Building Predicates Primitives are easy to use, but of limited utility Predicate andP = new LogicalAnd(); Boolean flag = andP.p(Boolean.TRUE, Boolean.FALSE) STL/JGL provide for assembly of compound expressions
12
copyright © 2002, David A. Hall Bind1st & Bind2nd Binders allow use of constant values with binary functors Require BinaryFunctor, Constant at construction UnaryFunctor discounter = new Bind1st(new Multiplies(), 1 - discountPct); UnaryFunctor taxer = new Bind1st(new Multiplies(), 1 + salesTaxRate);... salesPrice = discounter.fn(markedPrice); total = taxer.fn(salesPrice);
13
copyright © 2002, David A. Hall Unary Compose UnaryCompose allows result of one functor to be input to another Requires two UnaryFunctors at construction UnaryCompose netPrice = new UnaryCompose(taxer, discounter);... total = netPrice.fn(markedPrice);
14
copyright © 2002, David A. Hall BinaryCompose BinaryCompose is itself a UnaryFunctor BinaryCompose passes the results of two UnaryFunctors as arguments to a BinaryFunctor Requires BinaryFunctor, two UnaryFunctors at construction BinaryCompose cappedDiscount = new BinaryCompose(new min(), discounter, new ConstantUnary(10.0));
15
copyright © 2002, David A. Hall Miscellaneous Constant returns value passed at construction Identity returns the runtime argument Project returns one of two runtime arguments
16
copyright © 2002, David A. Hall Application Level Predicates Primitives and assemblies provide support for built in reference types: Arithmetic Functors require Number args Logical Functors require Boolean args Comparison Functors require Comparable args No support for user/business level objects
17
copyright © 2002, David A. Hall Custom Predicates You can build customized functors for your business objects public class GetStatusFn implements UnaryFunctor { public Object fn(Object arg) { PurchaseOrder po = (PurchaseOrder) arg; return po.getStatus(); } }
18
copyright © 2002, David A. Hall GetPropertyFn Alternatively, you can reflect using bean idioms public class GetPropertyFn implements UnaryFunctor { private String methName; public GetPropertyFn(String propName) { if (propName.startsWith("get")) methName = propName; else methName = "get" + propName; }...
19
copyright © 2002, David A. Hall GetPropertyFn (cont.)... public Object fn(Object arg) { try { Object[] parm = new Object[0]; Class[] types = new Class[0]; Class argclass = arg.getClass(); Method meth = argclass.getMethod(methName,types); return getMethod(arg).invoke(arg, parm); } catch (IllegalAccessException x) {...} catch (IllegalArgumentException x) {...} catch (InvocationTargetException x) {...} catch (NoSuchMethodException x) {...} }
20
copyright © 2002, David A. Hall Business Rule Example Business Rule example UnaryPredicate requiresApproval = new BinaryCompose(new GreaterThan(), new GetPropertyFn("Amount"), new ConstantUnary(500.00));
21
copyright © 2002, David A. Hall SimpleCompare public class SimpleCompare implements UnaryPredicate{ BinaryCompose bc; public SimpleCompare(BinaryPredicate comp, String propName, Object value) { fn = new BinaryCompose(comp, new GetPropertyFn(propName), new ConstantUnary(value); } public Boolean p(Object arg) { return (Boolean) bc.fn(arg); } }
22
copyright © 2002, David A. Hall SimpleCompare Same Business Rule UnaryPredicate requiresApproval = new SimpleCompare(new GreaterThan(), "Amount", 500.00);
23
copyright © 2002, David A. Hall SimpleKey Most SimpleCompare objects will use Equality comparisons, so create a special implementation public class SimpleKey extends SimpleCompare { public SimpleKey(String propName, Object value){ super(new EqualTo(), propName,value); } }... UnaryPredicate pendingOrders = new SimpleKey("Status", "PENDING");
24
copyright © 2002, David A. Hall Applications Collections Swing: ListCellRenderer Dynamic Query & Query-By-Example EJB: BMP Finder methods Symbolic Set Manipulation
25
copyright © 2002, David A. Hall Filtered Iterator public class FilteredIterator implements Iterator { private Object next; private Iterator base; private UnaryPredicate pred; public FilteredIterator(Iterator iter, UnaryPredicate p) { base = iter; pred = p }...
26
copyright © 2002, David A. Hall Filtered Iterator (cont)... public boolean hasNext() { while (iter.hasNext() { Object obj = iter.next(); if (pred == null || pred.p(obj)) { next = obj; return true; } } return false; }...
27
copyright © 2002, David A. Hall Filtered Iterator (cont)... public Object next() { if (next != null) { Object val = next; next = null; return val; } throw new NoSuchElementException(); } }
28
copyright © 2002, David A. Hall Collections & Algorithms public Iterator findAll (Collecton coll, UnaryPredicate p) { return new FilteredIterator(coll.iterator(), p); } public int countIf (Collection coll, UnaryPredicate p){ Iterator iter = new FilteredIterator(coll.iterator(), p); int ct = 0; while(iter.hasNext()) { iter.next(); ++ct; } return ct; }
29
copyright © 2002, David A. Hall Swing Example Swing provides many default models that work with built in primitives and/or collections of primitives. You are expected to provide implementations that map your business objects within Swing defaults By default, Swing hijacks toString() method
30
copyright © 2002, David A. Hall ListCellRenderer public class FunctorRenderer extends DefaultListCellRenderer { private UnaryFunctor func; public FunctorRenderer(UnaryFunctor fn) { func = fn; } public Component getListCellRendererComponent( JList list, Object value, int index, boolean sel, boolean focus) { setText(func.fn(value).toString()); setBackground(sel ? Color.red : Color.white); setForeground(sel ? Color.white : Color.black); return this; } }
31
copyright © 2002, David A. Hall ListCellRenderer Usage JList list = new JList(); UnaryFunctor fn = new GetPropertyFn("Id"); list.setCellRenderer(new FunctorRenderer(fn)); getContentPane().add(list);
32
copyright © 2002, David A. Hall Dynamic Query Visitable and Visitor interfaces public interface Visitable { public void accept(Visitor visitor); } public interface Visitor { public void visit(Visitable visitable); }
33
copyright © 2002, David A. Hall Implementing Acyclic Visitor Add Visitation support to SimpleKey public class SimpleKey extends SimpleCompare, implements Visitable {... public void accept(Visitor v) { if (v instanceof SimpleKey.Viz) ((SimpleKey.Viz)v).visit(this); } public interface Viz extends Visitor { public void visit(SimpleKey host); } }
34
copyright © 2002, David A. Hall Translation Visitor public class CloudscapeTranslator implements SimpleKey.Viz,... { StringBuffer buf; public String translate(UnaryPredicate p) { buf = new StringBuffer(256); try { p.accept(this); } catch (Exception x) { x.printStackTrace(); } return buf.toString(); }...
35
copyright © 2002, David A. Hall Translation Visitor... public void visit(Visitable host) {} public void visit(SimpleKey host) { buf.append('"'); buf.append(host.getPropName()); buf.append("\" = "); host.getPredicate().accept(this); quote(host.getValue()); }...
36
copyright © 2002, David A. Hall Translation Visitor... private void quote(Object val) { if (val instanceof Number) { buf.append(val); } else if (val instanceof String) { buf.append("'"); buf.append(val); buf.append("'"); } // plus any other cases: Dates, Booleans, // Objects, etc }
37
copyright © 2002, David A. Hall Translator Usage private Collection selectIf(UnaryPredicate p) throws SQLException { CloudscapeTranslator trans = new CloudscapeTranslator(); String selectStatement = "select \"poId\" from \"PurchaseOrderEJBTable\“” +” where " + trans.translate(p); PreparedStatement prepStmt = getDBConnection().prepareStatement(selectStatement);...
38
copyright © 2002, David A. Hall Translator Usage (cont)... ResultSet rs = prepStmt.executeQuery(); ArrayList a = new ArrayList(); while (rs.next()) { a.add(rs.getString(1)); } prepStmt.close(); return a; }
39
copyright © 2002, David A. Hall Predicates and Entity Beans public interface OrderHome extends EJBHome { public Order create(String id, String userId, Date date, BigDecimal amount, String status) throws RemoteException, CreateException; public Order findByPrimaryKey(UnaryPredicate p) throws RemoteException, FinderException; public Collection findByPredicate(UnaryPredicate p) throws RemoteException, FinderException; }
40
copyright © 2002, David A. Hall Set Manipulation Predicate implicitly defines a set (the set of all values for which the Predicate will return true) Define set manipulation operations in terms of Predicates Allows program to work with sets of values without having to instantiate them
41
copyright © 2002, David A. Hall Set Manipulation public class Predicates { static public UnaryPredicate union(UnaryPredicate p1, UnaryPredicate p2) { return new BinaryCompose(new LogicalOr(), p1, p2); /* thank you to the guy in the back row */ } // intersection, set difference, etc }
42
copyright © 2002, David A. Hall References Prolog http://mini.net/cetus/oo_prolog.html STL http://www.yrl.co.uk/~phil/stl/stl.htmlx#Algorithms_and_Fun ctions http://www.byte.com/art/9510/sec12/art3.htm http://www.sgi.com/tech/stl/ JGL: Recursion Software, Inc http://www.recursionsw.com/
43
copyright © 2002, David A. Hall References (cont) Acyclic Visitor Pattern http://www.objectmentor.com/resources/articles/acv.pdf James O. Coplien. Advanced C++ Programming Styles and Idioms. Addison-Wesley, Reading, MA, 1992 Erich Gamma, et al. Design Patterns Elements of Reusable Object-Oriented Software. Addison-Wesley, Reading, MA, 1995 Kenneth P. Bogart. Discrete Mathematics. D. C. Heath and Company, Lexington, MA, 1988
Similar presentations
© 2025 SlidePlayer.com Inc.
All rights reserved.