You need to evaluate an
object to see if it meets criteria,
and you want to capture these criteria in a custom
Predicate
.
Implement the Predicate
interface and capture your
logic in an evaluate( )
method. Example 4-5 is a
simple Predicate
implementation that always
returns true
; it is intended as a basic example of
how to implement the Predicate
interface.
Predicates
can be used in any number of
situations, such as validating user input, filtering a
Collection
, or just as a replacement for complex
conditional logic. A Predicate
can be as simple or
as complex as you need it to be; the only contract it must satisfy is
the production of a boolean
result from an
evaluate( )
method.
To demonstrate the process of writing a fairly complex implementation
of the Predicate
interface, a contrived example is
developed in Example 4-6. Your application evaluates
the condition of the space shuttle and makes a determination for
launch—go or no go. Some of the criteria include the
temperature of the launch pad, the status of the crew, and the
presence (or absence) of fuel. In the end, your boss is looking for
thumbs up or thumbs down, and you decide to write a program that
returns a boolean
decision. This decision is
implemented in the LaunchPredicate
class.
Example 4-6. Implementing the Predicate interface
package com.discursive.jccook.collections.predicate; import org.apache.commons.collections.Predicate; public class LaunchPredicate implements Predicate { public LaunchPredicate( ) {} public boolean evaluate(Object object) { boolean launchGo = false; LaunchStats stats = (LaunchStats) object; boolean crewReady = stats.isCrewPresent( ) && stats.isCrewHealthy( ); boolean fueled = stats.isShuttleFueled( ) && stats. isFuelIgnitionReady( ); boolean withinLaunchWindow = stats.isLaunchWindowOpen( ); boolean properWeather = ( stats.temperature( ) > 35 ) && ( !stats.isLightningDangerPresent( ) ); // Check the crew, fuel, and launch time if( crewReady && fueled && withinLaunchWindow ) { launchGo = true; } // Override a GO decision if the weather is bad if( !properWeather ) { launchGo = false; } return launchGo; } }
A shuttle launch is predicated on the presence and health of the
crew, the state of the fuel, and the time of the launch event. A
final weather check is performed to ensure that the temperature of
the shuttle is not below 35 degrees Fahrenheit. If this critical
temperature limit is not met, the Predicate
overrides the previous decision to launch. Using a
LaunchPredicate
encapsulates your decision logic
in one object, making it easier to upgrade, maintain, and test this
decision process. Your unit tests can pass a mock object to this
predicate, testing every possible permutation of possible inputs. The
following example demonstrates the use of the
LaunchPredicate
:
LaunchPredicate launchDecision = new LaunchPredicate( ); LaunchStats stats = measureLaunchStatistics( ); if( launchDecision.evaluate( stats ) ) { System.out.println( "We are Go for Ignition." ); } else { System.out.println( "Abort mission." ); }
The real Space Shuttle Launch Team has the outrageously complex job
of monitoring and controlling every aspect of launching a spacecraft,
and I’m sure that NASA doesn’t
implement the Predicate
interface from Jakarta
Commons Collections. While it isn’t related to the
topic of open source Java programming, it is a fascinatingly complex
piece of software that maintains a shuttle launch. It is written in
something called high-order assembly language/shuttle (HAL/S). If you
are interested in learning more about one of the most complex pieces
of software, take a look at NASA’s Space Shuttle
Launch Team website at http://science.ksc.nasa.gov/shuttle/countdown/launch-team.html.
(Besides, I’m sure you are amused that NASA controls
spacecraft with an assembly language known as HAL.)
This recipe mentions the use of a mock object to test a
Predicate
. One of the attractions of using a
Predicate
to encapsulate any complex condition is
the ability to write a test for this condition logic; mock
objects
are a method of unit testing that involves passing
a mock implementation of an object to a class i
n a test. For
more information about mock objects, see http://www.mockobjects.com/.
Get Jakarta Commons Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.