From 2c8d1744df346ca87e8843580c72bb6126f0f15d Mon Sep 17 00:00:00 2001 From: nikhilbarar Date: Mon, 2 Jul 2018 00:42:04 +0530 Subject: [PATCH] #564: Collection Pipeline pattern --- collection-pipeline/README.md | 29 +++++++ .../etc/collection-pipeline.png | Bin 0 -> 14519 bytes .../etc/collection-pipeline.ucls | 62 ++++++++++++++ collection-pipeline/pom.xml | 45 ++++++++++ .../com/iluwatar/collectionpipeline/App.java | 60 +++++++++++++ .../com/iluwatar/collectionpipeline/Car.java | 56 ++++++++++++ .../FunctionalProgramming.java | 61 +++++++++++++ .../ImperativeProgramming.java | 80 ++++++++++++++++++ .../collectionpipeline/Iterating.java | 46 ++++++++++ .../iluwatar/collectionpipeline/AppTest.java | 50 +++++++++++ pom.xml | 1 + 11 files changed, 490 insertions(+) create mode 100644 collection-pipeline/README.md create mode 100644 collection-pipeline/etc/collection-pipeline.png create mode 100644 collection-pipeline/etc/collection-pipeline.ucls create mode 100644 collection-pipeline/pom.xml create mode 100644 collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/App.java create mode 100644 collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/Car.java create mode 100644 collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/FunctionalProgramming.java create mode 100644 collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/ImperativeProgramming.java create mode 100644 collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/Iterating.java create mode 100644 collection-pipeline/src/test/java/com/iluwatar/collectionpipeline/AppTest.java diff --git a/collection-pipeline/README.md b/collection-pipeline/README.md new file mode 100644 index 000000000..3599a6d5d --- /dev/null +++ b/collection-pipeline/README.md @@ -0,0 +1,29 @@ +--- +layout: pattern +title: Collection Pipeline +folder: collection-pipeline +permalink: /patterns/collection-pipeline/ +categories: Functional +tags: + - Java + - Difficulty-Beginner + - Functional +--- + +## Intent +Collection Pipeline introduces Function Composition and Collection Pipeline, two functional-style patterns that you can combine to iterate collections in your code. +In functional programming, it's common to sequence complex operations through a series of smaller modular functions or operations. The series is called a composition of functions, or a function composition. When a collection of data flows through a function composition, it becomes a collection pipeline. Function Composition and Collection Pipeline are two design patterns frequently used in functional-style programming. + +![alt text](./etc/collection-pipeline.png "Collection Pipeline") + +## Applicability +Use the Collection Pipeline pattern when + +* When you want to perform a sequence of operations where one operation's collected output is fed into the next +* When you use a lot of statements in your code +* When you use a lot of loops in your code + +## Credits + +* [Function composition and the Collection Pipeline pattern](https://www.ibm.com/developerworks/library/j-java8idioms2/index.html) +* [Martin Fowler](https://martinfowler.com/articles/collection-pipeline/) \ No newline at end of file diff --git a/collection-pipeline/etc/collection-pipeline.png b/collection-pipeline/etc/collection-pipeline.png new file mode 100644 index 0000000000000000000000000000000000000000..7fcdb0b9452a3c206443901ff3fc693f8ff58efb GIT binary patch literal 14519 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 literal 0 HcmV?d00001 diff --git a/collection-pipeline/etc/collection-pipeline.ucls b/collection-pipeline/etc/collection-pipeline.ucls new file mode 100644 index 000000000..676dc48e8 --- /dev/null +++ b/collection-pipeline/etc/collection-pipeline.ucls @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/collection-pipeline/pom.xml b/collection-pipeline/pom.xml new file mode 100644 index 000000000..a663fb35a --- /dev/null +++ b/collection-pipeline/pom.xml @@ -0,0 +1,45 @@ + + + 4.0.0 + + com.iluwatar + java-design-patterns + 1.20.0-SNAPSHOT + + collection-pipeline + + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.jupiter + junit-jupiter-engine + test + + + \ No newline at end of file diff --git a/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/App.java b/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/App.java new file mode 100644 index 000000000..109d60b88 --- /dev/null +++ b/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/App.java @@ -0,0 +1,60 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.collectionpipeline; + +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * In imperative-style programming, it is common to use for and while loops for + * most kinds of data processing. Function composition is a simple technique + * that lets you sequence modular functions to create more complex operations. + * When you run data through the sequence, you have a collection pipeline. + * Together, the Function Composition and Collection Pipeline patterns enable + * you to create sophisticated programs where data flow from upstream to + * downstream and is passed through a series of transformations. + * + */ +public class App { + + private static final Logger LOGGER = LoggerFactory.getLogger(App.class); + + /** + * Program entry point. + * + * @param args + * command line args + */ + public static void main(String[] args) { + + List cars = Iterating.createCars(); + + List modelsImperative = ImperativeProgramming.getModelsAfter2000UsingFor(cars); + LOGGER.info(modelsImperative.toString()); + + List modelsFunctional = FunctionalProgramming.getModelsAfter2000UsingPipeline(cars); + LOGGER.info(modelsFunctional.toString()); + } +} diff --git a/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/Car.java b/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/Car.java new file mode 100644 index 000000000..be113c7cd --- /dev/null +++ b/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/Car.java @@ -0,0 +1,56 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.collectionpipeline; + +/** + * A Car class that has the properties of make, model, and year. + */ +public class Car { + private String make; + private String model; + private int year; + + /** + * Constructor to create an instance of car. + * @param theMake the make of the car + * @param theModel the model of the car + * @param yearOfMake the year of built of the car + */ + public Car(String theMake, String theModel, int yearOfMake) { + make = theMake; + model = theModel; + year = yearOfMake; + } + + public String getMake() { + return make; + } + + public String getModel() { + return model; + } + + public int getYear() { + return year; + } +} \ No newline at end of file diff --git a/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/FunctionalProgramming.java b/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/FunctionalProgramming.java new file mode 100644 index 000000000..7d9834bc0 --- /dev/null +++ b/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/FunctionalProgramming.java @@ -0,0 +1,61 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.collectionpipeline; + +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Iterating and sorting with a collection pipeline + * + *

