Refactoring for DRY
Peter Levart
peter.levart at gmail.com
Tue Apr 9 05:08:00 PDT 2013
With some utilities like:
https://github.com/plevart/streamx/blob/master/main/src/si/pele/streamx/Streamable.java
The re-use can be accomplished in another fashion:
Streamable<Person> peoples = people::parallelStream;
Streamable<Person> filteredPeoples = peoples
.filter(p -> p.getAge() >= 12)
.filter(p -> p.getAge() < 65);
filteredPeoples.stream()
.forEach(p -> {
p.setPrice(9.25);
});
filteredPeoples.stream()
.filter(p -> p.hasCoupon())
.forEach(p -> {
p.setPrice(p.getPrice() - 2.00);
});
Regards, Peter
On 04/09/2013 12:59 PM, Peter Levart wrote:
> 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