Repository: iluwatar/java-design-patterns
Issue: Collecting Parameter pattern
Labels: epic: pattern
type: feature

https://wiki.c2.com/?CollectingParameter

Issue comments:
Hello, I would like to work on this issue. I manage to finish it within a month.
Great to have you onboarded @santyelegy!

We are expecting the PR for this by the end of May '21
Hey @iluwatar, may I please pick up on this issue? I am interested in working on this.
Ok @JoshuaSinglaANU 
@iluwatar I am almost ready to make a PR, however, the automatic class diagram generation isn't working on my end. I have updated the parent pom.xml file to include my work and locally installed PlantUML, yet still, no class diagram is made. The wiki does not give much detail either. May I please know how to have this feature work?
UML diagram added.

Pull request review comments:
Check out yaml frontmatter requirements at https://github.com/iluwatar/java-design-patterns/wiki/01.-How-to-contribute
I suggest category `Idiom` and tags `Generic`. See https://github.com/iluwatar/java-design-patterns/wiki/07.-Categories-and-Tags
```suggestion
## Name
```
```suggestion
In the Collecting Parameter idiom a collection (list, map, etc.) is passed repeatedly as a parameter to a method which adds items to the collection.
```
This part is already defined in the parent pom.xml and shouldn't normally need any additional configuration here
Add comments to this part as well
Fixed now.
Fixed now.
Fixed now.
Fixed now.
Fixed now.

