我认为这是网络项目中非常常见的情况。假设有一个实体,例如:
//JAVA code
@Data
class Entity{
private String a;
private String aExt;
private String b;
private String bExt;
private String c;
private String cExt;
... something more ...
}
出于某种目的,我需要根据传递的参数从Entity
获取部分值,例如:
public ViewObject foo(Entity entity, String condition){
ViewObject vo = new ViewObject();
if("aRelated".equals(condition)){
vo.setValue1(entity.getA());
vo.setValue2(entity.getAExt());
}
else if("bRelated".equals(condition)){
vo.setValue1(entity.getB());
vo.setValue2(entity.getBExt());
}
else if(cRelated".equals(condition)){
vo.setValue1(entity.getC());
vo.setValue2(entity.getCExt());
}
... else statement if there are other values ....
return vo;
}
我知道我可以使用switch-case
语句来减少foo()
中的某些字词,但与if-else
相比没有本质区别,特别是当Entity
有很多变量时
作为一个简单的例子,foo()
只是一个视图对象构建器,但我的项目更复杂,每个{{strong>只有不同的变量名称有许多重复的代码{1}}陈述。
如何减少上述重复代码?
答案 0 :(得分:3)
您可以尝试创建两个哈希映射:
// name these properly!
HashMap<String, Function<Entity, String>> valueMap = new HashMap<>();
HashMap<String, Function<Entity, String>> extMap = new HashMap<>();
添加这些KVP:
// valueMap
"aRelated" - Entity::getA
"bRelated" - Entity::getB
"cRelated" - Entity::getC
// extMap
"aRelated" - Entity::getAExt
"bRelated" - Entity::getBExt
"cRelated" - Entity::getCExt
现在,您可以在没有if语句的情况下执行此操作:
vo.setValue1(valueMap.get(condition).apply(entity));
vo.setValue2(extMap.get(condition).apply(entity));
答案 1 :(得分:1)
另一种选择是使用反射:
import java.lang.reflect.Method;
import java.lang.reflext.InvocationTargetException;
...
public ViewObject foo(Entity e, String c) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
String[] methodNames = { "get" + c.substring(0,1).toUpperCase(), "get" + c.substring(0,1).toUpperCase() + "Ext" };
Method[] methods = { e.getClass().getDeclaredMethod(methodNames[0]), e.getClass().getDeclaredMethod(methodNames[1]) };
ViewObject vo = new ViewObject();
vo.setValue1((String)methods[0].invoke(e));
vo.setValue2((String)methods[1].invoke(e));
return vo;
}
虽然我不得不承认我个人更喜欢其他答案的地图方法,只是显示更多选项。
答案 2 :(得分:0)
使用地图可以解决问题:
class EntityPart {
String s;
String sExt;
}
class Entity {
Map<String,EntityPart> m = new HashMap<>();
m.add("aRelated",new EntityPart());
m.add("bRelated",new EntityPart());
....
}
public ViewObject foo(Entity entity, String condition) {
ViewObject vo = new ViewObject();
EntityPart ep = entity.m.get(condition);
vo.setValue1(ep.s);
vo.setValue2(ep.sExt);
return vo;
}
答案 3 :(得分:0)
将实体设为enum
而不是类。
public enum Entity {
A("a", "aExt"), B("b", "bExt"), C("c", "cExt");
private final String name;
private final String text;
private Entity(String name, String text) {
this.name = name;
this.text = text;
}
public String getName() {
return name;
}
public String getText() {
return text;
}
public static Entity fromString(String raw) {
return LOOKUP.get(raw);
}
private static final Map<String, Entity> LOOKUP = new HashMap<>();
static {
for (Entity e : values()) {
LOOKUP.put(e.getName(), e);
}
}
}
并将您的foo
方法修改为
public ViewObject foo(String condition){
/*
* pass condition as "a", "b", "c" only not "aRelated", "bRelated", "cRelated"
*
*/
ViewObject vo = new ViewObject();
Entity e = Entity.fromString(condition);
if(null != e) {
vo.setValue1(e.getName());
vo.setValue2(e.getText());
}
return vo;
}