Lookup Pattern and Java Generics
In some situations I dislike the verbosity of declaring Java generics.
Map<Key<String, Integer>, List<Item>> m = getItemsMap();
But using Java generics reduces other forms of tedious class casting common when using List and Map objects. For example, in my current project their we use a Lookup pattern, used to locate concrete implementation to certain key services. For example, to read and write application data we use a FileService which we can get via the Lookup class.
FileService fs = (FileService)Lookup.lookup(FileService.class)
These services we lookup are stateless and we can switch the underlying implementation by modifying some configuration file. In terms of this discussion, I wanted to note that casting. Using Java generics that cast is not required if you use parameterized types. Notice that the key of the lookup is a Java type, in our application it is an interface which the underlying implementation class needs to implement. As you can imagine, the implmenation of the lookup method can be simplified to the following…
public static Object lookup(final Class type) { // compoments is a map of implementation service Object comp = components.get(type); return comp; }
Using Java genetics we can use the class information in the parameter to cast the return type correctly. We can remove the required class cast by updating the code that locates the required concrete class for the service requested. Here is a simplified version of the lookup method which removes the need to cast.
public static <t> T lookup(final Class<t> type) { T comp = (T)components.get(type); return comp; }
Now, using this updated lookup method and employing Java generics our lookup can be of the following form.
FileService fs = Lookup.lookup(FileService.class);