In functional programming, it's common to sequence complex operations through + * a series of smaller modular functions or operations. The series is called a + * composition of functions, or a function composition. When a collection of + * data flows through a function composition, it becomes a collection pipeline. + * Function Composition and Collection Pipeline are two design patterns + * frequently used in functional-style programming. + * + *

Instead of passing a lambda expression to the map method, we passed the + * method reference Car::getModel. Likewise, instead of passing the lambda + * expression car -> car.getYear() to the comparing method, we passed the method + * reference Car::getYear. Method references are short, concise, and expressive. + * It is best to use them wherever possible. + * + */ +public class FunctionalProgramming { + private FunctionalProgramming() { + } + + /** + * Method to get models using for collection pipeline. + * + * @param cars {@link List} of {@link Car} to be used for filtering + * @return {@link List} of {@link String} representing models built after year 2000 + */ + public static List getModelsAfter2000UsingPipeline(List cars) { + return cars.stream().filter(car -> car.getYear() > 2000) + .sorted(Comparator.comparing(Car::getYear)) + .map(Car::getModel).collect(Collectors.toList()); + } +} diff --git a/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/ImperativeProgramming.java b/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/ImperativeProgramming.java new file mode 100644 index 000000000..092469fbd --- /dev/null +++ b/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/ImperativeProgramming.java @@ -0,0 +1,80 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.collectionpipeline; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +/** + * Imperative-style programming to iterate over the list and get the names of + * cars made later than the year 2000. We then sort the models in ascending + * order by year. + * + *

As you can see, there's a lot of looping in this code. First, the + * getModelsAfter2000UsingFor method takes a list of cars as its parameter. It + * extracts or filters out cars made after the year 2000, putting them into a + * new list named carsSortedByYear. Next, it sorts that list in ascending order + * by year-of-make. Finally, it loops through the list carsSortedByYear to get + * the model names and returns them in a list. + * + *

This short example demonstrates what I call the effect of statements. While + * functions and methods in general can be used as expressions, the {@link Collections} + * sort method doesn't return a result. Because it is used as a statement, it + * mutates the list given as argument. Both of the for loops also mutate lists + * as they iterate. Being statements, that's just how these elements work. As a + * result, the code contains unnecessary garbage variables + */ +public class ImperativeProgramming { + private ImperativeProgramming() { + } + + /** + * Method to return the car models built after year 2000 using for loops. + * @param cars {@link List} of {@link Car} to iterate over + * @return {@link List} of {@link String} of car models built after year 2000 + */ + public static List getModelsAfter2000UsingFor(List cars) { + List carsSortedByYear = new ArrayList<>(); + + for (Car car : cars) { + if (car.getYear() > 2000) { + carsSortedByYear.add(car); + } + } + + Collections.sort(carsSortedByYear, new Comparator() { + public int compare(Car car1, Car car2) { + return new Integer(car1.getYear()).compareTo(car2.getYear()); + } + }); + + List models = new ArrayList<>(); + for (Car car : carsSortedByYear) { + models.add(car.getModel()); + } + + return models; + } +} diff --git a/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/Iterating.java b/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/Iterating.java new file mode 100644 index 000000000..4293603cb --- /dev/null +++ b/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/Iterating.java @@ -0,0 +1,46 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.collectionpipeline; + +import java.util.Arrays; +import java.util.List; + +/** + * A factory class to create a collection of {@link Car} instances. + */ +public class Iterating { + private Iterating() { + } + + /** + * Factory method to create a {@link List} of {@link Car} instances. + * @return {@link List} of {@link Car} + */ + public static List createCars() { + return Arrays.asList(new Car("Jeep", "Wrangler", 2011), new Car("Jeep", "Comanche", 1990), + new Car("Dodge", "Avenger", 2010), + new Car("Buick", "Cascada", 2016), + new Car("Ford", "Focus", 2012), + new Car("Chevrolet", "Geo Metro", 1992)); + } +} \ No newline at end of file diff --git a/collection-pipeline/src/test/java/com/iluwatar/collectionpipeline/AppTest.java b/collection-pipeline/src/test/java/com/iluwatar/collectionpipeline/AppTest.java new file mode 100644 index 000000000..26f546a16 --- /dev/null +++ b/collection-pipeline/src/test/java/com/iluwatar/collectionpipeline/AppTest.java @@ -0,0 +1,50 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.collectionpipeline; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Arrays; +import java.util.List; + +import org.junit.jupiter.api.Test; + +/** + * Tests that Collection Pipeline methods work as expected. + */ +public class AppTest { + + private List cars = Iterating.createCars(); + + @Test + public void testGetModelsAfter2000UsingFor() { + List models = ImperativeProgramming.getModelsAfter2000UsingFor(cars); + assertEquals(models, Arrays.asList("Avenger", "Wrangler", "Focus", "Cascada")); + } + + @Test + public void testGetModelsAfter2000UsingPipeline() { + List models = FunctionalProgramming.getModelsAfter2000UsingPipeline(cars); + assertEquals(models, Arrays.asList("Avenger", "Wrangler", "Focus", "Cascada")); + } +} diff --git a/pom.xml b/pom.xml index e1d025c13..9d2ca8066 100644 --- a/pom.xml +++ b/pom.xml @@ -161,6 +161,7 @@ dirty-flag trampoline serverless + collection-pipeline