From 3c6f7aa046cd70524ecd73c4ebcb664ac008c711 Mon Sep 17 00:00:00 2001
From: "Igor C. A. de Lima"
Date: Sat, 12 Aug 2017 12:11:10 -0300
Subject: [PATCH 01/10] Protect against instantiation via reflection
Signed-off-by: Igor C. A. de Lima
---
.../ThreadSafeLazyLoadedIvoryTower.java | 35 +++++++++----------
1 file changed, 16 insertions(+), 19 deletions(-)
diff --git a/singleton/src/main/java/com/iluwatar/singleton/ThreadSafeLazyLoadedIvoryTower.java b/singleton/src/main/java/com/iluwatar/singleton/ThreadSafeLazyLoadedIvoryTower.java
index 68f190d46..fb88c68d5 100644
--- a/singleton/src/main/java/com/iluwatar/singleton/ThreadSafeLazyLoadedIvoryTower.java
+++ b/singleton/src/main/java/com/iluwatar/singleton/ThreadSafeLazyLoadedIvoryTower.java
@@ -1,24 +1,20 @@
/**
- * The MIT License
- * Copyright (c) 2014-2016 Ilkka Seppälä
+ * The MIT License Copyright (c) 2014-2016 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
+ * 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 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.
+ * 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.singleton;
@@ -34,8 +30,10 @@ public final class ThreadSafeLazyLoadedIvoryTower {
private static ThreadSafeLazyLoadedIvoryTower instance;
private ThreadSafeLazyLoadedIvoryTower() {
- // to prevent instantiating by Reflection call
- if (instance != null) {
+ // protect against instantiation via reflection
+ if (instance == null) {
+ instance = this;
+ } else {
throw new IllegalStateException("Already initialized.");
}
}
@@ -44,7 +42,6 @@ public final class ThreadSafeLazyLoadedIvoryTower {
* The instance gets created only when it is called for first time. Lazy-loading
*/
public static synchronized ThreadSafeLazyLoadedIvoryTower getInstance() {
-
if (instance == null) {
instance = new ThreadSafeLazyLoadedIvoryTower();
}
From 684cad9beb686855a015d68418851255eb63f555 Mon Sep 17 00:00:00 2001
From: Sanket
Date: Sat, 23 Sep 2017 20:55:38 -0400
Subject: [PATCH 02/10] added tutorial links to bridge, decorator,
abstract-factory, strategy and template method patterns
---
abstract-factory/README.md | 3 +++
bridge/README.md | 3 +++
decorator/README.md | 3 +++
strategy/README.md | 3 +++
template-method/README.md | 3 +++
5 files changed, 15 insertions(+)
diff --git a/abstract-factory/README.md b/abstract-factory/README.md
index c049401fc..1c1966739 100644
--- a/abstract-factory/README.md
+++ b/abstract-factory/README.md
@@ -141,6 +141,9 @@ Use the Abstract Factory pattern when
* Dependency injection in java hides the service class dependencies that can lead to runtime errors that would have been caught at compile time.
+## Tutorial
+* [Abstract Factory Method Tutorial](https://www.journaldev.com/1418/abstract-factory-design-pattern-in-java)
+
## Real world examples
* [javax.xml.parsers.DocumentBuilderFactory](http://docs.oracle.com/javase/8/docs/api/javax/xml/parsers/DocumentBuilderFactory.html)
diff --git a/bridge/README.md b/bridge/README.md
index a37c35174..a53e6143f 100644
--- a/bridge/README.md
+++ b/bridge/README.md
@@ -189,6 +189,9 @@ Use the Bridge pattern when
* you have a proliferation of classes. Such a class hierarchy indicates the need for splitting an object into two parts. Rumbaugh uses the term "nested generalizations" to refer to such class hierarchies
* you want to share an implementation among multiple objects (perhaps using reference counting), and this fact should be hidden from the client. A simple example is Coplien's String class, in which multiple objects can share the same string representation.
+## Tutorial
+* [Bridge Pattern Tutorial](https://www.journaldev.com/1491/bridge-design-pattern-java)
+
## Credits
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)
diff --git a/decorator/README.md b/decorator/README.md
index 37cfd88df..1b9d8a511 100644
--- a/decorator/README.md
+++ b/decorator/README.md
@@ -117,6 +117,9 @@ Use Decorator
* For responsibilities that can be withdrawn
* When extension by subclassing is impractical. Sometimes a large number of independent extensions are possible and would produce an explosion of subclasses to support every combination. Or a class definition may be hidden or otherwise unavailable for subclassing
+## Tutorial
+* [Decorator Pattern Tutorial](https://www.journaldev.com/1540/decorator-design-pattern-in-java-example)
+
## Real world examples
* [java.io.InputStream](http://docs.oracle.com/javase/8/docs/api/java/io/InputStream.html), [java.io.OutputStream](http://docs.oracle.com/javase/8/docs/api/java/io/OutputStream.html),
[java.io.Reader](http://docs.oracle.com/javase/8/docs/api/java/io/Reader.html) and [java.io.Writer](http://docs.oracle.com/javase/8/docs/api/java/io/Writer.html)
diff --git a/strategy/README.md b/strategy/README.md
index 697b6cc88..74828cafc 100644
--- a/strategy/README.md
+++ b/strategy/README.md
@@ -29,6 +29,9 @@ Use the Strategy pattern when
* an algorithm uses data that clients shouldn't know about. Use the Strategy pattern to avoid exposing complex, algorithm-specific data structures
* a class defines many behaviors, and these appear as multiple conditional statements in its operations. Instead of many conditionals, move related conditional branches into their own Strategy class
+## Tutorial
+* [Strategy Pattern Tutorial](https://www.journaldev.com/1754/strategy-design-pattern-in-java-example-tutorial)
+
## Credits
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)
diff --git a/template-method/README.md b/template-method/README.md
index 65381d0ce..def168a8d 100644
--- a/template-method/README.md
+++ b/template-method/README.md
@@ -25,6 +25,9 @@ The Template Method pattern should be used
* when common behavior among subclasses should be factored and localized in a common class to avoid code duplication. This is good example of "refactoring to generalize" as described by Opdyke and Johnson. You first identify the differences in the existing code and then separate the differences into new operations. Finally, you replace the differing code with a template method that calls one of these new operations
* to control subclasses extensions. You can define a template method that calls "hook" operations at specific points, thereby permitting extensions only at those points
+## Tutorial
+* [Template-method Pattern Tutorial](https://www.journaldev.com/1763/template-method-design-pattern-in-java)
+
## Credits
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)
From b61b64073a01edd5fd1154a5993ea028732d4229 Mon Sep 17 00:00:00 2001
From: tigraboris
Date: Mon, 8 Jan 2018 14:00:12 +0300
Subject: [PATCH 03/10] #677 init folder for pattern trampoline
---
trampoline/.gitignore | 2 +
trampoline/README.md | 38 +++++++++++
trampoline/pom.xml | 67 +++++++++++++++++++
.../java/com/iluwatar/trampoline/App.java | 4 ++
4 files changed, 111 insertions(+)
create mode 100644 trampoline/.gitignore
create mode 100644 trampoline/README.md
create mode 100644 trampoline/pom.xml
create mode 100644 trampoline/src/main/java/com/iluwatar/trampoline/App.java
diff --git a/trampoline/.gitignore b/trampoline/.gitignore
new file mode 100644
index 000000000..431845ed0
--- /dev/null
+++ b/trampoline/.gitignore
@@ -0,0 +1,2 @@
+/target/
+.idea/
diff --git a/trampoline/README.md b/trampoline/README.md
new file mode 100644
index 000000000..849cc663e
--- /dev/null
+++ b/trampoline/README.md
@@ -0,0 +1,38 @@
+---
+layout: pattern
+title: Trampoline
+folder: trampoline
+permalink: /patterns/trampoline/
+categories: Behavior
+tags:
+ - Java
+ - Difficulty-Intermediate
+ - Performance
+ - Recursion
+---
+
+## Intent
+By representing a computation in one of 2 states
+(completed with result, or a reference to the reminder of the computation,
+something like the way a java.util.Supplier does)
+it is possible to implement algorithms recursively in Java without blowing the stack
+and to interleave the execution of functions without hard coding them together or even using threads.
+
+
+
+## Applicability
+Use the Trampoline pattern when
+
+* For implementing tail recursive function. This pattern allows to switch on a stackless operation.
+* For to interleaving the execution of two or more functions on the same thread.
+
+## Known uses(real world examples)
+* Trampoline refers to using reflection to avoid using inner classes, for example in event listeners.
+The time overhead of a reflection call is traded for the space overhead of an inner class.
+Trampolines in Java usually involve the creation of a GenericListener to pass events to an outer class.
+
+## Credits
+
+* [Trampolining: a practical guide for awesome Java Developers](https://medium.com/@johnmcclean/trampolining-a-practical-guide-for-awesome-java-developers-4b657d9c3076)
+* [Trampoline in java ](http://mindprod.com/jgloss/trampoline.html)
+
diff --git a/trampoline/pom.xml b/trampoline/pom.xml
new file mode 100644
index 000000000..c4cef6860
--- /dev/null
+++ b/trampoline/pom.xml
@@ -0,0 +1,67 @@
+
+
+
+ 4.0.0
+
+ com.iluwatar
+ java-design-patterns
+ 1.19.0-SNAPSHOT
+
+ trampoline
+
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+
+ org.projectlombok
+ lombok
+ 1.16.18
+ provided
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 2.19
+
+ false
+
+
+
+
+
diff --git a/trampoline/src/main/java/com/iluwatar/trampoline/App.java b/trampoline/src/main/java/com/iluwatar/trampoline/App.java
new file mode 100644
index 000000000..8afda31a7
--- /dev/null
+++ b/trampoline/src/main/java/com/iluwatar/trampoline/App.java
@@ -0,0 +1,4 @@
+package com.iluwatar.trampoline;
+
+public class App {
+}
From 94fdefee3a65f8a67335c919440c1a8962681c51 Mon Sep 17 00:00:00 2001
From: tigraboris
Date: Mon, 8 Jan 2018 14:45:38 +0300
Subject: [PATCH 04/10] add code
---
trampoline/README.md | 4 +-
.../java/com/iluwatar/trampoline/App.java | 4 -
.../com/iluwatar/trampoline/Trampoline.java | 84 +++++++++++++++++++
.../iluwatar/trampoline/TrampolineApp.java | 67 +++++++++++++++
.../trampoline/TrampolineAppTest.java | 17 ++++
5 files changed, 171 insertions(+), 5 deletions(-)
delete mode 100644 trampoline/src/main/java/com/iluwatar/trampoline/App.java
create mode 100644 trampoline/src/main/java/com/iluwatar/trampoline/Trampoline.java
create mode 100644 trampoline/src/main/java/com/iluwatar/trampoline/TrampolineApp.java
create mode 100644 trampoline/src/test/java/com/iluwatar/trampoline/TrampolineAppTest.java
diff --git a/trampoline/README.md b/trampoline/README.md
index 849cc663e..4a4030f39 100644
--- a/trampoline/README.md
+++ b/trampoline/README.md
@@ -24,15 +24,17 @@ and to interleave the execution of functions without hard coding them together o
Use the Trampoline pattern when
* For implementing tail recursive function. This pattern allows to switch on a stackless operation.
-* For to interleaving the execution of two or more functions on the same thread.
+* For interleaving the execution of two or more functions on the same thread.
## Known uses(real world examples)
* Trampoline refers to using reflection to avoid using inner classes, for example in event listeners.
The time overhead of a reflection call is traded for the space overhead of an inner class.
Trampolines in Java usually involve the creation of a GenericListener to pass events to an outer class.
+
## Credits
* [Trampolining: a practical guide for awesome Java Developers](https://medium.com/@johnmcclean/trampolining-a-practical-guide-for-awesome-java-developers-4b657d9c3076)
* [Trampoline in java ](http://mindprod.com/jgloss/trampoline.html)
+* [cyclops-react](https://github.com/aol/cyclops-react)
diff --git a/trampoline/src/main/java/com/iluwatar/trampoline/App.java b/trampoline/src/main/java/com/iluwatar/trampoline/App.java
deleted file mode 100644
index 8afda31a7..000000000
--- a/trampoline/src/main/java/com/iluwatar/trampoline/App.java
+++ /dev/null
@@ -1,4 +0,0 @@
-package com.iluwatar.trampoline;
-
-public class App {
-}
diff --git a/trampoline/src/main/java/com/iluwatar/trampoline/Trampoline.java b/trampoline/src/main/java/com/iluwatar/trampoline/Trampoline.java
new file mode 100644
index 000000000..3be44ebba
--- /dev/null
+++ b/trampoline/src/main/java/com/iluwatar/trampoline/Trampoline.java
@@ -0,0 +1,84 @@
+package com.iluwatar.trampoline;
+
+import java.util.stream.Stream;
+
+/**When get is called on the returned Trampoline, internally it will iterate calling ‘jump’
+ on the returned Trampoline as long as the concrete instance returned is More,
+ stopping once the returned instance is Done. Essential we convert looping via recursion into iteration,
+ the key enabling mechanism is the fact that Trampoline.more is a lazy operation.
+ Trampoline in cyclops-react extends java.util.Supplier. Calling Trampoline.more we are basically creating
+ a Supplier that defers the actual recursive call, and having defered the call we can move it outside of the recursive loop.
+ This means we can define algorithms recursively in Java but execute them iteratively.*/
+
+public interface Trampoline {
+ T get();
+
+
+ /**
+ * @return next stage
+ */
+ default Trampoline jump() {
+ return this;
+ }
+
+
+ default T result() {
+ return get();
+ }
+
+ /**
+ * @return true if complete
+ *
+ */
+ default boolean complete() {
+ return true;
+ }
+
+ /**
+ * Created a completed Trampoline
+ *
+ * @param result Completed result
+ * @return Completed Trampoline
+ */
+ static Trampoline done(final T result) {
+ return () -> result;
+ }
+
+
+ /**
+ * Create a Trampoline that has more work to do
+ *
+ * @param trampoline Next stage in Trampoline
+ * @return Trampoline with more work
+ */
+ static Trampoline more(final Trampoline> trampoline) {
+ return new Trampoline() {
+ @Override
+ public boolean complete() {
+ return false;
+ }
+
+ @Override
+ public Trampoline jump() {
+ return trampoline.result();
+ }
+
+ @Override
+ public T get() {
+ return trampoline(this);
+ }
+
+ T trampoline(final Trampoline trampoline) {
+
+ return Stream.iterate(trampoline, Trampoline::jump)
+ .filter(Trampoline::complete)
+ .findFirst()
+ .get()
+ .result();
+
+ }
+ };
+ }
+
+
+}
diff --git a/trampoline/src/main/java/com/iluwatar/trampoline/TrampolineApp.java b/trampoline/src/main/java/com/iluwatar/trampoline/TrampolineApp.java
new file mode 100644
index 000000000..d629f7a84
--- /dev/null
+++ b/trampoline/src/main/java/com/iluwatar/trampoline/TrampolineApp.java
@@ -0,0 +1,67 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014-2016 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.trampoline;
+
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ *
+ * By representing a computation in one of 2 states
+ (completed with result, or a reference to the reminder of the computation,
+ something like the way a java.util.Supplier does)
+ it is possible to implement algorithms recursively in Java without blowing the stack
+ and to interleave the execution of functions without hard coding them together or even using threads.
+
+
+ Trampoline has 2 state : [done], [ more]
+
+ When get is called on the returned Trampoline, internally it will iterate calling ‘jump’
+ on the returned Trampoline as long as the concrete instance returned is More,
+ stopping once the returned instance is Done. Essential we convert looping via recursion into iteration,
+ the key enabling mechanism is the fact that Trampoline.more is a lazy operation.
+ Trampoline in cyclops-react extends java.util.Supplier. Calling Trampoline.more we are basically creating
+ a Supplier that defers the actual recursive call, and having defered the call we can move it outside of the recursive loop.
+ This means we can define algorithms recursively in Java but execute them iteratively.
+ */
+
+@Slf4j
+public class TrampolineApp {
+ public static void main(String[] args) {
+ log.info("start pattern");
+ Integer result = loop(10, 1).result();
+ log.info("result {}" ,result);
+
+ }
+ /**
+ * Manager for pattern.
+ * */
+ public static Trampoline loop(int times,int prod){
+ if(times==0)
+ return Trampoline.done(prod);
+ else
+ return Trampoline.more(()->loop(times-1,prod*times));
+ }
+
+}
diff --git a/trampoline/src/test/java/com/iluwatar/trampoline/TrampolineAppTest.java b/trampoline/src/test/java/com/iluwatar/trampoline/TrampolineAppTest.java
new file mode 100644
index 000000000..fb7fc09ee
--- /dev/null
+++ b/trampoline/src/test/java/com/iluwatar/trampoline/TrampolineAppTest.java
@@ -0,0 +1,17 @@
+package com.iluwatar.trampoline;
+
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.junit.Assert.*;
+
+public class TrampolineAppTest {
+
+ @Test
+ public void test()throws IOException{
+ int result = TrampolineApp.loop(10, 1).result();
+ assertEquals("Be equal",3628800,result);
+ }
+
+}
\ No newline at end of file
From f7825f6c9942b0d7e07f500bc8f5b4ebf227a8af Mon Sep 17 00:00:00 2001
From: tigraboris
Date: Sat, 20 Jan 2018 13:36:43 +0300
Subject: [PATCH 05/10] changes fixing mistakes
---
pom.xml | 2 +-
trampoline/README.md | 19 ++++++----
trampoline/pom.xml | 3 --
.../com/iluwatar/trampoline/Trampoline.java | 14 +++----
.../iluwatar/trampoline/TrampolineApp.java | 37 ++++++-------------
.../trampoline/TrampolineAppTest.java | 3 +-
6 files changed, 34 insertions(+), 44 deletions(-)
diff --git a/pom.xml b/pom.xml
index 66c5fa850..7e669d396 100644
--- a/pom.xml
+++ b/pom.xml
@@ -147,13 +147,13 @@
event-sourcingdata-transfer-objectthrottling
-
unit-of-workpartial-responseeip-wire-tapeip-splittereip-aggregatorretry
+ trampoline
diff --git a/trampoline/README.md b/trampoline/README.md
index 4a4030f39..cae343a61 100644
--- a/trampoline/README.md
+++ b/trampoline/README.md
@@ -12,13 +12,16 @@ tags:
---
## Intent
-By representing a computation in one of 2 states
+Trampoline pattern is used for implementing algorithms recursively in Java without blowing the stack
+and to interleave the execution of functions without hard coding them together
+It is possible by representing a computation in one of 2 states : done | more
(completed with result, or a reference to the reminder of the computation,
-something like the way a java.util.Supplier does)
-it is possible to implement algorithms recursively in Java without blowing the stack
-and to interleave the execution of functions without hard coding them together or even using threads.
+something like the way a java.util.Supplier does).
+## Explanation
+Trampoline pattern allows to define recursive algorithms by iterative loop.
+
## Applicability
Use the Trampoline pattern when
@@ -32,9 +35,11 @@ The time overhead of a reflection call is traded for the space overhead of an in
Trampolines in Java usually involve the creation of a GenericListener to pass events to an outer class.
-## Credits
-
+## Tutorials
* [Trampolining: a practical guide for awesome Java Developers](https://medium.com/@johnmcclean/trampolining-a-practical-guide-for-awesome-java-developers-4b657d9c3076)
* [Trampoline in java ](http://mindprod.com/jgloss/trampoline.html)
-* [cyclops-react](https://github.com/aol/cyclops-react)
+
+## Credits
+* [library 'cyclops-react' uses the pattern](https://github.com/aol/cyclops-react)
+
diff --git a/trampoline/pom.xml b/trampoline/pom.xml
index c4cef6860..cea93969c 100644
--- a/trampoline/pom.xml
+++ b/trampoline/pom.xml
@@ -34,19 +34,16 @@
trampoline
-
junitjunit4.12test
-
org.projectlomboklombok1.16.18
- provided
diff --git a/trampoline/src/main/java/com/iluwatar/trampoline/Trampoline.java b/trampoline/src/main/java/com/iluwatar/trampoline/Trampoline.java
index 3be44ebba..8a02e246b 100644
--- a/trampoline/src/main/java/com/iluwatar/trampoline/Trampoline.java
+++ b/trampoline/src/main/java/com/iluwatar/trampoline/Trampoline.java
@@ -2,13 +2,13 @@ package com.iluwatar.trampoline;
import java.util.stream.Stream;
-/**When get is called on the returned Trampoline, internally it will iterate calling ‘jump’
- on the returned Trampoline as long as the concrete instance returned is More,
- stopping once the returned instance is Done. Essential we convert looping via recursion into iteration,
- the key enabling mechanism is the fact that Trampoline.more is a lazy operation.
- Trampoline in cyclops-react extends java.util.Supplier. Calling Trampoline.more we are basically creating
- a Supplier that defers the actual recursive call, and having defered the call we can move it outside of the recursive loop.
- This means we can define algorithms recursively in Java but execute them iteratively.*/
+/**
Trampoline pattern allows to define recursive algorithms by iterative loop
+ *
When get is called on the returned Trampoline, internally it will iterate calling ‘jump’
+ on the returned Trampoline as long as the concrete instance returned is {@link #more(Trampoline)},
+ stopping once the returned instance is {@link #done(Object)}.
+
Essential we convert looping via recursion into iteration,
+ the key enabling mechanism is the fact that {@link #more(Trampoline)} is a lazy operation.
+*/
public interface Trampoline {
T get();
diff --git a/trampoline/src/main/java/com/iluwatar/trampoline/TrampolineApp.java b/trampoline/src/main/java/com/iluwatar/trampoline/TrampolineApp.java
index d629f7a84..73222ddf5 100644
--- a/trampoline/src/main/java/com/iluwatar/trampoline/TrampolineApp.java
+++ b/trampoline/src/main/java/com/iluwatar/trampoline/TrampolineApp.java
@@ -1,17 +1,17 @@
/**
* The MIT License
* Copyright (c) 2014-2016 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
@@ -27,23 +27,9 @@ package com.iluwatar.trampoline;
import lombok.extern.slf4j.Slf4j;
/**
- *
- * By representing a computation in one of 2 states
- (completed with result, or a reference to the reminder of the computation,
- something like the way a java.util.Supplier does)
- it is possible to implement algorithms recursively in Java without blowing the stack
- and to interleave the execution of functions without hard coding them together or even using threads.
-
-
- Trampoline has 2 state : [done], [ more]
-
- When get is called on the returned Trampoline, internally it will iterate calling ‘jump’
- on the returned Trampoline as long as the concrete instance returned is More,
- stopping once the returned instance is Done. Essential we convert looping via recursion into iteration,
- the key enabling mechanism is the fact that Trampoline.more is a lazy operation.
- Trampoline in cyclops-react extends java.util.Supplier. Calling Trampoline.more we are basically creating
- a Supplier that defers the actual recursive call, and having defered the call we can move it outside of the recursive loop.
- This means we can define algorithms recursively in Java but execute them iteratively.
+ *
Trampoline pattern allows to define recursive algorithms by iterative loop
+ *
it is possible to implement algorithms recursively in Java without blowing the stack
+ * and to interleave the execution of functions without hard coding them together or even using threads.
*/
@Slf4j
@@ -51,17 +37,18 @@ public class TrampolineApp {
public static void main(String[] args) {
log.info("start pattern");
Integer result = loop(10, 1).result();
- log.info("result {}" ,result);
+ log.info("result {}", result);
}
+
/**
- * Manager for pattern.
+ * Manager for pattern. Define it with a factorial function.
* */
- public static Trampoline loop(int times,int prod){
- if(times==0)
+ public static Trampoline loop(int times, int prod) {
+ if (times == 0)
return Trampoline.done(prod);
else
- return Trampoline.more(()->loop(times-1,prod*times));
+ return Trampoline.more(() -> loop(times - 1, prod * times));
}
}
diff --git a/trampoline/src/test/java/com/iluwatar/trampoline/TrampolineAppTest.java b/trampoline/src/test/java/com/iluwatar/trampoline/TrampolineAppTest.java
index fb7fc09ee..9765131d5 100644
--- a/trampoline/src/test/java/com/iluwatar/trampoline/TrampolineAppTest.java
+++ b/trampoline/src/test/java/com/iluwatar/trampoline/TrampolineAppTest.java
@@ -8,8 +8,9 @@ import static org.junit.Assert.*;
public class TrampolineAppTest {
+
@Test
- public void test()throws IOException{
+ public void testTrampolineWithFactorialFunction()throws IOException{
int result = TrampolineApp.loop(10, 1).result();
assertEquals("Be equal",3628800,result);
}
From 4c4cbd41cf8a1310304bd16a2b40acb18ee7a05d Mon Sep 17 00:00:00 2001
From: tigraboris
Date: Sat, 20 Jan 2018 21:42:14 +0300
Subject: [PATCH 06/10] fix checkstyle errors
---
.../com/iluwatar/trampoline/Trampoline.java | 127 +++++++++---------
.../iluwatar/trampoline/TrampolineApp.java | 32 +++--
.../trampoline/TrampolineAppTest.java | 14 +-
3 files changed, 91 insertions(+), 82 deletions(-)
diff --git a/trampoline/src/main/java/com/iluwatar/trampoline/Trampoline.java b/trampoline/src/main/java/com/iluwatar/trampoline/Trampoline.java
index 8a02e246b..277ae9ffb 100644
--- a/trampoline/src/main/java/com/iluwatar/trampoline/Trampoline.java
+++ b/trampoline/src/main/java/com/iluwatar/trampoline/Trampoline.java
@@ -2,83 +2,84 @@ package com.iluwatar.trampoline;
import java.util.stream.Stream;
-/**
Trampoline pattern allows to define recursive algorithms by iterative loop
+/**
+ *
Trampoline pattern allows to define recursive algorithms by iterative loop
*
When get is called on the returned Trampoline, internally it will iterate calling ‘jump’
- on the returned Trampoline as long as the concrete instance returned is {@link #more(Trampoline)},
- stopping once the returned instance is {@link #done(Object)}.
-
Essential we convert looping via recursion into iteration,
- the key enabling mechanism is the fact that {@link #more(Trampoline)} is a lazy operation.
-*/
-
-public interface Trampoline {
- T get();
+ * on the returned Trampoline as long as the concrete instance returned is {@link #more(Trampoline)},
+ * stopping once the returned instance is {@link #done(Object)}.
+ *
Essential we convert looping via recursion into iteration,
+ * the key enabling mechanism is the fact that {@link #more(Trampoline)} is a lazy operation.
+ *
+ * @param is type for returning result.
+ */
+public interface Trampoline {
+ T get();
- /**
- * @return next stage
- */
- default Trampoline jump() {
- return this;
- }
+ /**
+ * @return next stage
+ */
+ default Trampoline jump() {
+ return this;
+ }
- default T result() {
- return get();
- }
+ default T result() {
+ return get();
+ }
- /**
- * @return true if complete
- *
- */
- default boolean complete() {
- return true;
- }
+ /**
+ * @return true if complete
+ */
+ default boolean complete() {
+ return true;
+ }
- /**
- * Created a completed Trampoline
- *
- * @param result Completed result
- * @return Completed Trampoline
- */
- static Trampoline done(final T result) {
- return () -> result;
- }
+ /**
+ * Created a completed Trampoline
+ *
+ * @param result Completed result
+ * @return Completed Trampoline
+ */
+ static Trampoline done(final T result) {
+ return () -> result;
+ }
- /**
- * Create a Trampoline that has more work to do
- *
- * @param trampoline Next stage in Trampoline
- * @return Trampoline with more work
- */
- static Trampoline more(final Trampoline> trampoline) {
- return new Trampoline() {
- @Override
- public boolean complete() {
- return false;
- }
+ /**
+ * Create a Trampoline that has more work to do
+ *
+ * @param trampoline Next stage in Trampoline
+ * @return Trampoline with more work
+ */
+ static Trampoline more(final Trampoline> trampoline) {
+ return new Trampoline() {
+ @Override
+ public boolean complete() {
+ return false;
+ }
- @Override
- public Trampoline jump() {
- return trampoline.result();
- }
+ @Override
+ public Trampoline jump() {
+ return trampoline.result();
+ }
- @Override
- public T get() {
- return trampoline(this);
- }
+ @Override
+ public T get() {
+ return trampoline(this);
+ }
- T trampoline(final Trampoline trampoline) {
+ T trampoline(final Trampoline trampoline) {
- return Stream.iterate(trampoline, Trampoline::jump)
- .filter(Trampoline::complete)
- .findFirst()
- .get()
- .result();
+ return Stream.iterate(trampoline, Trampoline::jump)
+ .filter(Trampoline::complete)
+ .findFirst()
+ .get()
+ .result();
- }
- };
- }
+ }
+ };
+ }
}
diff --git a/trampoline/src/main/java/com/iluwatar/trampoline/TrampolineApp.java b/trampoline/src/main/java/com/iluwatar/trampoline/TrampolineApp.java
index 73222ddf5..76e3ed3da 100644
--- a/trampoline/src/main/java/com/iluwatar/trampoline/TrampolineApp.java
+++ b/trampoline/src/main/java/com/iluwatar/trampoline/TrampolineApp.java
@@ -31,24 +31,28 @@ import lombok.extern.slf4j.Slf4j;
*
it is possible to implement algorithms recursively in Java without blowing the stack
* and to interleave the execution of functions without hard coding them together or even using threads.
*/
-
@Slf4j
public class TrampolineApp {
- public static void main(String[] args) {
- log.info("start pattern");
- Integer result = loop(10, 1).result();
- log.info("result {}", result);
- }
+ /**
+ * Main program for showing pattern. It does loop with factorial function.
+ * */
+ public static void main(String[] args) {
+ log.info("start pattern");
+ Integer result = loop(10, 1).result();
+ log.info("result {}", result);
- /**
- * Manager for pattern. Define it with a factorial function.
- * */
- public static Trampoline loop(int times, int prod) {
- if (times == 0)
- return Trampoline.done(prod);
- else
- return Trampoline.more(() -> loop(times - 1, prod * times));
+ }
+
+ /**
+ * Manager for pattern. Define it with a factorial function.
+ */
+ public static Trampoline loop(int times, int prod) {
+ if (times == 0) {
+ return Trampoline.done(prod);
+ } else {
+ return Trampoline.more(() -> loop(times - 1, prod * times));
}
+ }
}
diff --git a/trampoline/src/test/java/com/iluwatar/trampoline/TrampolineAppTest.java b/trampoline/src/test/java/com/iluwatar/trampoline/TrampolineAppTest.java
index 9765131d5..553e583e1 100644
--- a/trampoline/src/test/java/com/iluwatar/trampoline/TrampolineAppTest.java
+++ b/trampoline/src/test/java/com/iluwatar/trampoline/TrampolineAppTest.java
@@ -6,13 +6,17 @@ import java.io.IOException;
import static org.junit.Assert.*;
+
+/**
+ * Test for trampoline pattern.
+ * */
public class TrampolineAppTest {
- @Test
- public void testTrampolineWithFactorialFunction()throws IOException{
- int result = TrampolineApp.loop(10, 1).result();
- assertEquals("Be equal",3628800,result);
- }
+ @Test
+ public void testTrampolineWithFactorialFunction() throws IOException {
+ int result = TrampolineApp.loop(10, 1).result();
+ assertEquals("Be equal", 3628800, result);
+ }
}
\ No newline at end of file
From 9667878b5f3dacb8a9bd1a7c7d95fa13a153b2d5 Mon Sep 17 00:00:00 2001
From: tigraboris
Date: Sat, 20 Jan 2018 22:09:42 +0300
Subject: [PATCH 07/10] add junit - jupiter -engine
---
trampoline/pom.xml | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/trampoline/pom.xml b/trampoline/pom.xml
index cea93969c..71de3f8f2 100644
--- a/trampoline/pom.xml
+++ b/trampoline/pom.xml
@@ -31,6 +31,7 @@
com.iluwatarjava-design-patterns1.19.0-SNAPSHOT
+
trampoline
@@ -40,6 +41,18 @@
4.12test
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ test
+
+
org.projectlomboklombok
From 2dcf63c6465da0c0209627d10474a46615f836dd Mon Sep 17 00:00:00 2001
From: Sanket
Date: Sat, 27 Jan 2018 20:30:15 -0500
Subject: [PATCH 08/10] fixed typo in abstract factory pattern
---
abstract-factory/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/abstract-factory/README.md b/abstract-factory/README.md
index 1c1966739..25b63f7a2 100644
--- a/abstract-factory/README.md
+++ b/abstract-factory/README.md
@@ -142,7 +142,7 @@ Use the Abstract Factory pattern when
* Dependency injection in java hides the service class dependencies that can lead to runtime errors that would have been caught at compile time.
## Tutorial
-* [Abstract Factory Method Tutorial](https://www.journaldev.com/1418/abstract-factory-design-pattern-in-java)
+* [Abstract Factory Pattern Tutorial](https://www.journaldev.com/1418/abstract-factory-design-pattern-in-java)
## Real world examples
From f62ae456b03eea52addb95d8e3bbdf0277632d65 Mon Sep 17 00:00:00 2001
From: Ryan Guest
Date: Thu, 1 Feb 2018 15:44:23 -0800
Subject: [PATCH 09/10] Fix typo
---
.../java/com/iluwatar/objectmother/RoyaltyObjectMother.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/object-mother/src/main/java/com/iluwatar/objectmother/RoyaltyObjectMother.java b/object-mother/src/main/java/com/iluwatar/objectmother/RoyaltyObjectMother.java
index 118253d56..633a95b71 100644
--- a/object-mother/src/main/java/com/iluwatar/objectmother/RoyaltyObjectMother.java
+++ b/object-mother/src/main/java/com/iluwatar/objectmother/RoyaltyObjectMother.java
@@ -28,7 +28,7 @@ package com.iluwatar.objectmother;
public final class RoyaltyObjectMother {
/**
- * Method to create a sober and unhappy king. The standard paramters are set.
+ * Method to create a sober and unhappy king. The standard parameters are set.
* @return An instance of {@link com.iluwatar.objectmother.King} with the standard properties.
*/
public static King createSoberUnhappyKing() {
From 36f5947cd78a66eeec0b1de51c92100c94b345ad Mon Sep 17 00:00:00 2001
From: baislsl
Date: Thu, 8 Feb 2018 03:00:55 +0800
Subject: [PATCH 10/10] Use the @TestInstance annotation
---
.../java/com/iluwatar/interpreter/ExpressionTest.java | 9 +++++++++
.../com/iluwatar/interpreter/MinusExpressionTest.java | 3 ++-
.../com/iluwatar/interpreter/MultiplyExpressionTest.java | 3 ++-
.../com/iluwatar/interpreter/NumberExpressionTest.java | 3 ++-
.../com/iluwatar/interpreter/PlusExpressionTest.java | 3 ++-
.../src/test/java/com/iluwatar/observer/HobbitsTest.java | 3 ++-
.../src/test/java/com/iluwatar/observer/OrcsTest.java | 3 ++-
.../java/com/iluwatar/observer/WeatherObserverTest.java | 6 ++++++
.../java/com/iluwatar/observer/generic/GHobbitsTest.java | 3 ++-
.../java/com/iluwatar/observer/generic/ObserverTest.java | 5 +++++
.../java/com/iluwatar/observer/generic/OrcsTest.java | 3 ++-
11 files changed, 36 insertions(+), 8 deletions(-)
diff --git a/interpreter/src/test/java/com/iluwatar/interpreter/ExpressionTest.java b/interpreter/src/test/java/com/iluwatar/interpreter/ExpressionTest.java
index a3d9f21f2..a9a4f11d8 100644
--- a/interpreter/src/test/java/com/iluwatar/interpreter/ExpressionTest.java
+++ b/interpreter/src/test/java/com/iluwatar/interpreter/ExpressionTest.java
@@ -23,6 +23,7 @@
package com.iluwatar.interpreter;
import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
@@ -43,6 +44,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
* @param Type of Expression
* @author Jeroen Meulemeester
*/
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public abstract class ExpressionTest {
/**
@@ -88,6 +90,13 @@ public abstract class ExpressionTest {
this.factory = factory;
}
+ /**
+ * Create a new set of test entries with the expected result
+ *
+ * @return The list of parameters used during this test
+ */
+ public abstract Stream expressionProvider();
+
/**
* Verify if the expression calculates the correct result when calling {@link E#interpret()}
*/
diff --git a/interpreter/src/test/java/com/iluwatar/interpreter/MinusExpressionTest.java b/interpreter/src/test/java/com/iluwatar/interpreter/MinusExpressionTest.java
index eab0ea011..276b934c3 100644
--- a/interpreter/src/test/java/com/iluwatar/interpreter/MinusExpressionTest.java
+++ b/interpreter/src/test/java/com/iluwatar/interpreter/MinusExpressionTest.java
@@ -38,7 +38,8 @@ public class MinusExpressionTest extends ExpressionTest {
*
* @return The list of parameters used during this test
*/
- public static Stream expressionProvider() {
+ @Override
+ public Stream expressionProvider() {
return prepareParameters((f, s) -> f - s);
}
diff --git a/interpreter/src/test/java/com/iluwatar/interpreter/MultiplyExpressionTest.java b/interpreter/src/test/java/com/iluwatar/interpreter/MultiplyExpressionTest.java
index 6e5384f8b..e5f4e61ee 100644
--- a/interpreter/src/test/java/com/iluwatar/interpreter/MultiplyExpressionTest.java
+++ b/interpreter/src/test/java/com/iluwatar/interpreter/MultiplyExpressionTest.java
@@ -38,7 +38,8 @@ public class MultiplyExpressionTest extends ExpressionTest {
*
* @return The list of parameters used during this test
*/
- public static Stream expressionProvider() {
+ @Override
+ public Stream expressionProvider() {
return prepareParameters((f, s) -> f * s);
}
diff --git a/interpreter/src/test/java/com/iluwatar/interpreter/NumberExpressionTest.java b/interpreter/src/test/java/com/iluwatar/interpreter/NumberExpressionTest.java
index 698da52bc..cc7c82e7e 100644
--- a/interpreter/src/test/java/com/iluwatar/interpreter/NumberExpressionTest.java
+++ b/interpreter/src/test/java/com/iluwatar/interpreter/NumberExpressionTest.java
@@ -42,7 +42,8 @@ public class NumberExpressionTest extends ExpressionTest {
*
* @return The list of parameters used during this test
*/
- public static Stream expressionProvider() {
+ @Override
+ public Stream expressionProvider() {
return prepareParameters((f, s) -> f);
}
diff --git a/interpreter/src/test/java/com/iluwatar/interpreter/PlusExpressionTest.java b/interpreter/src/test/java/com/iluwatar/interpreter/PlusExpressionTest.java
index ae2423c7a..9687b5399 100644
--- a/interpreter/src/test/java/com/iluwatar/interpreter/PlusExpressionTest.java
+++ b/interpreter/src/test/java/com/iluwatar/interpreter/PlusExpressionTest.java
@@ -38,7 +38,8 @@ public class PlusExpressionTest extends ExpressionTest {
*
* @return The list of parameters used during this test
*/
- public static Stream expressionProvider() {
+ @Override
+ public Stream expressionProvider() {
return prepareParameters((f, s) -> f + s);
}
diff --git a/observer/src/test/java/com/iluwatar/observer/HobbitsTest.java b/observer/src/test/java/com/iluwatar/observer/HobbitsTest.java
index 21e4acd44..8bad7f59e 100644
--- a/observer/src/test/java/com/iluwatar/observer/HobbitsTest.java
+++ b/observer/src/test/java/com/iluwatar/observer/HobbitsTest.java
@@ -33,7 +33,8 @@ import java.util.List;
*/
public class HobbitsTest extends WeatherObserverTest {
- static Collection