Enums as factories
I started to enjoy very much J2SE 5, especially generics,
I still don't get static imports, but overall J2SE 5 is been a good experience.
One thing I found nice about
For example, Webwork 2 can be configured to use 3 different multipart parsers.
The configuration option is called
The 3 implementation classes extends the class
Using this class is very simple, given the following configuration:
A
Note the
Using
The possibility to use more verbose values (like 'pell' or 'jakarta') is definitely more appealing than using integer values (like '1' or '2') to distinguish parsers.
I have used this pattern also for commands, and the
enum
s and the java.util.concurrent
package.I still don't get static imports, but overall J2SE 5 is been a good experience.
One thing I found nice about
enum
s is the possibility to use them as factories in a simple way.For example, Webwork 2 can be configured to use 3 different multipart parsers.
The configuration option is called
webwork.multipart.parser
and can have one of 3 possible values: pell
, jakarta
or cos
.The 3 implementation classes extends the class
com.opensymphony.webwork.dispatcher.multipart.MultiPartRequest
so it's possible to write the following enum
:
public enum MultipartParsers
{
PELL(PellMultiPartRequest.class),
JAKARTA(JakartaMultiPartRequest.class),
COS(CosMultiPartRequest.class);
private final Class<? extends MultiPartRequest> parserClass;
private MultipartParser(Class<? extends MultiPartRequest> parserClass)
{
this.parserClass = parserClass;
}
public MultiPartRequest newInstance()
{
return parserClass.newInstance();
}
}
Using this class is very simple, given the following configuration:
webwork.multipart.parser=pell
A
Configuration
class can read the configuration, and creating the multipart parser is then very easy:
String parser = Configuration.getString("webwork.multipart.parser");
MultiPartRequest multipart = MultiPartParsers.valueOf(parser.toUpperCase()).newInstance();
Note the
MultiPartParsers.valueOf()
method, which is generated by the compiler for each enum
class: it takes a string and returns the enum
instance whose name matches the string.Using
MultiPartParsers.valueOf()
avoid switch
statements or chained if/else
statements.The possibility to use more verbose values (like 'pell' or 'jakarta') is definitely more appealing than using integer values (like '1' or '2') to distinguish parsers.
I have used this pattern also for commands, and the
newInstance()
method can take parameters to initialize the newly created instance, or even a vararg parameters.
public enum Commands
{
UPDATE(UpdateCommand.class),
INSERT(InsertCommand.class),
...
DELETE(DeleteCommand.class);
private final Class<? extends Command> commandClass;
private MultipartParser(Class<? extends Command> commandClass)
{
this.commandClass = commandClass;
}
public Command newInstance(Configuration config)
{
Command command = commandClass.newInstance();
command.configure(config);
return command;
}
}