Closures Hierarchy - UnquietCode/Closures-for-Java GitHub Wiki
The Closure classes have three basic 'layers'. The first is made up of the AbstractClosure
classes, which are used to construct new closures. The methods and variables available to AbstractClosure
are useful while implementing them, but create clutter when using them. To that end, each AbstractClosure
class implements a corresponding Closure
interface, which hides the unnecessary parts.
Still, some methods like curry(...)
can modify the closure, and you would probably rather that nobody else did that but you. To further reduce the functionality the AbstractClosure
or Closure
objects can return a 'View'. A View provides only the basic methods to work the closure. Its name also more accurately spells out what it is: a view. A single closure can have any number of active views, and changes to the closure will affect the views. Views are what is often passed around, since recipients need only run them and be aware that they are potentially mutable from the outside.
The following chart shows more clearly the three levels (click to enlarge).
When working with different kinds of closures with different arguments and possibly type parameters, it becomes useful to have a "common currency". The ClosureView
provides this, and is often used by other classes in the package, such as Chain
. A MultiClosure
, for example, can be constructed using its makeMultiClosure(...)
method and a series of ClosureView
objects. Any of the closures and views can be turned into a ClosureView
, and passed around.
In closing, to create a new closure you will have to use an AbstractClosure
object. This can immediately be cast to a Closure
object, which is generally the default use case. Further, both of these have methods which create a ClosureView
object. To prevent modification of a closure (through currying), you can remove all references to the original object and preserve only one or more views. The ClosureView
is the common class which other classes and methods accept as inputs.