From 689486267d975dd9d40932d1f431e85ee73c4dd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Thu, 23 Jul 2020 18:53:47 +0300 Subject: [PATCH] #590 add explanation to Pipeline --- pipeline/README.md | 88 +++++++++++++++++-- .../main/java/com/iluwatar/pipeline/App.java | 3 +- 2 files changed, 84 insertions(+), 7 deletions(-) diff --git a/pipeline/README.md b/pipeline/README.md index bc8f9399a..fd03cd7b9 100644 --- a/pipeline/README.md +++ b/pipeline/README.md @@ -9,7 +9,83 @@ tags: --- ## Intent -Allows processing of data in a series of stages by giving in an initial input and passing the processed output to be used by the next stages. +Allows processing of data in a series of stages by giving in an initial input and passing the processed output to be +used by the next stages. + +## Explanation + +The Pipeline pattern uses ordered stages to process a sequence of input values. Each implemented task is represented by +a stage of the pipeline. You can think of pipelines as similar to assembly lines in a factory, where each item in the +assembly line is constructed in stages. The partially assembled item is passed from one assembly stage to another. The +outputs of the assembly line occur in the same order as that of the inputs. + +Real world example + +> Suppose we wanted to pass through a string to a series of filtering stages and convert it as a char array on the last stage. + +In plain words + +> Pipeline pattern is an assembly line where partial results are passed from one stage to another. + +Wikipedia says + +> In software engineering, a pipeline consists of a chain of processing elements (processes, threads, coroutines, functions, etc.), arranged so that the output of each element is the input of the next; the name is by analogy to a physical pipeline. + +**Programmatic Example** + +The stages of our pipeline are called `Handler`s. + +```java +interface Handler { + O process(I input); +} +``` + +In our string processing example we have 3 different concrete `Handler`s. + +```java +class RemoveAlphabetsHandler implements Handler { + ... +} + +class RemoveDigitsHandler implements Handler { + ... +} + +class ConvertToCharArrayHandler implements Handler { + ... +} +``` + +Here is the `Pipeline` that will gather and execute the handlers one by one. + +```java +class Pipeline { + + private final Handler currentHandler; + + Pipeline(Handler currentHandler) { + this.currentHandler = currentHandler; + } + + Pipeline addHandler(Handler newHandler) { + return new Pipeline<>(input -> newHandler.process(currentHandler.process(input))); + } + + O execute(I input) { + return currentHandler.process(input); + } +} +``` + +And here's the `Pipeline` in action processing the string. + +```java + var filters = new Pipeline<>(new RemoveAlphabetsHandler()) + .addHandler(new RemoveDigitsHandler()) + .addHandler(new ConvertToCharArrayHandler()); + filters.execute("GoYankees123!"); +``` ## Class diagram ![alt text](./etc/pipeline.urm.png "Pipeline pattern class diagram") @@ -21,16 +97,16 @@ Use the Pipeline pattern when you want to * Add readability to complex sequence of operations by providing a fluent builder as an interface * Improve testability of code since stages will most likely be doing a single thing, complying to the [Single Responsibility Principle (SRP)](https://java-design-patterns.com/principles/#single-responsibility-principle) -## Typical Use Case - -* Implement stages and execute them in an ordered manner - -## Real world examples +## Known uses * [java.util.Stream](https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html) * [Maven Build Lifecycle](http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html) * [Functional Java](https://github.com/functionaljava/functionaljava) +## Related patterns + +* [Chain of Responsibility](https://java-design-patterns.com/patterns/chain/) + ## Credits * [The Pipeline Pattern — for fun and profit](https://medium.com/@aaronweatherall/the-pipeline-pattern-for-fun-and-profit-9b5f43a98130) diff --git a/pipeline/src/main/java/com/iluwatar/pipeline/App.java b/pipeline/src/main/java/com/iluwatar/pipeline/App.java index 1b1e443e6..cfbcbafc2 100644 --- a/pipeline/src/main/java/com/iluwatar/pipeline/App.java +++ b/pipeline/src/main/java/com/iluwatar/pipeline/App.java @@ -59,8 +59,9 @@ public class App { then is expected to receive an input of char[] array since that is the type being returned by the previous handler, ConvertToCharArrayHandler. */ - new Pipeline<>(new RemoveAlphabetsHandler()) + var filters = new Pipeline<>(new RemoveAlphabetsHandler()) .addHandler(new RemoveDigitsHandler()) .addHandler(new ConvertToCharArrayHandler()); + filters.execute("GoYankees123!"); } }