Patch that resolved the issue:
diff --git a/collecting-parameter/README.md b/collecting-parameter/README.md
new file mode 100644
index 000000000000..a57b8d2991da
--- /dev/null
+++ b/collecting-parameter/README.md
@@ -0,0 +1,197 @@
+---
+title: Collecting Parameter 
+category: Idiom
+language: en
+tags:
+- Generic
+---
+
+## Name
+Collecting Parameter
+
+## Intent
+To store the collaborative result of numerous methods within a collection.
+
+## Explanation
+### Real-world example
+Within a large corporate building, there exists a global printer queue that is a collection of all the printing jobs
+that are currently pending. Various floors contain different models of printers, each having a different printing
+policy. We must construct a program that can continually add appropriate printing jobs to a collection, which is called the *collecting parameter*.
+
+### In plain words
+Instead of having one giant method that contains numerous policies for collecting information into a variable, we can
+create numerous smaller functions that each take parameter, and append new information. We can pass the parameter to
+all of these smaller functions and by the end, we will have what we wanted originally. This time, the code is cleaner
+and easier to understand. Because the larger function has been broken down, the code is also easier to modify as changes
+are localised to the smaller functions.
+
+### Wikipedia says
+In the Collecting Parameter idiom a collection (list, map, etc.) is passed repeatedly as a parameter to a method which adds items to the collection.
+
+### Programmatic example
+Coding our example from above, we may use the collection `result` as a collecting parameter. The following restrictions
+are implemented:
+- If an A4 paper is coloured, it must also be single-sided. All other non-coloured papers are accepted
+- A3 papers must be non-coloured and single-sided
+- A2 papers must be single-page, single-sided, and non-coloured
+
+```java
+package com.iluwatar.collectingparameter;
+import java.util.LinkedList;
+import java.util.Queue;
+public class App {
+  static PrinterQueue printerQueue = PrinterQueue.getInstance();
+
+  /**
+   * Program entry point.
+   *
+   * @param args command line args
+   */
+  public static void main(String[] args) {
+    /*
+      Initialising the printer queue with jobs
+    */
+    printerQueue.addPrinterItem(new PrinterItem(PaperSizes.A4, 5, false, false));
+    printerQueue.addPrinterItem(new PrinterItem(PaperSizes.A3, 2, false, false));
+    printerQueue.addPrinterItem(new PrinterItem(PaperSizes.A2, 5, false, false));
+
+    /*
+      This variable is the collecting parameter.
+    */    
+    var result = new LinkedList<PrinterItem>();
+
+    /* 
+     * Using numerous sub-methods to collaboratively add information to the result collecting parameter
+     */
+    addA4Papers(result);
+    addA3Papers(result);
+    addA2Papers(result);
+  }
+}
+```
+
+We use the `addA4Paper`, `addA3Paper`, and `addA2Paper` methods to populate the `result` collecting parameter with the
+appropriate print jobs as per the policy described previously. The three policies are encoded below,
+
+```java
+public class App {
+  static PrinterQueue printerQueue = PrinterQueue.getInstance();
+  /**
+   * Adds A4 document jobs to the collecting parameter according to some policy that can be whatever the client
+   * (the print center) wants.
+   *
+   * @param printerItemsCollection the collecting parameter
+   */
+  public static void addA4Papers(Queue<PrinterItem> printerItemsCollection) {
+    /*
+      Iterate through the printer queue, and add A4 papers according to the correct policy to the collecting parameter,
+      which is 'printerItemsCollection' in this case.
+     */
+    for (PrinterItem nextItem : printerQueue.getPrinterQueue()) {
+      if (nextItem.paperSize.equals(PaperSizes.A4)) {
+        var isColouredAndSingleSided = nextItem.isColour && !nextItem.isDoubleSided;
+        if (isColouredAndSingleSided) {
+          printerItemsCollection.add(nextItem);
+        } else if (!nextItem.isColour) {
+          printerItemsCollection.add(nextItem);
+        }
+      }
+    }
+  }
+
+  /**
+   * Adds A3 document jobs to the collecting parameter according to some policy that can be whatever the client
+   * (the print center) wants. The code is similar to the 'addA4Papers' method. The code can be changed to accommodate
+   * the wants of the client.
+   *
+   * @param printerItemsCollection the collecting parameter
+   */
+  public static void addA3Papers(Queue<PrinterItem> printerItemsCollection) {
+    for (PrinterItem nextItem : printerQueue.getPrinterQueue()) {
+      if (nextItem.paperSize.equals(PaperSizes.A3)) {
+
+        // Encoding the policy into a Boolean: the A3 paper cannot be coloured and double-sided at the same time
+        var isNotColouredAndSingleSided = !nextItem.isColour && !nextItem.isDoubleSided;
+        if (isNotColouredAndSingleSided) {
+          printerItemsCollection.add(nextItem);
+        }
+      }
+    }
+  }
+
+  /**
+   * Adds A2 document jobs to the collecting parameter according to some policy that can be whatever the client
+   * (the print center) wants. The code is similar to the 'addA4Papers' method. The code can be changed to accommodate
+   * the wants of the client.
+   *
+   * @param printerItemsCollection the collecting parameter
+   */
+  public static void addA2Papers(Queue<PrinterItem> printerItemsCollection) {
+    for (PrinterItem nextItem : printerQueue.getPrinterQueue()) {
+      if (nextItem.paperSize.equals(PaperSizes.A2)) {
+
+        // Encoding the policy into a Boolean: the A2 paper must be single page, single-sided, and non-coloured.
+        var isNotColouredSingleSidedAndOnePage = nextItem.pageCount == 1 && !nextItem.isDoubleSided
+                && !nextItem.isColour;
+        if (isNotColouredSingleSidedAndOnePage) {
+          printerItemsCollection.add(nextItem);
+        }
+      }
+    }
+  }
+}
+```
+
+Each method takes a collecting parameter as an argument. It then adds elements, taken from a global variable,
+to this collecting parameter if each element satisfies a given criteria. These methods can have whatever policy the client desires.
+
+In this programmatic example, three print jobs are added to the queue. Only the first two print jobs should be added to
+the collecting parameter as per the policy. The elements of the `result` variable after execution are,
+
+| paperSize | pageCount | isDoubleSided | isColour |
+|-----------|-----------|---------------|----------|
+| A4        | 5         | false         | false    |
+| A3        | 2         | false         | false    |
+
+which is what we expected.
+
+## Class diagram
+![alt text](./etc/collecting-parameter.urm.png "Collecting Parameter")
+
+## Applicability
+Use the Collecting Parameter design pattern when
+- you want to return a collection or object that is the collaborative result of several methods
+- You want to simplify a method that accumulates data as the original method is too complex
+
+## Tutorials
+Tutorials for this method are found in:
+- [Refactoring To Patterns](http://www.tarrani.net/RefactoringToPatterns.pdf)  by Joshua Kerivsky
+- [Smalltalk Best Practice Patterns](https://ptgmedia.pearsoncmg.com/images/9780134769042/samplepages/013476904X.pdf)  by Kent Beck
+
+## Known uses
+Joshua Kerivsky gives a real-world example in his book 'Refactoring to Patterns'. He gives an example of using the
+Collecting Parameter Design Pattern to create a `toString()` method for an XML tree. Without using this design pattern,
+this would require a bulky function with conditionals and concatenation that would worsen code readability. Such a method
+can be broken down into smaller methods, each appending their own set of information to the collecting parameter.
+
+See this in [Refactoring To Patterns](http://www.tarrani.net/RefactoringToPatterns.pdf).
+
+## Consequences
+Pros:
+- Makes code more readable
+- Avoids 'linkages', where numerous methods reference the same global variable
+- Increases maintainability by decomposing larger functions
+
+Cons:
+- May increase code length
+- Adds 'layers' of methods
+
+## Related patterns
+- [Compose Methods](https://www.geeksforgeeks.org/composite-design-pattern/)
+
+## Credits
+Following books were used:
+- [Refactoring To Patterns](http://www.tarrani.net/RefactoringToPatterns.pdf)  by Joshua Kerivsky
+- [Smalltalk Best Practice Patterns](https://ptgmedia.pearsoncmg.com/images/9780134769042/samplepages/013476904X.pdf)  by Kent Beck
+Sites:
+- [Wiki](https://wiki.c2.com/?CollectingParameter)
diff --git a/collecting-parameter/etc/collecting-parameter.urm.puml b/collecting-parameter/etc/collecting-parameter.urm.puml
new file mode 100644
index 000000000000..06320fa022ee
--- /dev/null
+++ b/collecting-parameter/etc/collecting-parameter.urm.puml
@@ -0,0 +1,39 @@
+@startuml
+package com.iluwatar.collectingparameter {
+  class App {
+    ~ printerQueue : PrinterQueue {static}
+    + App()
+    + addValidA2Papers(printerItemsCollection : Queue<PrinterItem>) {static}
+    + addValidA3Papers(printerItemsCollection : Queue<PrinterItem>) {static}
+    + addValidA4Papers(printerItemsCollection : Queue<PrinterItem>) {static}
+    + main(args : String[]) {static}
+  }
+  ~enum PaperSizes {
+    + A2 {static}
+    + A3 {static}
+    + A4 {static}
+    + valueOf(name : String) : PaperSizes {static}
+    + values() : PaperSizes[] {static}
+  }
+  class PrinterItem {
+    ~ isColour : boolean
+    ~ isDoubleSided : boolean
+    ~ pageCount : int
+    ~ paperSize : PaperSizes
+    + PrinterItem(paperSize : PaperSizes, pageCount : int, isDoubleSided : boolean, isColour : boolean)
+  }
+  class PrinterQueue {
+    ~ currentInstance : PrinterQueue {static}
+    - printerItemQueue : Queue<PrinterItem>
+    - PrinterQueue()
+    + addPrinterItem(printerItem : PrinterItem)
+    + emptyQueue()
+    + getInstance() : PrinterQueue {static}
+    + getPrinterQueue() : Queue<PrinterItem>
+  }
+}
+PrinterQueue -->  "-currentInstance" PrinterQueue
+PrinterQueue -->  "-printerItemQueue" PrinterItem
+App -->  "-printerQueue" PrinterQueue
+PrinterItem -->  "-paperSize" PaperSizes
+@enduml
\ No newline at end of file
diff --git a/collecting-parameter/pom.xml b/collecting-parameter/pom.xml
new file mode 100644
index 000000000000..8f7fdc2b52db
--- /dev/null
+++ b/collecting-parameter/pom.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
+
+    The MIT License
+    Copyright © 2014-2022 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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>java-design-patterns</artifactId>
+        <groupId>com.iluwatar</groupId>
+        <version>1.26.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>collecting-parameter</artifactId>
+    <dependencies>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-engine</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <configuration>
+                            <archive>
+                                <manifest>
+                                    <mainClass>com.iluwatar.collectingparameter.App</mainClass>
+                                </manifest>
+                            </archive>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/collecting-parameter/src/main/java/com/iluwatar/collectingparameter/App.java b/collecting-parameter/src/main/java/com/iluwatar/collectingparameter/App.java
new file mode 100644
index 000000000000..93ead620da95
--- /dev/null
+++ b/collecting-parameter/src/main/java/com/iluwatar/collectingparameter/App.java
@@ -0,0 +1,138 @@
+/*
+ * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
+ *
+ * The MIT License
+ * Copyright © 2014-2022 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.collectingparameter;
+
+import java.util.LinkedList;
+import java.util.Queue;
+
+/**
+ * The Collecting Parameter Design Pattern aims to return a result that is the collaborative result of several
+ * methods. This design pattern uses a 'collecting parameter' that is passed to several functions, accumulating results
+ * as it travels from method-to-method. This is different to the Composed Method design pattern, where a single
+ * collection is modified via several methods.
+ *
+ * <p>This example is inspired by Kent Beck's example in his book, 'Smalltalk Best Practice Patterns'. The context for this
+ * situation is that there is a single printer queue {@link PrinterQueue} that holds numerous print jobs
+ * {@link PrinterItem} that must be distributed to various print centers.
+ * Each print center has its own requirements and printing limitations. In this example, the following requirements are:
+ * If an A4 document is coloured, it must also be single-sided. All other non-coloured A4 documents are accepted.
+ * All A3 documents must be non-coloured and single sided. All A2 documents must be a single page, single sided, and
+ * non-coloured.
+ *
+ * <p>A collecting parameter (the result variable) is used to filter the global printer queue so that it meets the
+ * requirements for this centre,
+ **/
+
+public class App {
+  static PrinterQueue printerQueue = PrinterQueue.getInstance();
+
+  /**
+   * Program entry point.
+   *
+   * @param args command line args
+   */
+  public static void main(String[] args) {
+    /*
+      Initialising the printer queue with jobs
+    */
+    printerQueue.addPrinterItem(new PrinterItem(PaperSizes.A4, 5, false, false));
+    printerQueue.addPrinterItem(new PrinterItem(PaperSizes.A3, 2, false, false));
+    printerQueue.addPrinterItem(new PrinterItem(PaperSizes.A2, 5, false, false));
+
+    /*
+      This variable is the collecting parameter, and will store the policy abiding print jobs.
+    */
+    var result = new LinkedList<PrinterItem>();
+
+    /*
+      Adding A4, A3, and A2 papers that obey the policy
+    */
+    addValidA4Papers(result);
+    addValidA3Papers(result);
+    addValidA2Papers(result);
+  }
+
+  /**
+   * Adds A4 document jobs to the collecting parameter according to some policy that can be whatever the client
+   * (the print center) wants.
+   *
+   * @param printerItemsCollection the collecting parameter
+   */
+  public static void addValidA4Papers(Queue<PrinterItem> printerItemsCollection) {
+    /*
+      Iterate through the printer queue, and add A4 papers according to the correct policy to the collecting parameter,
+      which is 'printerItemsCollection' in this case.
+     */
+    for (PrinterItem nextItem : printerQueue.getPrinterQueue()) {
+      if (nextItem.paperSize.equals(PaperSizes.A4)) {
+        var isColouredAndSingleSided = nextItem.isColour && !nextItem.isDoubleSided;
+        if (isColouredAndSingleSided || !nextItem.isColour) {
+          printerItemsCollection.add(nextItem);
+        }
+      }
+    }
+  }
+
+  /**
+   * Adds A3 document jobs to the collecting parameter according to some policy that can be whatever the client
+   * (the print center) wants. The code is similar to the 'addA4Papers' method. The code can be changed to accommodate
+   * the wants of the client.
+   *
+   * @param printerItemsCollection the collecting parameter
+   */
+  public static void addValidA3Papers(Queue<PrinterItem> printerItemsCollection) {
+    for (PrinterItem nextItem : printerQueue.getPrinterQueue()) {
+      if (nextItem.paperSize.equals(PaperSizes.A3)) {
+
+        // Encoding the policy into a Boolean: the A3 paper cannot be coloured and double-sided at the same time
+        var isNotColouredAndSingleSided = !nextItem.isColour && !nextItem.isDoubleSided;
+        if (isNotColouredAndSingleSided) {
+          printerItemsCollection.add(nextItem);
+        }
+      }
+    }
+  }
+
+  /**
+   * Adds A2 document jobs to the collecting parameter according to some policy that can be whatever the client
+   * (the print center) wants. The code is similar to the 'addA4Papers' method. The code can be changed to accommodate
+   * the wants of the client.
+   *
+   * @param printerItemsCollection the collecting parameter
+   */
+  public static void addValidA2Papers(Queue<PrinterItem> printerItemsCollection) {
+    for (PrinterItem nextItem : printerQueue.getPrinterQueue()) {
+      if (nextItem.paperSize.equals(PaperSizes.A2)) {
+
+        // Encoding the policy into a Boolean: the A2 paper must be single page, single-sided, and non-coloured.
+        var isNotColouredSingleSidedAndOnePage = nextItem.pageCount == 1 && !nextItem.isDoubleSided
+                && !nextItem.isColour;
+        if (isNotColouredSingleSidedAndOnePage) {
+          printerItemsCollection.add(nextItem);
+        }
+      }
+    }
+  }
+}
diff --git a/collecting-parameter/src/main/java/com/iluwatar/collectingparameter/PaperSizes.java b/collecting-parameter/src/main/java/com/iluwatar/collectingparameter/PaperSizes.java
new file mode 100644
index 000000000000..352bf3cc241a
--- /dev/null
+++ b/collecting-parameter/src/main/java/com/iluwatar/collectingparameter/PaperSizes.java
@@ -0,0 +1,7 @@
+package com.iluwatar.collectingparameter;
+
+enum PaperSizes {
+  A2,
+  A3,
+  A4
+}
diff --git a/collecting-parameter/src/main/java/com/iluwatar/collectingparameter/PrinterItem.java b/collecting-parameter/src/main/java/com/iluwatar/collectingparameter/PrinterItem.java
new file mode 100644
index 000000000000..629cdb62500e
--- /dev/null
+++ b/collecting-parameter/src/main/java/com/iluwatar/collectingparameter/PrinterItem.java
@@ -0,0 +1,34 @@
+package com.iluwatar.collectingparameter;
+
+import java.util.Objects;
+
+/**
+ * This class represents a Print Item, that should be added to the queue.
+ **/
+public class PrinterItem {
+  PaperSizes paperSize;
+  int pageCount;
+  boolean isDoubleSided;
+  boolean isColour;
+
+  /**
+   * The {@link PrinterItem} constructor.
+   **/
+  public PrinterItem(PaperSizes paperSize, int pageCount, boolean isDoubleSided, boolean isColour) {
+    if (!Objects.isNull(paperSize)) {
+      this.paperSize = paperSize;
+    } else {
+      throw new IllegalArgumentException();
+    }
+
+    if (pageCount > 0) {
+      this.pageCount = pageCount;
+    } else {
+      throw new IllegalArgumentException();
+    }
+
+    this.isColour = isColour;
+    this.isDoubleSided = isDoubleSided;
+
+  }
+}
diff --git a/collecting-parameter/src/main/java/com/iluwatar/collectingparameter/PrinterQueue.java b/collecting-parameter/src/main/java/com/iluwatar/collectingparameter/PrinterQueue.java
new file mode 100644
index 000000000000..2408d076c7c6
--- /dev/null
+++ b/collecting-parameter/src/main/java/com/iluwatar/collectingparameter/PrinterQueue.java
@@ -0,0 +1,52 @@
+package com.iluwatar.collectingparameter;
+
+import java.util.LinkedList;
+import java.util.Objects;
+import java.util.Queue;
+
+/**
+ * This class represents a singleton Printer Queue. It contains a queue that can be filled up with {@link PrinterItem}.
+ **/
+public class PrinterQueue {
+
+  static PrinterQueue currentInstance = null;
+  private final Queue<PrinterItem> printerItemQueue;
+
+  /**
+   * This class is a singleton. The getInstance method will ensure that only one instance exists at a time.
+   */
+  public static PrinterQueue getInstance() {
+    if (Objects.isNull(currentInstance)) {
+      currentInstance = new PrinterQueue();
+    }
+    return currentInstance;
+  }
+
+  /**
+   * Empty the printer queue.
+   */
+  public void emptyQueue() {
+    currentInstance.getPrinterQueue().clear();
+  }
+
+  /**
+   * Private constructor prevents instantiation, unless using the getInstance() method.
+   */
+  private PrinterQueue() {
+    printerItemQueue = new LinkedList<>();
+  }
+
+  public Queue<PrinterItem> getPrinterQueue() {
+    return currentInstance.printerItemQueue;
+  }
+
+  /**
+   * Adds a single print job to the queue.
+   *
+   * @param printerItem The printing job to be added to the queue
+   */
+  public void addPrinterItem(PrinterItem printerItem) {
+    currentInstance.getPrinterQueue().add(printerItem);
+  }
+
+}
diff --git a/pom.xml b/pom.xml
index 3aacbad55d4a..c14cf5dbdcb3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -84,6 +84,7 @@
   </properties>
   <modules>
     <module>abstract-factory</module>
+    <module>collecting-parameter</module>
     <module>monitor</module>
     <module>tls</module>
     <module>builder</module>


Test patch:
diff --git a/collecting-parameter/src/test/java/com/iluwatar/collectingparameter/AppTest.java b/collecting-parameter/src/test/java/com/iluwatar/collectingparameter/AppTest.java
new file mode 100644
index 000000000000..57f9037778ae
--- /dev/null
+++ b/collecting-parameter/src/test/java/com/iluwatar/collectingparameter/AppTest.java
@@ -0,0 +1,39 @@
+/*
+ * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
+ *
+ * The MIT License
+ * Copyright © 2014-2022 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.collectingparameter;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+class AppTest {
+  /**
+   * Checks whether {@link App} executes without throwing exception
+   */
+  @Test
+  void executesWithoutException() {
+    assertDoesNotThrow(() -> App.main(new String[]{}));
+  }
+}
diff --git a/collecting-parameter/src/test/java/com/iluwatar/collectingparameter/CollectingParameterTest.java b/collecting-parameter/src/test/java/com/iluwatar/collectingparameter/CollectingParameterTest.java
new file mode 100644
index 000000000000..53b7a4635df1
--- /dev/null
+++ b/collecting-parameter/src/test/java/com/iluwatar/collectingparameter/CollectingParameterTest.java
@@ -0,0 +1,55 @@
+package com.iluwatar.collectingparameter;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Timeout;
+
+import java.util.LinkedList;
+import java.util.Queue;
+
+class CollectingParameterTest {
+
+  @Test
+  @Timeout(1000)
+  void testCollectingParameter() {
+    PrinterQueue printerQueue = PrinterQueue.getInstance();
+    printerQueue.emptyQueue();
+
+    PrinterItem item1 = new PrinterItem(PaperSizes.A4, 1, false, true);
+    PrinterItem item2 = new PrinterItem(PaperSizes.A4, 10, true, false);
+    PrinterItem item3 = new PrinterItem(PaperSizes.A4, 4, true, true);
+    PrinterItem item4 = new PrinterItem(PaperSizes.A3, 9, false, false);
+    PrinterItem item5 = new PrinterItem(PaperSizes.A3, 3, true, true);
+    PrinterItem item6 = new PrinterItem(PaperSizes.A3, 3, false, true);
+    PrinterItem item7 = new PrinterItem(PaperSizes.A3, 3, true, false);
+    PrinterItem item8 = new PrinterItem(PaperSizes.A2, 1, false, false);
+    PrinterItem item9 = new PrinterItem(PaperSizes.A2, 2, false, false);
+    PrinterItem item10 = new PrinterItem(PaperSizes.A2, 1, true, false);
+    PrinterItem item11 = new PrinterItem(PaperSizes.A2, 1, false, true);
+
+    printerQueue.addPrinterItem(item1);
+    printerQueue.addPrinterItem(item2);
+    printerQueue.addPrinterItem(item3);
+    printerQueue.addPrinterItem(item4);
+    printerQueue.addPrinterItem(item5);
+    printerQueue.addPrinterItem(item6);
+    printerQueue.addPrinterItem(item7);
+    printerQueue.addPrinterItem(item8);
+    printerQueue.addPrinterItem(item9);
+    printerQueue.addPrinterItem(item10);
+    printerQueue.addPrinterItem(item11);
+
+    Queue<PrinterItem> result = new LinkedList<>();
+    App.addValidA4Papers(result);
+    App.addValidA3Papers(result);
+    App.addValidA2Papers(result);
+
+    Queue<PrinterItem> testResult = new LinkedList<>();
+    testResult.add(item1);
+    testResult.add(item2);
+    testResult.add(item4);
+    testResult.add(item8);
+
+    Assertions.assertArrayEquals(testResult.toArray(), result.toArray());
+  }
+}
diff --git a/collecting-parameter/src/test/java/com/iluwatar/collectingparameter/PrinterQueueTest.java b/collecting-parameter/src/test/java/com/iluwatar/collectingparameter/PrinterQueueTest.java
new file mode 100644
index 000000000000..8371732f66e0
--- /dev/null
+++ b/collecting-parameter/src/test/java/com/iluwatar/collectingparameter/PrinterQueueTest.java
@@ -0,0 +1,34 @@
+package com.iluwatar.collectingparameter;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Timeout;
+
+import java.util.LinkedList;
+import java.util.Queue;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class PrinterQueueTest {
+
+  @Test
+  @Timeout(1000)
+  void singletonTest() {
+    PrinterQueue printerQueue1 = PrinterQueue.getInstance();
+    PrinterQueue printerQueue2 = PrinterQueue.getInstance();
+    assertSame(printerQueue1, printerQueue2);
+  }
+
+  @Test()
+  @Timeout(1000)
+  void negativePageCount() throws IllegalArgumentException {
+    Assertions.assertThrows(IllegalArgumentException.class, () -> new PrinterItem(PaperSizes.A4, -1, true, true));
+  }
+
+  @Test()
+  @Timeout(1000)
+  void nullPageSize() throws IllegalArgumentException {
+    Assertions.assertThrows(IllegalArgumentException.class, () -> new PrinterItem(null, 1, true, true));
+  }
+
+}
\ No newline at end of file