Skip to content

Commit b483bd8

Browse files
committed
docs: collection pipeline
1 parent 80ae1a9 commit b483bd8

File tree

4 files changed

+33
-138
lines changed

4 files changed

+33
-138
lines changed

collection-pipeline/README.md

Lines changed: 33 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ title: Collection Pipeline
33
category: Functional
44
language: en
55
tag:
6-
- Reactive
6+
- Functional decomposition
77
- Data processing
8+
- Data transformation
9+
- Reactive
810
---
911

1012
## Intent
@@ -15,7 +17,7 @@ The Collection Pipeline design pattern is intended to process collections of dat
1517

1618
Real-world example
1719

18-
> Imagine you're in a large library filled with books, and you're tasked with finding all the science fiction books published after 2000, then arranging them by author name in alphabetical order, and finally picking out the top 5 based on their popularity or ratings.
20+
> Imagine a real-world example of a factory assembly line for manufacturing cars. In this assembly line, each station performs a specific task on the car chassis, such as installing the engine, painting the body, attaching the wheels, and inspecting the final product. Each station takes the output from the previous station and adds its own processing step. This sequence of operations is analogous to the Collection Pipeline design pattern, where each step in the pipeline transforms the data and passes it on to the next step, ensuring an efficient and organized workflow.
1921
2022
In plain words
2123

@@ -27,63 +29,56 @@ Wikipedia says
2729
2830
**Programmatic Example**
2931

30-
The Collection Pipeline pattern is implemented in this code example by using Java's Stream API to perform a series of transformations on a collection of Car objects. The transformations are chained together to form a pipeline. Here's a breakdown of how it's done:
31-
32-
1. Creation of Cars: A list of Car objects is created using the `CarFactory.createCars()` method.
32+
The Collection Pipeline is a programming pattern where you organize some computation as a sequence of operations which compose by taking a collection as output of one operation and feeding it into the next.
3333

34-
`var cars = CarFactory.createCars();`
34+
Here's a programmatic example of the Collection Pipeline design pattern:
3535

36-
2. Filtering and Transforming: The `FunctionalProgramming.getModelsAfter2000(cars)` method filters the cars to only include those made after the year 2000, and then transforms the filtered cars into a list of their model names.
36+
**Step 1: Filtering**
3737

38-
`var modelsFunctional = FunctionalProgramming.getModelsAfter2000(cars);`
39-
40-
In the `getModelsAfter2000` method, the pipeline is created as follows:
38+
We start with a list of `Car` objects and we want to filter out those that were manufactured after the year 2000. This is done using the `stream()` method to create a stream from the list, the `filter()` method to filter out the cars we want, and the `collect()` method to collect the results into a new list.
4139

4240
```java
4341
public static List<String> getModelsAfter2000(List<Car> cars){
44-
return cars.stream().filter(car->car.getYear()>2000)
45-
.sorted(comparing(Car::getYear))
46-
.map(Car::getModel)
47-
.collect(toList());
48-
}
42+
return cars.stream()
43+
.filter(car -> car.getYear() > 2000) // Filter cars manufactured after 2000
44+
.sorted(comparing(Car::getYear)) // Sort the cars by year
45+
.map(Car::getModel) // Get the model of each car
46+
.collect(toList()); // Collect the results into a new list
47+
}
4948
```
5049

51-
3. Grouping: The `FunctionalProgramming.getGroupingOfCarsByCategory(cars)` method groups the cars by their category.
52-
53-
`var groupingByCategoryFunctional = FunctionalProgramming.getGroupingOfCarsByCategory(cars);`
50+
**Step 2: Grouping**
5451

55-
In the getGroupingOfCarsByCategory method, the pipeline is created as follows:
52+
Next, we want to group the cars by their category. This is done using the `groupingBy()` collector.
5653

5754
```java
58-
public static Map<Category, List<Car>>getGroupingOfCarsByCategory(List<Car> cars){
59-
return cars.stream().collect(groupingBy(Car::getCategory));
60-
}
55+
public static Map<Category, List<Car>> getGroupingOfCarsByCategory(List<Car> cars){
56+
return cars.stream()
57+
.collect(groupingBy(Car::getCategory)); // Group cars by category
58+
}
6159
```
6260

63-
4. Filtering, Sorting and Transforming: The `FunctionalProgramming.getSedanCarsOwnedSortedByDate(List.of(john))` method filters the cars owned by a person to only include sedans, sorts them by date, and then transforms the sorted cars into a list of Car objects.
61+
**Step 3: Filtering, Sorting and Transforming**
6462

65-
`var sedansOwnedFunctional = FunctionalProgramming.getSedanCarsOwnedSortedByDate(List.of(john));`
66-
67-
In the `getSedanCarsOwnedSortedByDate` method, the pipeline is created as follows:
63+
Finally, we want to filter the cars owned by a person to only include sedans, sort them by date, and then transform the sorted cars into a list of `Car` objects.
6864

6965
```java
7066
public static List<Car> getSedanCarsOwnedSortedByDate(List<Person> persons){
71-
return persons.stream().flatMap(person->person.getCars().stream())
72-
.filter(car->Category.SEDAN.equals(car.getCategory()))
73-
.sorted(comparing(Car::getDate))
74-
.collect(toList());
75-
}
67+
return persons.stream()
68+
.flatMap(person -> person.getCars().stream()) // Flatten the list of cars owned by each person
69+
.filter(car -> Category.SEDAN.equals(car.getCategory())) // Filter to only include sedans
70+
.sorted(comparing(Car::getDate)) // Sort the cars by date
71+
.collect(toList()); // Collect the results into a new list
72+
}
7673
```
7774

7875
In each of these methods, the Collection Pipeline pattern is used to perform a series of operations on the collection of cars in a declarative manner, which improves readability and maintainability.
7976

80-
## Class diagram
81-
82-
![alt text](./etc/collection-pipeline.png "Collection Pipeline")
83-
8477
## Applicability
8578

86-
This pattern is applicable in scenarios involving bulk data operations such as filtering, mapping, sorting, or reducing collections. It's particularly useful in data analysis, transformation tasks, and where a sequence of operations needs to be applied to each element of a collection.
79+
* When you need to perform a series of transformations on a collection of data.
80+
* When you want to improve readability and maintainability of complex data processing code.
81+
* When working with large datasets where intermediate results should not be stored in memory.
8782

8883
## Known Uses
8984

@@ -115,9 +110,7 @@ Trade-offs:
115110

116111
## Credits
117112

118-
* [Function composition and the Collection Pipeline pattern](https://www.ibm.com/developerworks/library/j-java8idioms2/index.html)
119-
* [Collection Pipeline described by Martin Fowler](https://martinfowler.com/articles/collection-pipeline/)
120-
* [Java8 Streams](https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html)
121-
* [Refactoring: Improving the Design of Existing Code](https://amzn.to/3VDMWDO)
122113
* [Functional Programming in Scala](https://amzn.to/4cEo6K2)
123114
* [Java 8 in Action: Lambdas, Streams, and functional-style programming](https://amzn.to/3THp4wy)
115+
* [Refactoring: Improving the Design of Existing Code](https://amzn.to/3VDMWDO)
116+
* [Collection Pipeline (Martin Fowler)](https://martinfowler.com/articles/collection-pipeline/)
-26.6 KB
Binary file not shown.

collection-pipeline/etc/collection-pipeline.ucls

Lines changed: 0 additions & 98 deletions
This file was deleted.
Loading

0 commit comments

Comments
 (0)