如何将此switch-case块转换为良好的代码?
private static void agentFieldContructor(Agent agent, String nodeName, String value) {
switch (nodeName) {
case "Description":
agent.setDescription(value);
break;
case "Model":
agent.setModel(value);
break;
(... +18)
}
}
agent
是一个对象,我根据指定的value
使用nodeName
参数填充它。
每个nodeName引用一个不同的代理属性,但我收到它就像一个字符串,我不能改变它。我搜索了一些设计模式但找不到任何可以帮助我的东西。
答案 0 :(得分:1)
如果允许您使用反射。
private static void agentFieldContructor(Agent agent, String nodeName, String value) {
Method setMethod = Agent.class.getMethod("set"+nodeName,String.class)
setMethod.invoke(Agent,value)
}
答案 1 :(得分:1)
实现这一目标的一个紧凑方法是通过反思。您可以访问setter方法并使用您的值调用它。
0 1 2
d1 1 1 1
d2 2 2 2
d3 3 3 3
请注意,您将不得不处理:
public static void agentFieldConstructor(Agent agent, String nodeName, String value) {
try {
agent.getClass().getDeclaredMethod("set" + nodeName, value.getClass()).invoke(agent, value);
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
e.printStackTrace();
}
}
)......所有这些都是读者的练习。
答案 2 :(得分:1)
没有switch-case或反射的另一种可能性是使用复杂的枚举。这里的枚举是转换器,从String键到setter调用:
public enum AgentFields {
DESCRIPTION {
@Override
public void setInAgent(Agent agent, String value) {
agent.setDescription(value);
}
},
MODEL {
@Override
public void setInAgent(Agent agent, String value) {
agent.setModel(value);
}
};
public abstract void setInAgent(Agent agent, String value);
// Call this method to set a named field's value
public static void agentFieldSetter(Agent agent, String nodeName, String value) {
AgentFields.valueOf(nodeName.toUpperCase()).setInAgent(agent, value);
}
}
这声明了一个枚举,每个字段有一个“值”,每个值带有一个单独的setter。使用所有枚举自动提供的valueOf()方法完成调度。我用toUpperCase修饰它以允许通常的大写枚举值约定,并使它不区分大小写。
答案 3 :(得分:0)
这里的问题不在于switch-case语句本身。而是与Agent类本身的设计有关。首先,Agent应该有一个合适的构造函数,您可以在其中传递属性值。如果这些值可以改变,那么Agent的用户应该直接调用setter而不是使用这个帮助函数。
更重要的是,具有20个属性的类可能是重构的候选者。尝试找到这些属性的子集之间的关系,这些属性可以分解为单独的类。
答案 4 :(得分:0)
我完全同意评论。但是,如果您真的不想使用switch case并且您的方法名称和案例字符串几乎相同,则可以使用反射。 Here是可以帮助您的解决方案。