How to use the TargetFactory

By Elmar Grom

Here is a simple approach that you can use to automatically instantiate flavors of your class that are tailored to a specific operating system. If necessary you can even have different versions for different flavors of an operating system, such as Windows-NT.

Implement your API with the class name that you would like to use. The API can be implemented as interface, a partially or completely abastact class or a complete class implementation. The choice is your's and primarily depends your specific needs. However, it seems likely that in most cases it will be necessary to have a default implementation that can be instantiated if an appropriate flavor does not exist for some reason. One situation might be that a special version is not needed for all the different OS/OS-Flavor combinations but only for one or two cases. For all other cases the default implementation might work just fine. Another reason would be that an installation is attempted on an OS that is unknown or is not listed and as a fallback position a default implementation of the class should be available. For the following I assume that a complete implementation is used.

In the next step you need to derive one class for each of the different flavors you want to support with specific implementations. All of these classes must be contained in the same package as the base class and must follow a prescribed naming convention. Name prefixes are defined for a number of operating systems and operating system flavores. Please review the class documentation for TargetFactory for a a complete list of these prefixes.

Let's assume you have a class called MyClass in the package com.izforge.izpack.installer. This class contains your default implementation. For some reason you need modified functionality for Mac OS X. You would now implement the class Mac_X_MyClass which is extending MyClass and implements the necessary differences. This is all you need to do on the implementation end.

To get the correct instance based on the OS, simply call makeObject(). This example illustrates the call:
  TargetFactory.getInstance ().makeObject ("com.izforge.izpack.installer.MyClass");
This call will return an instance of the proper flavor, without worry about the OS on your part. More specifically, you will recive an instance of MyClass on all operating systems, except on Mac OS X, in which case you will receive an instance of Mac_X_MyClass. To make this work, TargetFactory will automatically map the correct name and create an instance for you.

The Constructor

There is one drawback to this implementation that you must be aware of. Because of the way how instances are created, each class must have a default constructor. Of course this is done either by not implementing a constructor or by implementing a constructor without parameters (this must not be private). This constructor will be used when instances are created. As a result, you can not pass parameters to the constructor.

If you need to create instances that perform initial operations based on a set of parameters, I recommend the following approach. Instead of a constructor implement a method called initialize(). Call makeObject() to get your instance and then call initialize() with your parameters before using that object.