Java允许我们在Enum上嵌入数据和行为。我不想直接在Enum上实现工厂,因为我认为这不是它的角色。
但我可以将类引用放在枚举上,并将对象构造在外部工厂上。与传统的工厂模式相比,最适合您的实现是什么?在哪种情况下使用哪种解决方案更好?
现在,代码。
在两个解决方案中用来构造对象的函数。如果需要,使用fly实现带有Map的fly-weight pattern。
private Action getAction(Class<? extends Action> actionClazz) {
// logger + error handling
return actionClazz.newInstance();
}
1)使用传统工厂:
public enum ActionEnum {
LOAD_DATA,
LOAD_CONFIG;
}
public Action getAction(ActionEnum action) {
switch (action) {
case LOAD_CONFIG:
return getAction(ActionLoadConfig.class);
case LOAD_DATA:
return getAction(ActionLoadData.class);
}
}
2)使用Enum风格的工厂:
public enum ActionEnum {
LOAD_DATA(ActionLoadConfig.class),
LOAD_CONFIG(ActionLoadData.class);
public ActionEnum(Class<? extends Action> clazz){...}
public Class<? extends Action> getClazz() {return this.clazz}
}
public Action getAction(ActionEnum action) {
return getAction(action.getClazz());
}
发布于 2013-07-11 05:44:42
第二个更简洁:它不需要任何长的切换块,并且像第一个一样没有忘记枚举值的风险。
但是,并不总是可以使用它,因为枚举可能是某种通用枚举(例如,Month
),而不应该耦合到操作工厂。
发布于 2017-11-06 08:50:41
如果可能的话,应该避免IMO调用newInstance()
,因为它明目张胆地破坏了java提供的一些编译时保护(请阅读它的javadoc),并引入了新的Exception
来处理。
这里有一个类似于what Sergey provided的解决方案,由于使用了函数接口和方法引用,它更加简洁。
public enum ActionEnum {
LOAD_DATA(ActionLoadData::new),
LOAD_CONFIG(ActionLoadConfig::new)
private Supplier<Action> instantiator;
public Action getInstance() {
return instantiator.get();
}
ActionEnum(Supplier<Action> instantiator) {
this.instantiator = instantiator;
}
}
public Action getAction(ActionEnum action) {
return action.getInstance();
}
发布于 2016-12-22 19:10:31
这对我来说很有效:
enum ActionEnum
{
LOAD_DATA {
@Override
public ActionLoadData getInstance() {
return new ActionLoadData ();
}
},
LOAD_CONFIG {
@Override
public ActionLoadConfig getInstance() {
return new ActionLoadConfig();
}
};
public abstract ILightBulb getInstance();
}
class ActionFactory
{
public Action getAction(ActionEnum action)
{
return action.getInstance();
}
}
https://stackoverflow.com/questions/17581310
复制相似问题