Refactoring for DRY
Peter Levart
peter.levart at gmail.com
Tue Apr 9 03:59:52 PDT 2013
On 04/09/2013 01:35 AM, Barry Burd wrote:
> The following code seems very repetitious to me. Ss there a recommended way to refactor this code?
>
> people.parallelStream()
> .filter(p -> p.getAge() >= 12)
> .filter(p -> p.getAge() < 65)
> .forEach(p -> {
> p.setPrice(9.25);
> });
>
> people.parallelStream()
> .filter(p -> p.getAge() >= 12)
> .filter(p -> p.getAge() < 65)
> .filter(p -> p.hasCoupon())
> .forEach(p -> {
> p.setPrice(p.getPrice() - 2.00);
> });
>
> people.parallelStream()
> .filter(p -> (p.getAge() < 12 || p.getAge() >= 65))
> .forEach(p -> {
> p.setPrice(5.25);
> });
>
> people.stream()
> .forEach(p -> {
> p.display();
> });
>
> people.stream().map(p -> p.getPrice()).forEach(amount -> total += amount);
>
It depends what DRY means: Don't repead yourself (dont write exact same
code twice or more times) or Don't make CPU repeat itself (don't make
CPU execute the same code twice or more times unless it's necessary).
For the 1st DRY meaning (and I don't mean the 2nd is less important),
you could "capture" the code into a reusable block:
UnaryOperator<Stream<Person>> commonOps = (stream) ->
stream
.filter(p -> p.getAge() >= 12)
.filter(p -> p.getAge() < 65);
commonOps
.apply(people.parallelStream())
.forEach(p -> {
p.setPrice(9.25);
});
commonOps
.apply(people.parallelStream())
.filter(p -> p.hasCoupon())
.forEach(p -> {
p.setPrice(p.getPrice() - 2.00);
});
...
The above works, but would look fancier if j.u.s.Stream implemented the
following default methods:
default <U> Stream<U> transform(Function<Stream<T>, Stream<U>>
function) {
return function.apply(this);
}
default DoubleStream transformToDouble(Function<Stream<T>,
DoubleStream> function) {
return function.apply(this);
}
default LongStream transformToLong(Function<Stream<T>, LongStream>
function) {
return function.apply(this);
}
default IntStream transformToInt(Function<Stream<T>, IntStream>
function) {
return function.apply(this);
}
With those methods, you could write:
UnaryOperator<Stream<Person>> commonOps = (stream) ->
stream
.filter(p -> p.getAge() >= 12)
.filter(p -> p.getAge() < 65);
people.parallelStream()
.transform(commonOps)
.forEach(p -> {
p.setPrice(9.25);
});
people.parallelStream()
.transform(commonOps)
.filter(p -> p.hasCoupon())
.forEach(p -> {
p.setPrice(p.getPrice() - 2.00);
});
Regards, Peter
More information about the lambda-dev
mailing list