Java 嵌套的IF语句

Java 嵌套的IF语句,java,design-patterns,Java,Design Patterns,我经常遇到需要编写如下代码的情况 在没有大量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

我经常遇到需要编写如下代码的情况 在没有大量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())

}
A obj=新的A();
B obj2=新的B();
对于(i=1;i<20;i++){
如果(i==1)
obj.setField1(obj2.getOption1())
else如果(i==2)
obj.setField1(obj2.getOption2())
else如果(i==3)
obj.setField1(obj2.getOption3())
以此类推……20次。。
obj.setField2(obj2.getNonOptionField2());
obj.setField3(obj2.getNonOptionField3())
}
编辑-

与循环相似的是,我在一个数据库上循环,每条记录在另一个表中再创建20条记录。在这20条记录中,除了我添加的条件之外,大多数列都是相同的


是的,设计不是最好的,但我没有选择

如果操作以整数值为条件,您可以创建一个
映射
,其中
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);
    }
}
接口MyAction{
无效设置字段(A obj,B obj2);
}
...
Map actionByNumber=新建HashMap();
actionByNumber.put(1,new MyAction(){
无效设置字段(A obj,B obj2){
obj.setField1(obj2.getOption1());
}
});
actionByNumber.put(2,新的MyAction(){
无效设置字段(A obj,B obj2){
obj.setField1(obj2.getOption2());
}
});
...
一个obj=。。。
B obj2=。。。
for(int i=0;i!=20;i++){
MyAction=actionByNumber.get(i);
如果(操作!=null){
动作设定域(obj,obj2);
}
}

一个选项是
开关
语句

另一个选项是使
obj2
保留一个选项数组,并通过索引访问它。比如:

obj.setField1(obj2.options[i])

人们会争论这个问题的唯一性,但你可以用访问器的方法来修饰它。

试着用一个代替

例如,您的代码是:

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;
    }
}
(i=1;i<20;i++)的
{
开关(一){
案例(1):obj.setField1(obj2.getOption1());
打破
案例(2):obj.setField1(obj2.getOption2());
打破
案例(3):obj.setField1(obj2.getOption3());
打破
}
}

+1说明dasblinkenlight对界面的使用和建议的模式。不断增长的if/switch通常是一种代码气味,表明某种面向对象重构是合适的。您可以添加一个方法,将新的MyAction实例传递到映射。与if和switch构造相比,这种方法的好处在于:

1-执行开放到扩展,关闭到修改策略。是否要添加新的行为?无需向不断增长的原始类添加其他条件,只需创建MyAction的新实现并将其传入即可

2-运行时可以通过更改映射的内容来更改行为


根据您的具体要求,您可能不需要ActionByNumber来作为映射,可能需要一个列表,如有必要,可以进行排序或排序。

您可以使用switch case。根本不清楚为什么在这里使用循环。编写一个函数
getOption(i)
对于
B
类?您的设计似乎有问题……我的经验是,如果您没有足够的代码思考,这种问题经常会发生,很多时候,这样的问题可以使用多态性解决。这不是像上面的代码那样复杂吗,只是为了在数字上匹配?@Kata这只是一个插图,简单到骨架的本质(即将动作对象放入地图)。我确信OP没有展示他的真实代码——帖子中的代码也只是一个例子。@fortm是的,这种方法与命令设计模式有很多共同之处。我并没有把它称为命令设计模式,以避免对一个稍微简单的实现级技巧进行不必要的美化。@dasblinkenlight-我想知道类a是否是固定的,但类B是固定的。这只意味着我们需要使用固定源设置多个目标。在这种情况下,我是否应该有一个包装器类来屏蔽接口MyAction,使其不知道目标是类A1、类A2?因此接口MyAction变为-void设置字段(WrapperTArget obj,B obj2);原因是source@fortm接口完全由您决定。由于数字及其动作的配对是通过映射完成的,因此完全可以使用向上类型化的参数(即
java.lang.Object
)代替包装器,因为知道动作无论如何都会执行正确的强制转换。也可以将多个对象传递给
A
(我的意思是
a1a1、a2a2、a3a3
),并让操作有选择地选择要操作的
A
对象。其思想是将完整的上下文传递给
设置字段
方法;传递此上下文的具体方式完全取决于您。就可读性或可维护性而言,
开关
决不是对
if
序列的改进。性能是一个不同的关注点,但我非常确定OP非常清楚
开关的存在(
语句:)