blob: 28b51f1efcf76c0c348375f89361893adb463569 [file] [log] [blame]
<?xml version="1.0"?>
Copyright 2003-2004 The Apache Software Foundation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
See the License for the specific language governing permissions and
limitations under the License.
<author email="">Apache Commons Development Team</author>
<author email="">Rodney Waldhoff</author>
<section name="Examples">
We've begun to develop some example code that demonstrates the use and
utility of the Functor component.
In order to keep the examples in sync with the rest of the code,
each example is written as a <a href="">JUnit</a>
<code>TestCase</code>. The example programs are executed along with
all the other unit tests, and can be invoked via <code>ant test</code>
or <code>maven test</code> once you've set up Ant or Maven as described
in the <a href="building.html">build instructions</a>.
If you're not familiar with JUnit, don't worry. An understanding of
JUnit isn't important for an understanding of these examples, and
we'll walk you through the relevant bits anyway.
Two things you'll want to know about JUnit are (a) all the methods
whose names start with "test" will be executed automatically by the
test suite and (b) there are various "assert" methods that can be used
to make assertions about the Objects being tested. If any assertion
fails, the JUnit framework will count (and report) this as a test
<p>You can run a specific test case or sub-suite via Ant by invoking</p>
<pre>ant -Dtest.entry=&lt;fully-specified-test-case-name&gt; test</pre>
<p>or in Maven by invoking</p>
<pre>maven -Dtestcase=&lt;fully-specified-test-case-name&gt; test:single</pre>
<p>For example, to run the Quicksort example, invoke</p>
<pre>ant -Dtest.entry=org.apache.commons.functor.example.QuicksortExample test</pre>
<pre>maven -Dtestcase=org.apache.commons.functor.example.QuicksortExample test:single</pre>
<p>To run all the examples, invoke:</p>
<pre>ant -Dtest.entry=org.apache.commons.functor.example.TestAll test</pre>
<pre>maven -Dtestcase=org.apache.commons.functor.example.TestAll test:single</pre>
Each example is has descriptive prose mixed right in with the source, as
<code>/* C++ style */</code> comments.
<subsection name="Code Katas">
"Pragmatic" Dave Thomas has been
<a href="">blogging</a>
a series of programming exercises he calls
<a href="">Code Katas</a>.
These exercises are intended to provide "practice sesssions" that allow
programmers to hone their craft. The notion is borrowed from the
practice of Karate, where, in Dave's words
"a kata is an exercise where you repeat a form many, many times,
making little improvements in each".
Here we use several of Dave's Code Katas to explore the
Commons-Functor library.
<dt><a href="">Kata One: Supermarket Pricing</a></dt>
Dave's <a href=",v">Kata One</a> asks how
one might implement supermarket pricing rules, like "three for a dollar" or "buy two get one free".
By encapsulating tiny bits of logic, functors provide a useful solution to this problem, as
illustrated in the
<a href="*checkout*/jakarta/commons/sandbox/functor/trunk/src/test/org/apache/commons/functor/example/kata/one/">SupermarketPricingExample</a>.
<dt><a href="">Kata Two: Binary Chop</a></dt>
<a href=",v">Kata Two</a> asks us
to create several different implemenations of the binary search algorithm, which once you
get past three or four implemenations, is more difficult that it sounds.
<a href="*checkout*/jakarta/commons/sandbox/functor/trunk/src/test/org/apache/commons/functor/example/kata/two/">TestBinaryChop</a>
presents several implementations, with functor and non-functor variations.
<dt><a href="">Kata Four: Data Munging</a></dt>
<a href=",v">Kata Four</a> asks us
to explore extreme reuse. Our
<a href="*checkout*/jakarta/commons/sandbox/functor/trunk/src/test/org/apache/commons/functor/example/kata/four/">DataMunger</a>
allows for very small implementations of the
<a href="*checkout*/jakarta/commons/sandbox/functor/trunk/src/test/org/apache/commons/functor/example/kata/four/">weather</a>
<a href="*checkout*/jakarta/commons/sandbox/functor/trunk/src/test/org/apache/commons/functor/example/kata/four/">soccer (football)</a>
<subsection name="Generators">
The <a href="">lines</a>
package demonstrates a functional approach to IO using Generators and the Algorithms class.
<subsection name="Reuse Through Composition">
The Functor package, and more generally, a functional approach
to program design, supports a powerful technique for balancing
behavior specialization and code reuse.
Traditional Object Oriented design suggests inheritence as a
mechanism code reuse, and method overloading as a mechanism for
specialization. For example, one defines a general purpose, perhaps
even abstract class, say <i>AbstractList</i>, and then extend or
specialize this parent via subclasses, inheriting some behaviors
and overloading others.
Functors encourage another, complementary approach to code reuse
and behavior specialiazation: composition. Following a compositional
design, we create a number of simple objects and then combine them to
create more complex behaviors. For example, the
<a href="">Commons Pool</a>
component defines an <code>ObjectPool</code> type that maintains
a collection of pooled objects, but delegates to a
<code>PoolableObjectFactory</code> to create, validate and destroy
the objects to be pooled. Arbitrary <code>ObjectPool</code>
implementations can be composed with arbitrary
implementations in order to create new types of pools.
<a href="*checkout*/jakarta/commons/sandbox/functor/trunk/src/test/org/apache/commons/functor/example/">FlexiMap example</a>
applies this design to <code>java.util.Map</code>, demonstrating how
"pluggable" functors can be applied to a generic <code>Map</code> structure in order
to introduce new behaviors.
<a href="*checkout*/jakarta/commons/sandbox/functor/trunk/src/test/org/apache/commons/functor/example/map">map</a>
package is a more complete example of this, implementing a number of the Commons-Collections Maps
derived from a base
<a href="*checkout*/jakarta/commons/sandbox/functor/trunk/src/test/org/apache/commons/functor/example/map/">FunctoredMap</a>.
<subsection name="A Quicksort Implementation">
The <a href="*checkout*/jakarta/commons/sandbox/functor/trunk/src/test/org/apache/commons/functor/example/">Quicksort example</a>
presents an implementation of the Quicksort sorting algorithm written in a functional programming
style using Commons Functor.