The requirement that module dependency should be explicit creates a problem. One module must be able to refer to another. However if that class is referred to directly, then the class will be loaded immediately, when we might want to defer it.
To circumvent this problem, we use an identifier class, which can be used to refer to the module, the interface for this is shown in Listing 1.
[label=lst:ident, caption=The ModuleIdentifier Interface] public interface ModuleIdentifier public boolean isInterface(); public String getClassName(); public String getModuleName(); // ModuleIdentifier
The two methods in this interface public String getClassName() and public String getModuleName() define the link between a module and a String which can be used to refer to it, which solves the problem of referring to a Module (by a name) and a Class.
One difficulty with this is that using a String (the module name) to refer to a module is not type safe, and will result in errors when the name is typed incorrectly. This difficulty is solved by extending the class AbstractEnumeratedModuleIdentifier. This uses the a variation of the theme of the Singleton design pattern to create an identifier class which is relatively type safe. An example of its usage from Cinema-MX is shown in Listing 2. This class uses reflection to translate the variable name of its instances, into the String that it uses for its Module name.
[label=lst:enum, caption=The Abstract EnumeratedModuleIdentifier] public class CinemaBootIdentifier extends AbstractEnumeratedModuleIdentifier private CinemaBootIdentifier( String className, String toString ) super( className, toString ); public static final CinemaBootIdentifier CINEMA_BOOT = new CinemaBootIdentifier( "uk.ac.man.bioinf.apps.cinema.CinemaBoot", "Main Cinema Boot Class" ); public static final CinemaBootIdentifier CINEMA_SHARED = new CinemaBootIdentifier( "uk.ac.man.bioinf.apps.cinema.CinemaShared", "Shared Boot Class" ); // CinemaBootIdentifier
The practical upshot of all of this is that to refer to for instance the main Cinema Boot Module, the CINEMA_BOOT instance can be used directly. Its still possible to type this incorrectly of course, but this will be detected at compile time. Its also possible to type the class name incorrectly when writing the identifier, but at least this needs to only be done once.