在列表上迭代应用操作直到稳定时减少Java代码重复



我正在尝试减少java代码中的代码重复。我不是java专家,所以我可能遗漏了一些基本的东西。目标是通过几个操作符对列表进行操作,foo1, foo2, ..., fooN.

每个操作迭代,直到列表稳定(不再被操作改变)。每个操作都由向前传递和向后传递组成。传递是一样的,只是列表颠倒了。每次传递也会迭代,直到列表稳定下来。按顺序应用操作符很重要,这会导致令人沮丧的代码重复。

下面是一些伪java,展示了它目前是如何完成的。注意:这里的foo操作试图修改列表arg1;当(且仅当)arg1发生修改时,它们返回true。

reduceByFoo1(arg1,arg2,arg3){
doUpdate = true;
while(doUpdate) {
doUpdate = false;
doPass = true;
while(doPass) {
doPass = foo1(arg1,arg2,arg3);
doUpdate |= doPass;
}
Collections.reverse(arg1);
doPass = true;
while(doPass) {
doPass = foo1(arg1,arg2,arg3);
doUpdate |= doPass;
}
Collections.reverse(arg1);
}
}
reduceByFoo2(arg1,arg2,arg3){
...same code as above, but with foo2..
}
reduceByFoo2(arg1,arg2,arg3){
...same code as above, but with foo3..
}
...and so on...

减少重复或改进设计模式的好方法是什么?

编辑:使用公认的答案,这大致就是我最终得到的代码。现在好多了:

interface Foo {boolean bar(arg1, arg2, arg3);}
fooUntilStable(foo, arg1, arg2, arg3) = {
iterate = true;
updated = false;
while(iterate) {
iterate = foo.bar(arg1, arg2, arg3);
updated |= iterate;
}
return updated;
}
biFooUntilStable(foo, arg1, arg2, arg3){
Foo biFoo = (a1, a2, a3) -> {
updated = fooUntilStable(foo, a1, a2, a3);
Collections.reverse(a1);
updated |= fooUntilStable(foo, a1, a2, a3);
Collections.reverse(a1);
return updated;
}
fooUntilStable(biFoo,arg1,arg2,arg3);
}
Foo foo1 = (arg1,arg2,arg3) -> {...}
Foo foo2 = (arg1,arg2,arg3) -> {...}
...
Foo fooN = (arg1,arg2,arg3) -> {...}
biFooUntilStable(foo1,arg1,arg2,arg3);
biFooUntilStable(foo2,arg1,arg2,arg3);
...
biFooUntilStable(fooN,arg1,arg2,arg3);

我处理功能相同但略有不同的函数的方式如下:

reduceByFoo1(arg1,arg2,arg3){
// do common operation
foo1(arg1, arg2, arg3);
// do stuff
}

reduceByFoo2(arg1,arg2,arg3){
// do common operation
foo2(arg1, arg2, arg3);
// do stuff
}

在其他编程语言中,我们可以将函数作为参数传递,但Java略有不同。查看这篇文章来传递方法作为参数。

但是我要做的是:

public void reduce(arg1, arg2, arg3, someFunc) {
// do common operation
someFunc(arg1, arg2, arg3);
// do common operation
}

基于上述SO帖子的信息。

,你可以用指定的函数调用reduce:

reduceByFoo1(arg1,arg2,arg3){
// do common operation
reduce(arg1, arg2, arg3, foo1);
// do stuff
}

reduceByFoo2(arg1,arg2,arg3){
// do common operation
reduce(arg1, arg2, arg3, foo2);
// do stuff
}

编辑补充:这篇文章的其他想法可能更适合你的要求。

最新更新