In the first code snippet I am creating a generic class to hold configuration details. I am currently using it as a way to pass run time configuration options to plugins in a generic manner. The second snippet is a helper class that utilizes the class to provide the public methods for use which helps guarantee type safety.
Questions
- How is my use of generics? I feel like there is a better way to handle this.
- Is there a better design pattern to be used here?
DefaultConfiguration
import java.util.HashMap;
import java.util.Map;
public class DefaultConfiguration implements Configuration {
private final Map<String, Setting> options;
public DefaultConfiguration() {
this.options = new HashMap<String, Setting>();
}
@Override
public <T> T get(String option, Class<T> type) {
Setting setting = options.get(option);
if (setting != null) {
return type.cast(setting.getSetting(type));
}
return null;
}
@Override
public <T> void set(String option, T setting, Class<T> type) {
options.put(option, new Setting<T>(setting, type));
}
@Override
public void set(String option, Object setting) {
options.put(option, new Setting(setting, setting.getClass()));
}
class Setting<W> {
private final Class<? super W> type;
private final W setting;
public Setting(W setting, Class<? super W> type) {
this.type = type;
this.setting = setting;
}
public W getSetting(Class<? super W> type) {
if (type.isAssignableFrom(this.type)) {
return setting;
}
return null;
}
}
}
MyConfiguration
public class MyConfiguration extends DefaultConfiguration {
public String getSettingA() {
return super.get("settingA", String.class);
}
public void setSettingA(String settingA) {
super.set("settingA", settingA, String.class);
}
public Integer getSettingB() {
return super.get("settingB", Integer.class);
}
public void setSettingB() {
super.set("settingB", settingB, Integer.class);
}
}
Updated Classes
import java.util.HashMap;
public class Configuration
extends HashMap<String, Object>
{
/**
*
*/
private static final long serialVersionUID = 1L;
@Override
public <T> T get(String option, Class<T> type)
{
Object obj = get(option);
if (obj == null) {
return null;
}
try {
return type.cast(obj);
} catch (ClassCastException ex) {
throw new ConfigurationException(ex);
}
}
}
public class MyConfiguration
extends Configuration
{
/**
*
*/
private static final long serialVersionUID = 1L;
private static final String SETTING_A = "settingA";
private static final String SETTING_B = "settingB";
public String getSettingA()
{
return get(SETTING_A, String.class);
}
public void setSettingA(String settingA)
{
put(SETTING_A, settingA);
}
public Integer getSettingB()
{
return get(SETTING_B, Integer.class);
}
public void setSettingB()
{
put(SETTING_B, settingB);
}
}