我经常遇到需要编写如下代码的情况 任何设计模式都可以在没有大量IF语句的情况下做到这一点 -
A obj = new A();
B obj2 = new B();
for ( i = 1 ; i < 20 ; i ++ ) {
if( i == 1 )
obj.setField1(obj2.getOption1())
else if ( i == 2 )
obj.setField1(obj2.getOption2())
else if ( i == 3 )
obj.setField1(obj2.getOption3())
And so on.. for 20 times ..
obj.setField2(obj2.getNonOptionField2());
obj.setField3(obj2.getNonOptionField3())
}
编辑 -
这里循环的类比是我在数据库上循环,每个记录在其他表中创建20多个记录。在20条记录中,除了我添加的条件之外,大多数列都是相同的。
YEah设计不是最好的,但我没有选择。
答案 0 :(得分:3)
如果操作以整数值为条件,您可以创建Map<Integer,MyAction>
,其中MyAction
是您为此特定目的定义的接口。将MyAction
的实现放入映射以对应于整数选项,并在运行时调用操作以响应进入的值:
interface MyAction {
void setField(A obj, B obj2);
}
...
Map<Integer,MyAction> actionByNumber = new HashMap<Integer,MyAction>();
actionByNumber.put(1, new MyAction() {
void setField(A obj, B obj2) {
obj.setField1(obj2.getOption1());
}
});
actionByNumber.put(2, new MyAction() {
void setField(A obj, B obj2) {
obj.setField1(obj2.getOption2());
}
});
...
A obj = ...
B obj2 = ...
for (int i = 0 ; i != 20 ; i++) {
MyAction action = actionByNumber.get(i);
if (action != null) {
action.setField(obj, obj2);
}
}
答案 1 :(得分:2)
请尝试使用switch case。
例如,您的代码为:
for ( i = 1 ; i < 20 ; i ++ ) {
switch(i){
case(1): obj.setField1(obj2.getOption1());
break;
case(2): obj.setField1(obj2.getOption2());
break;
case(3): obj.setField1(obj2.getOption3());
break;
}
}
答案 2 :(得分:1)
一个选项是switch
声明。
另一种选择是让obj2
保留一系列选项,并通过索引访问它。类似的东西:
obj.setField1(obj2.options[i]);
人们会争论这个O-Oness,但你可以用一种存取方法来装扮它。
答案 3 :(得分:0)
+1到dasblinkenlight使用界面和建议的模式。越来越多的if / switch通常是代码气味,表明某些OO重构是合适的。您可以添加一个方法将新的MyAction实例传递给地图。这种方法优于 if 和 switch 构造的好处是:
1 - 实现Open to extension,关闭到修改策略。您想添加新行为吗?无需为不断增长的原始类添加另一个条件,只需创建一个新的MyAction实现并将其传入。
2 - 可以通过更改地图内容来改变运行时的行为。
根据您的具体要求,您可能不需要actionByNumberto作为地图,如果需要,列表可以执行,排序或排序。