The above algorithm to insert in order an integer into an ordered list of integers can only be used for a very specific implementation of
IList
, namely the one that has
MTList
and
NEList
as concrete subclasses. How can we write list algorithms that can be used for ANY implementation of the abstract specification of the list structure represented by the abstract class
IList
?
We can achieve our goal by
- abstracting the behavior of
MTList
andNEList
into interfaces with pure abstract structural behaviors. - applying the Abstract Factory Design Pattern to hide the concrete implementation from the user.
2. abstract list behaviors
The concrete empty list and non-empty list implemented as
MTList
and
NEList
are now expressed as interfaces as follow.
package listFW;
/*** Represents the abstract behavior of the immutable list structure.
* A list intrinsically "knows" how to execute an algorithm on itself.*/
interface IList {Object execute(IListAlgo algo, Object... inp);
} |
package listFW;
/*** Represents the immutable empty list.
* The empty list has no well-defined* structural behavior: it has no first
* and no rest.*/
interface IMTList extends IList {} |
package listFW;
/*** Represents the immutable non-empty list.
* An immutable non-empty list has a data* object called first, and an isomorphic
* subcomponent called rest. Its structural* behavior provides access to its internal
* data (first) and substructure (rest).*/
interface INEList extends IList {/**
* "Gettor" method for the list's first.* @return this INElist's first element.
*/Object getFirst();
/*** "Gettor" method for the list's rest.
* @return this INElist's rest.*/
IList getRest();} |
3. abstract list factory
Before we describe in general what the
Abstract Factory Pattern is, let's examine what we have to do in the case of
IList
.
- Define an abstract factory interface,
IListFactory
, to manufacture empty and non-emptyIList
objects. PutIList
,IMTList
,INEList
,IListVistor
, andIListFactory
in the same package.IListFactory
is specified as followed.
IListFactory.java |
package listFW;
/*** Abstract factory to manufacture IMTList and INEList.
*/interface IListFactory {
/*** Creates an empty list.
* @return an IMTList object.*/
IMTList makeEmptyList();/**
* Creates a non-empty list containing a given first and a given rest.* @param first a data object.
* @param rest != null, the rest of the non-empty list to be manufactured.* @return an INEList object containing first and rest
* @exception IllegalArgumentException if rest is null.*/
INEList makeNEList(Object first, IList rest);} |
IList
,
IListAlgo
, and
IListFactory
prescribe a
minimal and
complete abstract specification of what we call a list
software component . We claim without proof that we can do everything we ever want to do with the list structure using this specification.
- All algorithms (i.e. visitors) that call for the creation of concrete
IList
objects will need to have an abstract factory as a parameter and use it to manufactureIList
objects. We usually pass the factory as an argument to the constructor of the visitor. The visitor is thus not a singleton.