I am attempting to reduce code duplication in my java code. I am not a java expert, so I might be missing something basic. The goal is to operate on a list via several operators, foo1, foo2, ..., fooN
.
Each operation is iterated until the list stabilizes (no longer changes by the operation). Each operation consists of a forward pass, and then a backwards pass. The passes are the same, just the list is reversed. Each pass is also iterated until the list stabilizes. It's important that the operators are applied sequentially, resulting in frustrating code duplication.
Below is some pseudo-java showing how it is currently done. Note: the foo
operations here attempt to modify list arg1
; they return true if (and only if) a modification to arg1
occurred.
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...
What might be a good way to reduce duplication or improve the design pattern?
EDIT: Using the accepted answer, this is roughly the code I ended up with. Much better now:
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);