diff --git a/.gitignore b/.gitignore
index 5d2cd77e1..589d3fb13 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,4 +11,9 @@ target
.idea
*.iml
*.swp
-datanucleus.log
\ No newline at end of file
+datanucleus.log
+/bin/
+/bin/
+/bin/
+
+data-mapper/src/main/resources/log4j.xml
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
index 60693c5cc..deb436cd2 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -15,4 +15,4 @@ after_success:
- mvn clean test jacoco:report coveralls:report
- bash update-ghpages.sh
-sudo: false
+sudo: false # route the build to the container-based infrastructure for a faster build
diff --git a/CODE_COVERAGE.md b/CODE_COVERAGE.md
new file mode 100644
index 000000000..589c7ad79
--- /dev/null
+++ b/CODE_COVERAGE.md
@@ -0,0 +1,13 @@
+# Code Coverage Report generation
+
+To generate the code coverage report, execute the following command:
+> mvn clean verify
+
+This will generate code coverage report in each of the modules. In order to view the same, open the following file in your browser.
+> target/site/jacoco/index.html
+
+Please note that the above folder is created under each of the modules. For example:
+* adapter/target/site/jacoco/index.html
+* busniess-delegate/target/site/jacoco/index.html
+
+
diff --git a/CONTRIBUTING.MD b/CONTRIBUTING.MD
new file mode 100644
index 000000000..39087fbf1
--- /dev/null
+++ b/CONTRIBUTING.MD
@@ -0,0 +1,4 @@
+This is great you have something to contribute!
+
+Before going any further please read the [wiki](https://github.com/iluwatar/java-design-patterns/wiki)
+with conventions and rules we used for this project.
diff --git a/LICENSE.md b/LICENSE.md
index d1f75f80a..e73cf6618 100644
--- a/LICENSE.md
+++ b/LICENSE.md
@@ -1,6 +1,6 @@
The MIT License (MIT)
-Copyright (c) 2014 Ilkka Seppälä
+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
diff --git a/README.md b/README.md
index ac3aadd67..811d6a17a 100644
--- a/README.md
+++ b/README.md
@@ -2,11 +2,11 @@
that smart and dearly wants an empty line before a heading to be able to
display it as such, e.g. website) -->
-# Design pattern samples in Java
+# Design patterns implemented in Java
[](https://travis-ci.org/iluwatar/java-design-patterns)
[](https://coveralls.io/r/iluwatar/java-design-patterns?branch=master)
-[](https://scan.coverity.com/projects/5634)
+[](https://raw.githubusercontent.com/iluwatar/java-design-patterns/master/LICENSE.md)
[](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
# Introduction
@@ -40,19 +40,7 @@ patterns by any of the following approaches
# How to contribute
-If you are willing to contribute to the project you will find the relevant information in our [developer wiki](https://github.com/iluwatar/java-design-patterns/wiki).
-
-# Credits
-
-* [Effective Java (2nd Edition)](http://www.amazon.com/Effective-Java-Edition-Joshua-Bloch/dp/0321356683)
-* [Java Generics and Collections](http://www.amazon.com/Java-Generics-Collections-Maurice-Naftalin/dp/0596527756/)
-* [Let's Modify the Objects-First Approach into Design-Patterns-First](http://edu.pecinovsky.cz/papers/2006_ITiCSE_Design_Patterns_First.pdf)
-* [Pattern Languages of Program Design](http://www.amazon.com/Pattern-Languages-Program-Design-Coplien/dp/0201607344/ref=sr_1_1)
-* [Presentation Tier Patterns](http://www.javagyan.com/tutorials/corej2eepatterns/presentation-tier-patterns)
-* [Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions](http://www.amazon.com/Functional-Programming-Java-Harnessing-Expressions/dp/1937785467/ref=sr_1_1)
-* [Patterns of Enterprise Application Architecture](http://www.amazon.com/Patterns-Enterprise-Application-Architecture-Martin/dp/0321127420)
-* [Spring Data](http://www.amazon.com/Spring-Data-Mark-Pollack/dp/1449323952/ref=sr_1_1)
-* [J2EE Design Patterns](http://www.amazon.com/J2EE-Design-Patterns-William-Crawford/dp/0596004273/ref=sr_1_2)
+If you are willing to contribute to the project you will find the relevant information in our [developer wiki](https://github.com/iluwatar/java-design-patterns/wiki). We will help you and answer your questions in the [Gitter chatroom](https://gitter.im/iluwatar/java-design-patterns).
# License
diff --git a/abstract-document/README.md b/abstract-document/README.md
new file mode 100644
index 000000000..bf28ff999
--- /dev/null
+++ b/abstract-document/README.md
@@ -0,0 +1,31 @@
+---
+layout: pattern
+title: Abstract Document
+folder: abstract-document
+permalink: /patterns/abstract-document/
+categories: Structural
+tags:
+ - Java
+ - Difficulty-Intermediate
+---
+
+## Intent
+Achieve flexibility of untyped languages and keep the type-safety
+
+
+
+
+
+
+## Applicability
+Use the Abstract Document Pattern when
+
+* there is a need to add new properties on the fly
+* you want a flexible way to organize domain in tree like structure
+* you want more loosely coupled system
+
+
+## Credits
+
+* [Wikipedia: Abstract Document Pattern](https://en.wikipedia.org/wiki/Abstract_Document_Pattern)
+* [Martin Fowler: Dealing with properties](http://martinfowler.com/apsupp/properties.pdf)
\ No newline at end of file
diff --git a/abstract-document/etc/abstract-document-base.png b/abstract-document/etc/abstract-document-base.png
new file mode 100644
index 000000000..13345dbb8
Binary files /dev/null and b/abstract-document/etc/abstract-document-base.png differ
diff --git a/abstract-document/etc/abstract-document-base.ucls b/abstract-document/etc/abstract-document-base.ucls
new file mode 100644
index 000000000..bfe927ed9
--- /dev/null
+++ b/abstract-document/etc/abstract-document-base.ucls
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/abstract-document/etc/abstract-document.png b/abstract-document/etc/abstract-document.png
new file mode 100644
index 000000000..98d186f7e
Binary files /dev/null and b/abstract-document/etc/abstract-document.png differ
diff --git a/abstract-document/etc/abstract-document.ucls b/abstract-document/etc/abstract-document.ucls
new file mode 100644
index 000000000..ad97457fd
--- /dev/null
+++ b/abstract-document/etc/abstract-document.ucls
@@ -0,0 +1,96 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/abstract-document/pom.xml b/abstract-document/pom.xml
new file mode 100644
index 000000000..b7a348d26
--- /dev/null
+++ b/abstract-document/pom.xml
@@ -0,0 +1,42 @@
+
+
+
+ 4.0.0
+
+ java-design-patterns
+ com.iluwatar
+ 1.13.0-SNAPSHOT
+
+ abstract-document
+
+
+ junit
+ junit
+ test
+
+
+
\ No newline at end of file
diff --git a/abstract-document/src/main/java/com/iluwatar/abstractdocument/AbstractDocument.java b/abstract-document/src/main/java/com/iluwatar/abstractdocument/AbstractDocument.java
new file mode 100644
index 000000000..4bf8f0d14
--- /dev/null
+++ b/abstract-document/src/main/java/com/iluwatar/abstractdocument/AbstractDocument.java
@@ -0,0 +1,72 @@
+/**
+ * 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.abstractdocument;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.stream.Stream;
+
+/**
+ * Abstract implementation of Document interface
+ */
+public abstract class AbstractDocument implements Document {
+
+ private final Map properties;
+
+ protected AbstractDocument(Map properties) {
+ Objects.requireNonNull(properties, "properties map is required");
+ this.properties = properties;
+ }
+
+ @Override
+ public Void put(String key, Object value) {
+ properties.put(key, value);
+ return null;
+ }
+
+ @Override
+ public Object get(String key) {
+ return properties.get(key);
+ }
+
+ @Override
+ public Stream children(String key, Function, T> constructor) {
+ Optional>> any = Stream.of(get(key)).filter(el -> el != null)
+ .map(el -> (List>) el).findAny();
+ return any.isPresent() ? any.get().stream().map(constructor) : Stream.empty();
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append(getClass().getName()).append("[");
+ properties.entrySet()
+ .forEach(e -> builder.append("[").append(e.getKey()).append(" : ").append(e.getValue()).append("]"));
+ builder.append("]");
+ return builder.toString();
+ }
+
+}
diff --git a/abstract-document/src/main/java/com/iluwatar/abstractdocument/App.java b/abstract-document/src/main/java/com/iluwatar/abstractdocument/App.java
new file mode 100644
index 000000000..d7758b6f7
--- /dev/null
+++ b/abstract-document/src/main/java/com/iluwatar/abstractdocument/App.java
@@ -0,0 +1,88 @@
+/**
+ * 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.abstractdocument;
+
+import com.iluwatar.abstractdocument.domain.Car;
+import com.iluwatar.abstractdocument.domain.HasModel;
+import com.iluwatar.abstractdocument.domain.HasParts;
+import com.iluwatar.abstractdocument.domain.HasPrice;
+import com.iluwatar.abstractdocument.domain.HasType;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * The Abstract Document pattern enables handling additional, non-static
+ * properties. This pattern uses concept of traits to enable type safety and
+ * separate properties of different classes into set of interfaces.
+ *
+ *
+ * In Abstract Document pattern,({@link AbstractDocument}) fully implements
+ * {@link Document}) interface. Traits are then defined to enable access to
+ * properties in usual, static way.
+ */
+public class App {
+
+ /**
+ * Executes the App
+ */
+ public App() {
+ System.out.println("Constructing parts and car");
+
+ Map carProperties = new HashMap<>();
+ carProperties.put(HasModel.PROPERTY, "300SL");
+ carProperties.put(HasPrice.PROPERTY, 10000L);
+
+ Map wheelProperties = new HashMap<>();
+ wheelProperties.put(HasType.PROPERTY, "wheel");
+ wheelProperties.put(HasModel.PROPERTY, "15C");
+ wheelProperties.put(HasPrice.PROPERTY, 100L);
+
+ Map doorProperties = new HashMap<>();
+ doorProperties.put(HasType.PROPERTY, "door");
+ doorProperties.put(HasModel.PROPERTY, "Lambo");
+ doorProperties.put(HasPrice.PROPERTY, 300L);
+
+ carProperties.put(HasParts.PROPERTY, Arrays.asList(wheelProperties, doorProperties));
+
+ Car car = new Car(carProperties);
+
+ System.out.println("Here is our car:");
+ System.out.println("-> model: " + car.getModel().get());
+ System.out.println("-> price: " + car.getPrice().get());
+ System.out.println("-> parts: ");
+ car.getParts().forEach(p -> System.out
+ .println("\t" + p.getType().get() + "/" + p.getModel().get() + "/" + p.getPrice().get()));
+ }
+
+ /**
+ * Program entry point
+ *
+ * @param args command line args
+ */
+ public static void main(String[] args) {
+ new App();
+ }
+
+}
diff --git a/abstract-document/src/main/java/com/iluwatar/abstractdocument/Document.java b/abstract-document/src/main/java/com/iluwatar/abstractdocument/Document.java
new file mode 100644
index 000000000..7705f37eb
--- /dev/null
+++ b/abstract-document/src/main/java/com/iluwatar/abstractdocument/Document.java
@@ -0,0 +1,59 @@
+/**
+ * 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.abstractdocument;
+
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Stream;
+
+/**
+ * Document interface
+ */
+public interface Document {
+
+ /**
+ * Puts the value related to the key
+ *
+ * @param key element key
+ * @param value element value
+ * @return Void
+ */
+ Void put(String key, Object value);
+
+ /**
+ * Gets the value for the key
+ *
+ * @param key element key
+ * @return value or null
+ */
+ Object get(String key);
+
+ /**
+ * Gets the stream of child documents
+ *
+ * @param key element key
+ * @param constructor constructor of child class
+ * @return child documents
+ */
+ Stream children(String key, Function, T> constructor);
+}
diff --git a/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/Car.java b/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/Car.java
new file mode 100644
index 000000000..e29ee63da
--- /dev/null
+++ b/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/Car.java
@@ -0,0 +1,38 @@
+/**
+ * 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.abstractdocument.domain;
+
+import java.util.Map;
+
+import com.iluwatar.abstractdocument.AbstractDocument;
+
+/**
+ * Car entity
+ */
+public class Car extends AbstractDocument implements HasModel, HasPrice, HasParts {
+
+ public Car(Map properties) {
+ super(properties);
+ }
+
+}
diff --git a/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/HasModel.java b/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/HasModel.java
new file mode 100644
index 000000000..fbd8c0d7f
--- /dev/null
+++ b/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/HasModel.java
@@ -0,0 +1,40 @@
+/**
+ * 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.abstractdocument.domain;
+
+import java.util.Optional;
+
+import com.iluwatar.abstractdocument.Document;
+
+/**
+ * HasModel trait for static access to 'model' property
+ */
+public interface HasModel extends Document {
+
+ String PROPERTY = "model";
+
+ default Optional getModel() {
+ return Optional.ofNullable((String) get(PROPERTY));
+ }
+
+}
diff --git a/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/HasParts.java b/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/HasParts.java
new file mode 100644
index 000000000..581702cc9
--- /dev/null
+++ b/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/HasParts.java
@@ -0,0 +1,40 @@
+/**
+ * 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.abstractdocument.domain;
+
+import java.util.stream.Stream;
+
+import com.iluwatar.abstractdocument.Document;
+
+/**
+ * HasParts trait for static access to 'parts' property
+ */
+public interface HasParts extends Document {
+
+ String PROPERTY = "parts";
+
+ default Stream getParts() {
+ return children(PROPERTY, Part::new);
+ }
+
+}
diff --git a/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/HasPrice.java b/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/HasPrice.java
new file mode 100644
index 000000000..3d1d0e3e7
--- /dev/null
+++ b/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/HasPrice.java
@@ -0,0 +1,40 @@
+/**
+ * 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.abstractdocument.domain;
+
+import java.util.Optional;
+
+import com.iluwatar.abstractdocument.Document;
+
+/**
+ * HasPrice trait for static access to 'price' property
+ */
+public interface HasPrice extends Document {
+
+ String PROPERTY = "price";
+
+ default Optional getPrice() {
+ return Optional.ofNullable((Number) get(PROPERTY));
+ }
+
+}
diff --git a/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/HasType.java b/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/HasType.java
new file mode 100644
index 000000000..b0f292bb6
--- /dev/null
+++ b/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/HasType.java
@@ -0,0 +1,40 @@
+/**
+ * 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.abstractdocument.domain;
+
+import com.iluwatar.abstractdocument.Document;
+
+import java.util.Optional;
+
+/**
+ * HasType trait for static access to 'type' property
+ */
+public interface HasType extends Document {
+
+ String PROPERTY = "type";
+
+ default Optional getType() {
+ return Optional.ofNullable((String) get(PROPERTY));
+ }
+
+}
diff --git a/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/Part.java b/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/Part.java
new file mode 100644
index 000000000..e42f099d9
--- /dev/null
+++ b/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/Part.java
@@ -0,0 +1,38 @@
+/**
+ * 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.abstractdocument.domain;
+
+import java.util.Map;
+
+import com.iluwatar.abstractdocument.AbstractDocument;
+
+/**
+ * Part entity
+ */
+public class Part extends AbstractDocument implements HasType, HasModel, HasPrice {
+
+ public Part(Map properties) {
+ super(properties);
+ }
+
+}
diff --git a/abstract-document/src/test/java/com/iluwatar/abstractdocument/AbstractDocumentTest.java b/abstract-document/src/test/java/com/iluwatar/abstractdocument/AbstractDocumentTest.java
new file mode 100644
index 000000000..b6467e232
--- /dev/null
+++ b/abstract-document/src/test/java/com/iluwatar/abstractdocument/AbstractDocumentTest.java
@@ -0,0 +1,88 @@
+/**
+ * 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.abstractdocument;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Stream;
+
+import static junit.framework.TestCase.assertEquals;
+import static junit.framework.TestCase.assertNotNull;
+
+/**
+ * AbstractDocument test class
+ */
+public class AbstractDocumentTest {
+
+ private static final String KEY = "key";
+ private static final String VALUE = "value";
+
+ private class DocumentImplementation extends AbstractDocument {
+
+ DocumentImplementation(Map properties) {
+ super(properties);
+ }
+ }
+
+ private DocumentImplementation document = new DocumentImplementation(new HashMap<>());
+
+ @Test
+ public void shouldPutAndGetValue() {
+ document.put(KEY, VALUE);
+ assertEquals(VALUE, document.get(KEY));
+ }
+
+ @Test
+ public void shouldRetrieveChildren() {
+ Map child1 = new HashMap<>();
+ Map child2 = new HashMap<>();
+ List> children = Arrays.asList(child1, child2);
+
+ document.put(KEY, children);
+
+ Stream childrenStream = document.children(KEY, DocumentImplementation::new);
+ assertNotNull(children);
+ assertEquals(2, childrenStream.count());
+ }
+
+ @Test
+ public void shouldRetrieveEmptyStreamForNonExistingChildren() {
+ Stream children = document.children(KEY, DocumentImplementation::new);
+ assertNotNull(children);
+ assertEquals(0, children.count());
+ }
+
+ @Test
+ public void shouldIncludePropsInToString() {
+ Map props = new HashMap<>();
+ props.put(KEY, VALUE);
+ DocumentImplementation document = new DocumentImplementation(props);
+ assertNotNull(document.toString().contains(KEY));
+ assertNotNull(document.toString().contains(VALUE));
+ }
+
+}
diff --git a/abstract-document/src/test/java/com/iluwatar/abstractdocument/AppTest.java b/abstract-document/src/test/java/com/iluwatar/abstractdocument/AppTest.java
new file mode 100644
index 000000000..787ae3aa6
--- /dev/null
+++ b/abstract-document/src/test/java/com/iluwatar/abstractdocument/AppTest.java
@@ -0,0 +1,37 @@
+/**
+ * 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.abstractdocument;
+
+import org.junit.Test;
+
+/**
+ * Simple App test
+ */
+public class AppTest {
+
+ @Test
+ public void shouldExecuteAppWithoutException() {
+ App.main(null);
+ }
+
+}
diff --git a/abstract-document/src/test/java/com/iluwatar/abstractdocument/DomainTest.java b/abstract-document/src/test/java/com/iluwatar/abstractdocument/DomainTest.java
new file mode 100644
index 000000000..437244a3d
--- /dev/null
+++ b/abstract-document/src/test/java/com/iluwatar/abstractdocument/DomainTest.java
@@ -0,0 +1,77 @@
+/**
+ * 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.abstractdocument;
+
+import com.iluwatar.abstractdocument.domain.Car;
+import com.iluwatar.abstractdocument.domain.HasModel;
+import com.iluwatar.abstractdocument.domain.HasParts;
+import com.iluwatar.abstractdocument.domain.HasPrice;
+import com.iluwatar.abstractdocument.domain.HasType;
+import com.iluwatar.abstractdocument.domain.Part;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+import static junit.framework.TestCase.assertEquals;
+
+/**
+ * Test for Part and Car
+ */
+public class DomainTest {
+
+ private static final String TEST_PART_TYPE = "test-part-type";
+ private static final String TEST_PART_MODEL = "test-part-model";
+ private static final long TEST_PART_PRICE = 0L;
+
+ private static final String TEST_CAR_MODEL = "test-car-model";
+ private static final long TEST_CAR_PRICE = 1L;
+
+ @Test
+ public void shouldConstructPart() {
+ Map partProperties = new HashMap<>();
+ partProperties.put(HasType.PROPERTY, TEST_PART_TYPE);
+ partProperties.put(HasModel.PROPERTY, TEST_PART_MODEL);
+ partProperties.put(HasPrice.PROPERTY, TEST_PART_PRICE);
+ Part part = new Part(partProperties);
+
+ assertEquals(TEST_PART_TYPE, part.getType().get());
+ assertEquals(TEST_PART_MODEL, part.getModel().get());
+ assertEquals(TEST_PART_PRICE, part.getPrice().get());
+ }
+
+ @Test
+ public void shouldConstructCar() {
+ Map carProperties = new HashMap<>();
+ carProperties.put(HasModel.PROPERTY, TEST_CAR_MODEL);
+ carProperties.put(HasPrice.PROPERTY, TEST_CAR_PRICE);
+ carProperties.put(HasParts.PROPERTY, Arrays.asList(new HashMap<>(), new HashMap<>()));
+ Car car = new Car(carProperties);
+
+ assertEquals(TEST_CAR_MODEL, car.getModel().get());
+ assertEquals(TEST_CAR_PRICE, car.getPrice().get());
+ assertEquals(2, car.getParts().count());
+ }
+
+}
diff --git a/abstract-factory/index.md b/abstract-factory/README.md
similarity index 81%
rename from abstract-factory/index.md
rename to abstract-factory/README.md
index 7db699a99..485599b98 100644
--- a/abstract-factory/index.md
+++ b/abstract-factory/README.md
@@ -7,24 +7,30 @@ categories: Creational
tags:
- Java
- Gang Of Four
+ - Difficulty-Intermediate
---
-**Intent:** Provide an interface for creating families of related or dependent
+## Also known as
+Kit
+
+## Intent
+Provide an interface for creating families of related or dependent
objects without specifying their concrete classes.

-**Applicability:** Use the Abstract Factory pattern when
+## Applicability
+Use the Abstract Factory pattern when
* a system should be independent of how its products are created, composed and represented
* a system should be configured with one of multiple families of products
* a family of related product objects is designed to be used together, and you need to enforce this constraint
* you want to provide a class library of products, and you want to reveal just their interfaces, not their implementations
-**Real world examples:**
+## Real world examples
* [javax.xml.parsers.DocumentBuilderFactory](http://docs.oracle.com/javase/8/docs/api/javax/xml/parsers/DocumentBuilderFactory.html)
-**Credits**
+## Credits
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)
diff --git a/abstract-factory/pom.xml b/abstract-factory/pom.xml
index bb9df6bc9..ec0f700a5 100644
--- a/abstract-factory/pom.xml
+++ b/abstract-factory/pom.xml
@@ -1,11 +1,35 @@
+
4.0.0
com.iluwatar
java-design-patterns
- 1.7.0
+ 1.13.0-SNAPSHOT
abstract-factory
diff --git a/abstract-factory/src/main/java/com/iluwatar/abstractfactory/App.java b/abstract-factory/src/main/java/com/iluwatar/abstractfactory/App.java
index 618b98c52..aae396f1d 100644
--- a/abstract-factory/src/main/java/com/iluwatar/abstractfactory/App.java
+++ b/abstract-factory/src/main/java/com/iluwatar/abstractfactory/App.java
@@ -1,82 +1,115 @@
+/**
+ * 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.abstractfactory;
-
/**
*
- * The Abstract Factory pattern provides a way to encapsulate a group of individual
- * factories that have a common theme without specifying their concrete classes. In
- * normal usage, the client software creates a concrete implementation of the abstract
- * factory and then uses the generic interface of the factory to create the concrete
- * objects that are part of the theme. The client does not know (or care) which
- * concrete objects it gets from each of these internal factories, since it uses only
- * the generic interfaces of their products. This pattern separates the details of
- * implementation of a set of objects from their general usage and relies on object
- * composition, as object creation is implemented in methods exposed in the factory
- * interface.
+ * The Abstract Factory pattern provides a way to encapsulate a group of individual factories that have a common theme
+ * without specifying their concrete classes. In normal usage, the client software creates a concrete implementation of
+ * the abstract factory and then uses the generic interface of the factory to create the concrete objects that are part
+ * of the theme. The client does not know (or care) which concrete objects it gets from each of these internal
+ * factories, since it uses only the generic interfaces of their products. This pattern separates the details of
+ * implementation of a set of objects from their general usage and relies on object composition, as object creation is
+ * implemented in methods exposed in the factory interface.
*
- * The essence of the Abstract Factory pattern is a factory interface
- * ({@link KingdomFactory}) and its implementations ({@link ElfKingdomFactory},
- * {@link OrcKingdomFactory}). The example uses both concrete implementations to
- * create a king, a castle and an army.
+ * The essence of the Abstract Factory pattern is a factory interface ({@link KingdomFactory}) and its implementations (
+ * {@link ElfKingdomFactory}, {@link OrcKingdomFactory}). The example uses both concrete implementations to create a
+ * king, a castle and an army.
*
*/
public class App {
- private King king;
- private Castle castle;
- private Army army;
+ private King king;
+ private Castle castle;
+ private Army army;
+
+ /**
+ * Creates kingdom
+ */
+ public void createKingdom(final KingdomFactory factory) {
+ setKing(factory.createKing());
+ setCastle(factory.createCastle());
+ setArmy(factory.createArmy());
+ }
+
+ King getKing(final KingdomFactory factory) {
+ return factory.createKing();
+ }
+
+ public King getKing() {
+ return king;
+ }
+
+ private void setKing(final King king) {
+ this.king = king;
+ }
+
+ Castle getCastle(final KingdomFactory factory) {
+ return factory.createCastle();
+ }
+
+ public Castle getCastle() {
+ return castle;
+ }
+
+ private void setCastle(final Castle castle) {
+ this.castle = castle;
+ }
+
+ Army getArmy(final KingdomFactory factory) {
+ return factory.createArmy();
+ }
+
+ public Army getArmy() {
+ return army;
+ }
+
+ private void setArmy(final Army army) {
+ this.army = army;
+ }
+
+ /**
+ * Program entry point
+ *
+ * @param args
+ * command line args
+ */
+ public static void main(String[] args) {
+
+ App app = new App();
+
+ System.out.println("Elf Kingdom");
+ app.createKingdom(new ElfKingdomFactory());
+ System.out.println(app.getArmy().getDescription());
+ System.out.println(app.getCastle().getDescription());
+ System.out.println(app.getKing().getDescription());
+
+ System.out.println("\nOrc Kingdom");
+ app.createKingdom(new OrcKingdomFactory());
+ System.out.println(app.getArmy().getDescription());
+ System.out.println(app.getCastle().getDescription());
+ System.out.println(app.getKing().getDescription());
+
+ }
- /**
- * Creates kingdom
- * @param factory
- */
- public void createKingdom(final KingdomFactory factory) {
- setKing(factory.createKing());
- setCastle(factory.createCastle());
- setArmy(factory.createArmy());
- }
-
- ElfKingdomFactory getElfKingdomFactory() {
- return new ElfKingdomFactory();
- }
-
- OrcKingdomFactory getOrcKingdomFactory() {
- return new OrcKingdomFactory();
- }
-
- King getKing(final KingdomFactory factory) {
- return factory.createKing();
- }
-
- Castle getCastle(final KingdomFactory factory) {
- return factory.createCastle();
- }
-
- Army getArmy(final KingdomFactory factory) {
- return factory.createArmy();
- }
-
- public King getKing() {
- return king;
- }
-
- private void setKing(final King king) {
- this.king = king;
- }
-
- public Castle getCastle() {
- return castle;
- }
-
- private void setCastle(final Castle castle) {
- this.castle = castle;
- }
-
- public Army getArmy() {
- return army;
- }
-
- private void setArmy(final Army army) {
- this.army = army;
- }
}
diff --git a/abstract-factory/src/main/java/com/iluwatar/abstractfactory/Army.java b/abstract-factory/src/main/java/com/iluwatar/abstractfactory/Army.java
index 333b5c2cd..d9e7f9989 100644
--- a/abstract-factory/src/main/java/com/iluwatar/abstractfactory/Army.java
+++ b/abstract-factory/src/main/java/com/iluwatar/abstractfactory/Army.java
@@ -1,3 +1,25 @@
+/**
+ * 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.abstractfactory;
/**
@@ -7,5 +29,5 @@ package com.iluwatar.abstractfactory;
*/
public interface Army {
- String getDescription();
+ String getDescription();
}
diff --git a/abstract-factory/src/main/java/com/iluwatar/abstractfactory/Castle.java b/abstract-factory/src/main/java/com/iluwatar/abstractfactory/Castle.java
index 0290cb67c..adea2327e 100644
--- a/abstract-factory/src/main/java/com/iluwatar/abstractfactory/Castle.java
+++ b/abstract-factory/src/main/java/com/iluwatar/abstractfactory/Castle.java
@@ -1,3 +1,25 @@
+/**
+ * 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.abstractfactory;
/**
@@ -7,5 +29,5 @@ package com.iluwatar.abstractfactory;
*/
public interface Castle {
- String getDescription();
+ String getDescription();
}
diff --git a/abstract-factory/src/main/java/com/iluwatar/abstractfactory/ElfArmy.java b/abstract-factory/src/main/java/com/iluwatar/abstractfactory/ElfArmy.java
index 410f46951..2969a8615 100644
--- a/abstract-factory/src/main/java/com/iluwatar/abstractfactory/ElfArmy.java
+++ b/abstract-factory/src/main/java/com/iluwatar/abstractfactory/ElfArmy.java
@@ -1,3 +1,25 @@
+/**
+ * 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.abstractfactory;
/**
@@ -7,10 +29,10 @@ package com.iluwatar.abstractfactory;
*/
public class ElfArmy implements Army {
- static final String DESCRIPTION = "This is the Elven Army!";
+ static final String DESCRIPTION = "This is the Elven Army!";
- @Override
- public String getDescription() {
- return DESCRIPTION;
- }
+ @Override
+ public String getDescription() {
+ return DESCRIPTION;
+ }
}
diff --git a/abstract-factory/src/main/java/com/iluwatar/abstractfactory/ElfCastle.java b/abstract-factory/src/main/java/com/iluwatar/abstractfactory/ElfCastle.java
index fe2e9a0e7..5321bfeba 100644
--- a/abstract-factory/src/main/java/com/iluwatar/abstractfactory/ElfCastle.java
+++ b/abstract-factory/src/main/java/com/iluwatar/abstractfactory/ElfCastle.java
@@ -1,3 +1,25 @@
+/**
+ * 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.abstractfactory;
/**
@@ -7,10 +29,10 @@ package com.iluwatar.abstractfactory;
*/
public class ElfCastle implements Castle {
- static final String DESCRIPTION = "This is the Elven castle!";
+ static final String DESCRIPTION = "This is the Elven castle!";
- @Override
- public String getDescription() {
- return DESCRIPTION;
- }
+ @Override
+ public String getDescription() {
+ return DESCRIPTION;
+ }
}
diff --git a/abstract-factory/src/main/java/com/iluwatar/abstractfactory/ElfKing.java b/abstract-factory/src/main/java/com/iluwatar/abstractfactory/ElfKing.java
index 66571ee01..1eb892e6f 100644
--- a/abstract-factory/src/main/java/com/iluwatar/abstractfactory/ElfKing.java
+++ b/abstract-factory/src/main/java/com/iluwatar/abstractfactory/ElfKing.java
@@ -1,3 +1,25 @@
+/**
+ * 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.abstractfactory;
/**
@@ -7,10 +29,10 @@ package com.iluwatar.abstractfactory;
*/
public class ElfKing implements King {
- static final String DESCRIPTION = "This is the Elven king!";
-
- @Override
- public String getDescription() {
- return DESCRIPTION;
- }
+ static final String DESCRIPTION = "This is the Elven king!";
+
+ @Override
+ public String getDescription() {
+ return DESCRIPTION;
+ }
}
diff --git a/abstract-factory/src/main/java/com/iluwatar/abstractfactory/ElfKingdomFactory.java b/abstract-factory/src/main/java/com/iluwatar/abstractfactory/ElfKingdomFactory.java
index 0d62fa5f2..9d48ab25f 100644
--- a/abstract-factory/src/main/java/com/iluwatar/abstractfactory/ElfKingdomFactory.java
+++ b/abstract-factory/src/main/java/com/iluwatar/abstractfactory/ElfKingdomFactory.java
@@ -1,3 +1,25 @@
+/**
+ * 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.abstractfactory;
/**
@@ -7,16 +29,16 @@ package com.iluwatar.abstractfactory;
*/
public class ElfKingdomFactory implements KingdomFactory {
- public Castle createCastle() {
- return new ElfCastle();
- }
+ public Castle createCastle() {
+ return new ElfCastle();
+ }
- public King createKing() {
- return new ElfKing();
- }
+ public King createKing() {
+ return new ElfKing();
+ }
- public Army createArmy() {
- return new ElfArmy();
- }
+ public Army createArmy() {
+ return new ElfArmy();
+ }
}
diff --git a/abstract-factory/src/main/java/com/iluwatar/abstractfactory/King.java b/abstract-factory/src/main/java/com/iluwatar/abstractfactory/King.java
index c7b9a867c..ec1cff4d1 100644
--- a/abstract-factory/src/main/java/com/iluwatar/abstractfactory/King.java
+++ b/abstract-factory/src/main/java/com/iluwatar/abstractfactory/King.java
@@ -1,3 +1,25 @@
+/**
+ * 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.abstractfactory;
/**
@@ -7,5 +29,5 @@ package com.iluwatar.abstractfactory;
*/
public interface King {
- String getDescription();
+ String getDescription();
}
diff --git a/abstract-factory/src/main/java/com/iluwatar/abstractfactory/KingdomFactory.java b/abstract-factory/src/main/java/com/iluwatar/abstractfactory/KingdomFactory.java
index 00bcd1755..d8258fd8b 100644
--- a/abstract-factory/src/main/java/com/iluwatar/abstractfactory/KingdomFactory.java
+++ b/abstract-factory/src/main/java/com/iluwatar/abstractfactory/KingdomFactory.java
@@ -1,3 +1,25 @@
+/**
+ * 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.abstractfactory;
/**
@@ -7,10 +29,10 @@ package com.iluwatar.abstractfactory;
*/
public interface KingdomFactory {
- Castle createCastle();
+ Castle createCastle();
- King createKing();
+ King createKing();
- Army createArmy();
+ Army createArmy();
}
diff --git a/abstract-factory/src/main/java/com/iluwatar/abstractfactory/OrcArmy.java b/abstract-factory/src/main/java/com/iluwatar/abstractfactory/OrcArmy.java
index 108700511..261ad37c9 100644
--- a/abstract-factory/src/main/java/com/iluwatar/abstractfactory/OrcArmy.java
+++ b/abstract-factory/src/main/java/com/iluwatar/abstractfactory/OrcArmy.java
@@ -1,3 +1,25 @@
+/**
+ * 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.abstractfactory;
/**
@@ -7,10 +29,10 @@ package com.iluwatar.abstractfactory;
*/
public class OrcArmy implements Army {
- static final String DESCRIPTION = "This is the Orc Army!";
+ static final String DESCRIPTION = "This is the Orc Army!";
- @Override
- public String getDescription() {
- return DESCRIPTION;
- }
+ @Override
+ public String getDescription() {
+ return DESCRIPTION;
+ }
}
diff --git a/abstract-factory/src/main/java/com/iluwatar/abstractfactory/OrcCastle.java b/abstract-factory/src/main/java/com/iluwatar/abstractfactory/OrcCastle.java
index 5012f9200..cb2a92652 100644
--- a/abstract-factory/src/main/java/com/iluwatar/abstractfactory/OrcCastle.java
+++ b/abstract-factory/src/main/java/com/iluwatar/abstractfactory/OrcCastle.java
@@ -1,3 +1,25 @@
+/**
+ * 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.abstractfactory;
/**
@@ -7,10 +29,10 @@ package com.iluwatar.abstractfactory;
*/
public class OrcCastle implements Castle {
- static final String DESCRIPTION = "This is the Orc castle!";
+ static final String DESCRIPTION = "This is the Orc castle!";
- @Override
- public String getDescription() {
- return DESCRIPTION;
- }
+ @Override
+ public String getDescription() {
+ return DESCRIPTION;
+ }
}
diff --git a/abstract-factory/src/main/java/com/iluwatar/abstractfactory/OrcKing.java b/abstract-factory/src/main/java/com/iluwatar/abstractfactory/OrcKing.java
index a5657d4e4..ba7576492 100644
--- a/abstract-factory/src/main/java/com/iluwatar/abstractfactory/OrcKing.java
+++ b/abstract-factory/src/main/java/com/iluwatar/abstractfactory/OrcKing.java
@@ -1,3 +1,25 @@
+/**
+ * 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.abstractfactory;
/**
@@ -7,10 +29,10 @@ package com.iluwatar.abstractfactory;
*/
public class OrcKing implements King {
-static final String DESCRIPTION = "This is the Orc king!";
-
- @Override
- public String getDescription() {
- return DESCRIPTION;
- }
+ static final String DESCRIPTION = "This is the Orc king!";
+
+ @Override
+ public String getDescription() {
+ return DESCRIPTION;
+ }
}
diff --git a/abstract-factory/src/main/java/com/iluwatar/abstractfactory/OrcKingdomFactory.java b/abstract-factory/src/main/java/com/iluwatar/abstractfactory/OrcKingdomFactory.java
index 4fdea6656..2d740cf0d 100644
--- a/abstract-factory/src/main/java/com/iluwatar/abstractfactory/OrcKingdomFactory.java
+++ b/abstract-factory/src/main/java/com/iluwatar/abstractfactory/OrcKingdomFactory.java
@@ -1,3 +1,25 @@
+/**
+ * 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.abstractfactory;
/**
@@ -7,16 +29,15 @@ package com.iluwatar.abstractfactory;
*/
public class OrcKingdomFactory implements KingdomFactory {
- public Castle createCastle() {
- return new OrcCastle();
- }
+ public Castle createCastle() {
+ return new OrcCastle();
+ }
- public King createKing() {
- return new OrcKing();
- }
-
- public Army createArmy() {
- return new OrcArmy();
- }
+ public King createKing() {
+ return new OrcKing();
+ }
+ public Army createArmy() {
+ return new OrcArmy();
+ }
}
diff --git a/abstract-factory/src/test/java/com/iluwatar/abstractfactory/AbstractFactoryTest.java b/abstract-factory/src/test/java/com/iluwatar/abstractfactory/AbstractFactoryTest.java
new file mode 100644
index 000000000..216f0443a
--- /dev/null
+++ b/abstract-factory/src/test/java/com/iluwatar/abstractfactory/AbstractFactoryTest.java
@@ -0,0 +1,100 @@
+/**
+ * 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.abstractfactory;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class AbstractFactoryTest {
+
+ private App app = new App();
+ private KingdomFactory elfFactory;
+ private KingdomFactory orcFactory;
+
+ @Before
+ public void setUp() {
+ elfFactory = new ElfKingdomFactory();
+ orcFactory = new OrcKingdomFactory();
+ }
+
+ @Test
+ public void king() {
+ final King elfKing = app.getKing(elfFactory);
+ assertTrue(elfKing instanceof ElfKing);
+ assertEquals(ElfKing.DESCRIPTION, elfKing.getDescription());
+ final King orcKing = app.getKing(orcFactory);
+ assertTrue(orcKing instanceof OrcKing);
+ assertEquals(OrcKing.DESCRIPTION, orcKing.getDescription());
+ }
+
+ @Test
+ public void castle() {
+ final Castle elfCastle = app.getCastle(elfFactory);
+ assertTrue(elfCastle instanceof ElfCastle);
+ assertEquals(ElfCastle.DESCRIPTION, elfCastle.getDescription());
+ final Castle orcCastle = app.getCastle(orcFactory);
+ assertTrue(orcCastle instanceof OrcCastle);
+ assertEquals(OrcCastle.DESCRIPTION, orcCastle.getDescription());
+ }
+
+ @Test
+ public void army() {
+ final Army elfArmy = app.getArmy(elfFactory);
+ assertTrue(elfArmy instanceof ElfArmy);
+ assertEquals(ElfArmy.DESCRIPTION, elfArmy.getDescription());
+ final Army orcArmy = app.getArmy(orcFactory);
+ assertTrue(orcArmy instanceof OrcArmy);
+ assertEquals(OrcArmy.DESCRIPTION, orcArmy.getDescription());
+ }
+
+ @Test
+ public void createElfKingdom() {
+ app.createKingdom(elfFactory);
+ final King king = app.getKing();
+ final Castle castle = app.getCastle();
+ final Army army = app.getArmy();
+ assertTrue(king instanceof ElfKing);
+ assertEquals(ElfKing.DESCRIPTION, king.getDescription());
+ assertTrue(castle instanceof ElfCastle);
+ assertEquals(ElfCastle.DESCRIPTION, castle.getDescription());
+ assertTrue(army instanceof ElfArmy);
+ assertEquals(ElfArmy.DESCRIPTION, army.getDescription());
+ }
+
+ @Test
+ public void createOrcKingdom() {
+ app.createKingdom(orcFactory);
+ final King king = app.getKing();
+ final Castle castle = app.getCastle();
+ final Army army = app.getArmy();
+ assertTrue(king instanceof OrcKing);
+ assertEquals(OrcKing.DESCRIPTION, king.getDescription());
+ assertTrue(castle instanceof OrcCastle);
+ assertEquals(OrcCastle.DESCRIPTION, castle.getDescription());
+ assertTrue(army instanceof OrcArmy);
+ assertEquals(OrcArmy.DESCRIPTION, army.getDescription());
+ }
+}
diff --git a/abstract-factory/src/test/java/com/iluwatar/abstractfactory/AppTest.java b/abstract-factory/src/test/java/com/iluwatar/abstractfactory/AppTest.java
index 4d3659245..a965284f7 100644
--- a/abstract-factory/src/test/java/com/iluwatar/abstractfactory/AppTest.java
+++ b/abstract-factory/src/test/java/com/iluwatar/abstractfactory/AppTest.java
@@ -1,77 +1,38 @@
+/**
+ * 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.abstractfactory;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import org.junit.Before;
import org.junit.Test;
-public class AppTest {
+import java.io.IOException;
- private App app = new App();
- private KingdomFactory elfFactory;
- private KingdomFactory orcFactory;
-
- @Before
- public void setUp() {
- elfFactory = app.getElfKingdomFactory();
- orcFactory = app.getOrcKingdomFactory();
- }
-
- @Test
- public void king() {
- final King elfKing = app.getKing(elfFactory);
- assertTrue(elfKing instanceof ElfKing);
- assertEquals(ElfKing.DESCRIPTION, elfKing.getDescription());
- final King orcKing = app.getKing(orcFactory);
- assertTrue(orcKing instanceof OrcKing);
- assertEquals(OrcKing.DESCRIPTION, orcKing.getDescription());
- }
-
- @Test
- public void castle() {
- final Castle elfCastle = app.getCastle(elfFactory);
- assertTrue(elfCastle instanceof ElfCastle);
- assertEquals(ElfCastle.DESCRIPTION, elfCastle.getDescription());
- final Castle orcCastle = app.getCastle(orcFactory);
- assertTrue(orcCastle instanceof OrcCastle);
- assertEquals(OrcCastle.DESCRIPTION, orcCastle.getDescription());
- }
-
- @Test
- public void army() {
- final Army elfArmy = app.getArmy(elfFactory);
- assertTrue(elfArmy instanceof ElfArmy);
- assertEquals(ElfArmy.DESCRIPTION, elfArmy.getDescription());
- final Army orcArmy = app.getArmy(orcFactory);
- assertTrue(orcArmy instanceof OrcArmy);
- assertEquals(OrcArmy.DESCRIPTION, orcArmy.getDescription());
- }
-
- @Test
- public void createElfKingdom() {
- app.createKingdom(elfFactory);
- final King king = app.getKing();
- final Castle castle = app.getCastle();
- final Army army = app.getArmy();
- assertTrue(king instanceof ElfKing);
- assertEquals(ElfKing.DESCRIPTION, king.getDescription());
- assertTrue(castle instanceof ElfCastle);
- assertEquals(ElfCastle.DESCRIPTION, castle.getDescription());
- assertTrue(army instanceof ElfArmy);
- assertEquals(ElfArmy.DESCRIPTION, army.getDescription());
- }
-
- @Test
- public void createOrcKingdom() {
- app.createKingdom(orcFactory);
- final King king = app.getKing();
- final Castle castle = app.getCastle();
- final Army army = app.getArmy();
- assertTrue(king instanceof OrcKing);
- assertEquals(OrcKing.DESCRIPTION, king.getDescription());
- assertTrue(castle instanceof OrcCastle);
- assertEquals(OrcCastle.DESCRIPTION, castle.getDescription());
- assertTrue(army instanceof OrcArmy);
- assertEquals(OrcArmy.DESCRIPTION, army.getDescription());
- }
+/**
+ * Tests that Abstract Factory example runs without errors.
+ */
+public class AppTest {
+ @Test
+ public void test() throws IOException {
+ String[] args = {};
+ App.main(args);
+ }
}
diff --git a/adapter/index.md b/adapter/README.md
similarity index 72%
rename from adapter/index.md
rename to adapter/README.md
index be9a87228..ea3baa7fa 100644
--- a/adapter/index.md
+++ b/adapter/README.md
@@ -7,24 +7,31 @@ categories: Structural
tags:
- Java
- Gang Of Four
+ - Difficulty-Beginner
---
-**Intent:** Convert the interface of a class into another interface the clients
+## Also known as
+Wrapper
+
+## Intent
+Convert the interface of a class into another interface the clients
expect. Adapter lets classes work together that couldn't otherwise because of
incompatible interfaces.
-
+
-**Applicability:** Use the Adapter pattern when
+## Applicability
+Use the Adapter pattern when
* you want to use an existing class, and its interface does not match the one you need
* you want to create a reusable class that cooperates with unrelated or unforeseen classes, that is, classes that don't necessarily have compatible interfaces
* you need to use several existing subclasses, but it's impractical to adapt their interface by subclassing every one. An object adapter can adapt the interface of its parent class.
-**Real world examples:**
+## Real world examples
* [java.util.Arrays#asList()](http://docs.oracle.com/javase/8/docs/api/java/util/Arrays.html#asList%28T...%29)
-**Credits**
+## Credits
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)
+* [J2EE Design Patterns](http://www.amazon.com/J2EE-Design-Patterns-William-Crawford/dp/0596004273/ref=sr_1_2)
diff --git a/adapter/etc/adapter.png b/adapter/etc/adapter.png
index 511bb5880..f43358b04 100644
Binary files a/adapter/etc/adapter.png and b/adapter/etc/adapter.png differ
diff --git a/adapter/etc/adapter.ucls b/adapter/etc/adapter.ucls
index 8c09f0399..290ff544e 100644
--- a/adapter/etc/adapter.ucls
+++ b/adapter/etc/adapter.ucls
@@ -1,61 +1,61 @@
-
-
-
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
+
+
+
+
-
+
+
+
+
+
-
-
+
+
diff --git a/adapter/etc/adapter_1.png b/adapter/etc/adapter_1.png
deleted file mode 100644
index 64eb34b84..000000000
Binary files a/adapter/etc/adapter_1.png and /dev/null differ
diff --git a/adapter/pom.xml b/adapter/pom.xml
index d07d26b94..2c99796f4 100644
--- a/adapter/pom.xml
+++ b/adapter/pom.xml
@@ -1,11 +1,35 @@
+
4.0.0
com.iluwatar
java-design-patterns
- 1.7.0
+ 1.13.0-SNAPSHOT
adapter
@@ -14,5 +38,10 @@
junit
test
+
+ org.mockito
+ mockito-core
+ test
+
diff --git a/adapter/src/main/java/com/iluwatar/adapter/App.java b/adapter/src/main/java/com/iluwatar/adapter/App.java
index ed036b391..29c313b59 100644
--- a/adapter/src/main/java/com/iluwatar/adapter/App.java
+++ b/adapter/src/main/java/com/iluwatar/adapter/App.java
@@ -1,31 +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.adapter;
/**
+ * An adapter helps two incompatible interfaces to work together. This is the real world definition
+ * for an adapter. Interfaces may be incompatible but the inner functionality should suit the need.
+ * The Adapter design pattern allows otherwise incompatible classes to work together by converting
+ * the interface of one class into an interface expected by the clients.
*
- * An adapter helps two incompatible interfaces to work together. This is the real
- * world definition for an adapter. Interfaces may be incompatible but the inner
- * functionality should suit the need. The Adapter design pattern allows otherwise
- * incompatible classes to work together by converting the interface of one class
- * into an interface expected by the clients.
*
- * There are two variations of the Adapter pattern: The class adapter implements
- * the adaptee's interface whereas the object adapter uses composition to
- * contain the adaptee in the adapter object. This example uses the object
- * adapter approach.
+ * There are two variations of the Adapter pattern: The class adapter implements the adaptee's
+ * interface whereas the object adapter uses composition to contain the adaptee in the adapter
+ * object. This example uses the object adapter approach.
+ *
*
- * The Adapter ({@link GnomeEngineer}) converts the interface of the target class
- * ({@link GoblinGlider}) into a suitable one expected by the client
- * ({@link GnomeEngineeringManager}).
- *
+ * The Adapter ({@link BattleFishingBoat}) converts the interface of the adaptee class (
+ * {@link FishingBoat}) into a suitable one expected by the client ( {@link BattleShip} ).
+ *
+ *
+ * The story of this implementation is this.
+ * Pirates are coming! we need a {@link BattleShip} to fight! We have a {@link FishingBoat} and our
+ * captain. We have no time to make up a new ship! we need to reuse this {@link FishingBoat}. The
+ * captain needs a battleship which can fire and move. The spec is in {@link BattleShip}. We will
+ * use the Adapter pattern to reuse {@link FishingBoat}.
+ *
*/
public class App {
- /**
- * Program entry point
- * @param args command line args
- */
- public static void main(String[] args) {
- Engineer manager = new GnomeEngineeringManager();
- manager.operateDevice();
- }
+ /**
+ * Program entry point.
+ *
+ * @param args command line args
+ */
+ public static void main(String[] args) {
+ Captain captain = new Captain(new BattleFishingBoat());
+ captain.move();
+ captain.fire();
+ }
}
diff --git a/adapter/src/main/java/com/iluwatar/adapter/BattleFishingBoat.java b/adapter/src/main/java/com/iluwatar/adapter/BattleFishingBoat.java
new file mode 100644
index 000000000..a591818fe
--- /dev/null
+++ b/adapter/src/main/java/com/iluwatar/adapter/BattleFishingBoat.java
@@ -0,0 +1,51 @@
+/**
+ * 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.adapter;
+
+/**
+ *
+ * Adapter class. Adapts the interface of the device ({@link FishingBoat}) into {@link BattleShip}
+ * interface expected by the client ({@link Captain}).
+ * In this case we added a new function fire to suit the interface. We are reusing the
+ * {@link FishingBoat} without changing itself. The Adapter class can just map the functions of the
+ * Adaptee or add, delete features of the Adaptee.
+ *
+ */
+public class BattleFishingBoat implements BattleShip {
+
+ private FishingBoat boat;
+
+ public BattleFishingBoat() {
+ boat = new FishingBoat();
+ }
+
+ @Override
+ public void fire() {
+ System.out.println("fire!");
+ }
+
+ @Override
+ public void move() {
+ boat.sail();
+ }
+}
diff --git a/adapter/src/main/java/com/iluwatar/adapter/BattleShip.java b/adapter/src/main/java/com/iluwatar/adapter/BattleShip.java
new file mode 100644
index 000000000..6a29a5034
--- /dev/null
+++ b/adapter/src/main/java/com/iluwatar/adapter/BattleShip.java
@@ -0,0 +1,36 @@
+/**
+ * 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.adapter;
+
+/**
+ * The interface expected by the client.
+ * A Battleship can fire and move.
+ *
+ */
+public interface BattleShip {
+
+ void fire();
+
+ void move();
+
+}
diff --git a/adapter/src/main/java/com/iluwatar/adapter/Captain.java b/adapter/src/main/java/com/iluwatar/adapter/Captain.java
new file mode 100644
index 000000000..34f783cd4
--- /dev/null
+++ b/adapter/src/main/java/com/iluwatar/adapter/Captain.java
@@ -0,0 +1,55 @@
+/**
+ * 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.adapter;
+
+/**
+ * The Captain uses {@link BattleShip} to fight.
+ * This is the client in the pattern.
+ */
+public class Captain implements BattleShip {
+
+ private BattleShip battleship;
+
+ public Captain() {
+
+ }
+
+ public Captain(BattleShip battleship) {
+ this.battleship = battleship;
+ }
+
+ public void setBattleship(BattleShip battleship) {
+ this.battleship = battleship;
+ }
+
+ @Override
+ public void fire() {
+ battleship.fire();
+ }
+
+ @Override
+ public void move() {
+ battleship.move();
+ }
+
+}
diff --git a/adapter/src/main/java/com/iluwatar/adapter/Engineer.java b/adapter/src/main/java/com/iluwatar/adapter/Engineer.java
deleted file mode 100644
index 7478b5b69..000000000
--- a/adapter/src/main/java/com/iluwatar/adapter/Engineer.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.iluwatar.adapter;
-
-/**
- *
- * Engineers can operate devices.
- *
- */
-public interface Engineer {
-
- void operateDevice();
-
-}
diff --git a/adapter/src/main/java/com/iluwatar/adapter/FishingBoat.java b/adapter/src/main/java/com/iluwatar/adapter/FishingBoat.java
new file mode 100644
index 000000000..307437038
--- /dev/null
+++ b/adapter/src/main/java/com/iluwatar/adapter/FishingBoat.java
@@ -0,0 +1,40 @@
+/**
+ * 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.adapter;
+
+/**
+ *
+ * Device class (adaptee in the pattern). We want to reuse this class
+ *
+ */
+public class FishingBoat {
+
+ public void sail() {
+ System.out.println("The Boat is moving to that place");
+ }
+
+ public void fish() {
+ System.out.println("fishing ...");
+ }
+
+}
diff --git a/adapter/src/main/java/com/iluwatar/adapter/GnomeEngineer.java b/adapter/src/main/java/com/iluwatar/adapter/GnomeEngineer.java
deleted file mode 100644
index 35cbc9573..000000000
--- a/adapter/src/main/java/com/iluwatar/adapter/GnomeEngineer.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.iluwatar.adapter;
-
-/**
- *
- * Adapter class. Adapts the interface of the device ({@link GoblinGlider}) into
- * {@link Engineer} interface expected by the client ({@link GnomeEngineeringManager}).
- *
- */
-public class GnomeEngineer implements Engineer {
-
- private GoblinGlider glider;
-
- public GnomeEngineer() {
- glider = new GoblinGlider();
- }
-
- @Override
- public void operateDevice() {
- glider.attachGlider();
- glider.gainSpeed();
- glider.takeOff();
- }
-
-}
diff --git a/adapter/src/main/java/com/iluwatar/adapter/GnomeEngineeringManager.java b/adapter/src/main/java/com/iluwatar/adapter/GnomeEngineeringManager.java
deleted file mode 100644
index d95065b88..000000000
--- a/adapter/src/main/java/com/iluwatar/adapter/GnomeEngineeringManager.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.iluwatar.adapter;
-
-/**
- *
- * GnomeEngineering manager uses {@link Engineer} to operate devices.
- *
- */
-public class GnomeEngineeringManager implements Engineer {
-
- private Engineer engineer;
-
- public GnomeEngineeringManager() {
- engineer = new GnomeEngineer();
- }
-
- @Override
- public void operateDevice() {
- engineer.operateDevice();
- }
-}
diff --git a/adapter/src/main/java/com/iluwatar/adapter/GoblinGlider.java b/adapter/src/main/java/com/iluwatar/adapter/GoblinGlider.java
deleted file mode 100644
index ff1dbeb8d..000000000
--- a/adapter/src/main/java/com/iluwatar/adapter/GoblinGlider.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.iluwatar.adapter;
-
-/**
- *
- * Device class (adaptee in the pattern).
- *
- */
-public class GoblinGlider {
-
- public void attachGlider() {
- System.out.println("Glider attached.");
- }
-
- public void gainSpeed() {
- System.out.println("Gaining speed.");
- }
-
- public void takeOff() {
- System.out.println("Lift-off!");
- }
-}
diff --git a/adapter/src/test/java/com/iluwatar/adapter/AdapterPatternTest.java b/adapter/src/test/java/com/iluwatar/adapter/AdapterPatternTest.java
new file mode 100644
index 000000000..263c9ab02
--- /dev/null
+++ b/adapter/src/test/java/com/iluwatar/adapter/AdapterPatternTest.java
@@ -0,0 +1,83 @@
+/**
+ * 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.adapter;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+/**
+ * Test class
+ *
+ */
+public class AdapterPatternTest {
+
+ private Map beans;
+
+ private static final String BATTLESHIP_BEAN = "engineer";
+
+ private static final String CAPTAIN_BEAN = "captain";
+
+ /**
+ * This method runs before the test execution and sets the bean objects in the beans Map.
+ */
+ @Before
+ public void setup() {
+ beans = new HashMap<>();
+
+ BattleFishingBoat battleFishingBoat = spy(new BattleFishingBoat());
+ beans.put(BATTLESHIP_BEAN, battleFishingBoat);
+
+ Captain captain = new Captain();
+ captain.setBattleship((BattleFishingBoat) beans.get(BATTLESHIP_BEAN));
+ beans.put(CAPTAIN_BEAN, captain);
+ }
+
+ /**
+ * This test asserts that when we use the move() method on a captain bean(client), it is
+ * internally calling move method on the battleship object. The Adapter ({@link BattleFishingBoat}
+ * ) converts the interface of the target class ( {@link FishingBoat}) into a suitable one
+ * expected by the client ({@link Captain} ).
+ */
+ @Test
+ public void testAdapter() {
+ BattleShip captain = (BattleShip) beans.get(CAPTAIN_BEAN);
+
+ // when captain moves
+ captain.move();
+
+ // the captain internally calls the battleship object to move
+ BattleShip battleship = (BattleShip) beans.get(BATTLESHIP_BEAN);
+ verify(battleship).move();
+
+ // same with above with firing
+ captain.fire();
+ verify(battleship).fire();
+
+ }
+}
diff --git a/adapter/src/test/java/com/iluwatar/adapter/AppTest.java b/adapter/src/test/java/com/iluwatar/adapter/AppTest.java
index 3d877815a..4f5fcd91d 100644
--- a/adapter/src/test/java/com/iluwatar/adapter/AppTest.java
+++ b/adapter/src/test/java/com/iluwatar/adapter/AppTest.java
@@ -1,19 +1,38 @@
+/**
+ * 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.adapter;
import org.junit.Test;
-import com.iluwatar.adapter.App;
+import java.io.IOException;
/**
- *
- * Application test
- *
+ * Tests that Adapter example runs without errors.
*/
public class AppTest {
-
- @Test
- public void test() {
- String[] args = {};
- App.main(args);
- }
+ @Test
+ public void test() throws IOException {
+ String[] args = {};
+ App.main(args);
+ }
}
diff --git a/aggregator-microservices/README.md b/aggregator-microservices/README.md
new file mode 100644
index 000000000..e65f26d9a
--- /dev/null
+++ b/aggregator-microservices/README.md
@@ -0,0 +1,29 @@
+---
+layout: pattern
+title: Aggregator Microservices
+folder: aggregator-microservices
+permalink: /patterns/aggregator-microservices/
+categories: Architectural
+tags:
+- Java
+- Spring
+---
+
+## Intent
+
+The user makes a single call to the Aggregator, and the aggregator then calls each relevant microservice and collects
+the data, apply business logic to it, and further publish is as a REST Endpoint.
+More variations of the aggregator are:
+- Proxy Microservice Design Pattern: A different microservice is called upon the business need.
+- Chained Microservice Design Pattern: In this case each microservice is dependent/ chained to a series
+of other microservices.
+
+
+
+## Applicability
+
+Use the Aggregator Microservices pattern when you need a unified API for various microservices, regardless the client device.
+
+## Credits
+
+* [Microservice Design Patterns](http://blog.arungupta.me/microservice-design-patterns/)
diff --git a/aggregator-microservices/aggregator-service/pom.xml b/aggregator-microservices/aggregator-service/pom.xml
new file mode 100644
index 000000000..169d0da94
--- /dev/null
+++ b/aggregator-microservices/aggregator-service/pom.xml
@@ -0,0 +1,88 @@
+
+
+
+
+ aggregator-microservices
+ com.iluwatar
+ 1.13.0-SNAPSHOT
+
+ 4.0.0
+
+ aggregator-service
+ jar
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+
+
+
+
+
+ org.springframework
+ spring-webmvc
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ junit
+ junit
+ test
+
+
+ org.mockito
+ mockito-core
+ test
+
+
+ org.apache.httpcomponents
+ httpclient
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring-boot.version}
+
+
+
+ repackage
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/aggregator-microservices/aggregator-service/src/main/java/com/iluwatar/aggregator/microservices/Aggregator.java b/aggregator-microservices/aggregator-service/src/main/java/com/iluwatar/aggregator/microservices/Aggregator.java
new file mode 100644
index 000000000..639349db9
--- /dev/null
+++ b/aggregator-microservices/aggregator-service/src/main/java/com/iluwatar/aggregator/microservices/Aggregator.java
@@ -0,0 +1,58 @@
+/**
+ * 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.aggregator.microservices;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+/**
+ * The aggregator aggregates calls on various micro-services, collects
+ * data and further publishes them under a REST endpoint.
+ */
+@RestController
+public class Aggregator {
+
+
+ @Resource
+ private ProductInformationClient informationClient;
+
+ @Resource
+ private ProductInventoryClient inventoryClient;
+
+
+ /**
+ * Retrieves product data.
+ *
+ * @return a Product.
+ */
+ @RequestMapping("/product")
+ public Product getProduct() {
+ Product product = new Product();
+ product.setTitle(informationClient.getProductTitle());
+ product.setProductInventories(inventoryClient.getProductInventories());
+ return product;
+ }
+
+}
diff --git a/aggregator-microservices/aggregator-service/src/main/java/com/iluwatar/aggregator/microservices/App.java b/aggregator-microservices/aggregator-service/src/main/java/com/iluwatar/aggregator/microservices/App.java
new file mode 100644
index 000000000..25bb9ee6f
--- /dev/null
+++ b/aggregator-microservices/aggregator-service/src/main/java/com/iluwatar/aggregator/microservices/App.java
@@ -0,0 +1,39 @@
+/**
+ * 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.aggregator.microservices;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class App {
+
+ /**
+ * Program entry point
+ *
+ * @param args command line args
+ */
+ public static void main(String[] args) {
+ SpringApplication.run(App.class, args);
+ }
+}
diff --git a/aggregator-microservices/aggregator-service/src/main/java/com/iluwatar/aggregator/microservices/Product.java b/aggregator-microservices/aggregator-service/src/main/java/com/iluwatar/aggregator/microservices/Product.java
new file mode 100644
index 000000000..edf0c121d
--- /dev/null
+++ b/aggregator-microservices/aggregator-service/src/main/java/com/iluwatar/aggregator/microservices/Product.java
@@ -0,0 +1,57 @@
+/**
+ * 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.aggregator.microservices;
+
+/**
+ * Encapsulates all the data for a Product that clients will request.
+ */
+public class Product {
+
+ /**
+ * The title of the product.
+ */
+ private String title;
+
+
+ /**
+ * The inventories of the product.
+ */
+ private int productInventories;
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public int getProductInventories() {
+ return productInventories;
+ }
+
+ public void setProductInventories(int productInventories) {
+ this.productInventories = productInventories;
+ }
+
+}
diff --git a/aggregator-microservices/aggregator-service/src/main/java/com/iluwatar/aggregator/microservices/ProductInformationClient.java b/aggregator-microservices/aggregator-service/src/main/java/com/iluwatar/aggregator/microservices/ProductInformationClient.java
new file mode 100644
index 000000000..863db4759
--- /dev/null
+++ b/aggregator-microservices/aggregator-service/src/main/java/com/iluwatar/aggregator/microservices/ProductInformationClient.java
@@ -0,0 +1,32 @@
+/**
+ * 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.aggregator.microservices;
+
+/**
+ * Interface for the Information micro-service.
+ */
+public interface ProductInformationClient {
+
+ String getProductTitle();
+
+}
diff --git a/aggregator-microservices/aggregator-service/src/main/java/com/iluwatar/aggregator/microservices/ProductInformationClientImpl.java b/aggregator-microservices/aggregator-service/src/main/java/com/iluwatar/aggregator/microservices/ProductInformationClientImpl.java
new file mode 100644
index 000000000..1c5c1527c
--- /dev/null
+++ b/aggregator-microservices/aggregator-service/src/main/java/com/iluwatar/aggregator/microservices/ProductInformationClientImpl.java
@@ -0,0 +1,53 @@
+/**
+ * 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.aggregator.microservices;
+
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+
+/**
+ * An adapter to communicate with information micro-service.
+ */
+@Component
+public class ProductInformationClientImpl implements ProductInformationClient {
+
+ @Override
+ public String getProductTitle() {
+ String response = null;
+ try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
+ HttpGet httpGet = new HttpGet("http://localhost:51515/information");
+ try (CloseableHttpResponse httpResponse = httpClient.execute(httpGet)) {
+ response = EntityUtils.toString(httpResponse.getEntity());
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return response;
+ }
+}
diff --git a/aggregator-microservices/aggregator-service/src/main/java/com/iluwatar/aggregator/microservices/ProductInventoryClient.java b/aggregator-microservices/aggregator-service/src/main/java/com/iluwatar/aggregator/microservices/ProductInventoryClient.java
new file mode 100644
index 000000000..22be900b3
--- /dev/null
+++ b/aggregator-microservices/aggregator-service/src/main/java/com/iluwatar/aggregator/microservices/ProductInventoryClient.java
@@ -0,0 +1,31 @@
+/**
+ * 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.aggregator.microservices;
+
+/**
+ * Interface to Inventory micro-service.
+ */
+public interface ProductInventoryClient {
+
+ int getProductInventories();
+}
diff --git a/aggregator-microservices/aggregator-service/src/main/java/com/iluwatar/aggregator/microservices/ProductInventoryClientImpl.java b/aggregator-microservices/aggregator-service/src/main/java/com/iluwatar/aggregator/microservices/ProductInventoryClientImpl.java
new file mode 100644
index 000000000..14d0a32c4
--- /dev/null
+++ b/aggregator-microservices/aggregator-service/src/main/java/com/iluwatar/aggregator/microservices/ProductInventoryClientImpl.java
@@ -0,0 +1,53 @@
+/**
+ * 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.aggregator.microservices;
+
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+
+/**
+ * An adapter to communicate with inventory micro-service.
+ */
+@Component
+public class ProductInventoryClientImpl implements ProductInventoryClient {
+
+ @Override
+ public int getProductInventories() {
+ String response = "0";
+ try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
+ HttpGet httpGet = new HttpGet("http://localhost:51516/inventories");
+ try (CloseableHttpResponse httpResponse = httpClient.execute(httpGet)) {
+ response = EntityUtils.toString(httpResponse.getEntity());
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return Integer.parseInt(response);
+ }
+}
diff --git a/aggregator-microservices/aggregator-service/src/main/resources/application.properties b/aggregator-microservices/aggregator-service/src/main/resources/application.properties
new file mode 100644
index 000000000..69f581712
--- /dev/null
+++ b/aggregator-microservices/aggregator-service/src/main/resources/application.properties
@@ -0,0 +1,24 @@
+#
+# 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.
+#
+
+server.port=50004
\ No newline at end of file
diff --git a/aggregator-microservices/aggregator-service/src/test/java/com/iluwatar/aggregator/microservices/AggregatorTest.java b/aggregator-microservices/aggregator-service/src/test/java/com/iluwatar/aggregator/microservices/AggregatorTest.java
new file mode 100644
index 000000000..95d36fe25
--- /dev/null
+++ b/aggregator-microservices/aggregator-service/src/test/java/com/iluwatar/aggregator/microservices/AggregatorTest.java
@@ -0,0 +1,67 @@
+/**
+ * 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.aggregator.microservices;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+
+public class AggregatorTest {
+
+ @InjectMocks
+ private Aggregator aggregator;
+
+ @Mock
+ private ProductInformationClient informationClient;
+
+ @Mock
+ private ProductInventoryClient inventoryClient;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ /**
+ * Tests getting the data for a desktop client
+ */
+ @Test
+ public void testGetProduct() {
+ String title = "The Product Title.";
+ int inventories = 5;
+
+ when(informationClient.getProductTitle()).thenReturn(title);
+ when(inventoryClient.getProductInventories()).thenReturn(inventories);
+
+ Product testProduct = aggregator.getProduct();
+
+ assertEquals(title, testProduct.getTitle());
+ assertEquals(inventories, testProduct.getProductInventories());
+ }
+
+}
\ No newline at end of file
diff --git a/aggregator-microservices/etc/aggregator-microservice.png b/aggregator-microservices/etc/aggregator-microservice.png
new file mode 100644
index 000000000..ad344a7e1
Binary files /dev/null and b/aggregator-microservices/etc/aggregator-microservice.png differ
diff --git a/aggregator-microservices/information-microservice/pom.xml b/aggregator-microservices/information-microservice/pom.xml
new file mode 100644
index 000000000..986540344
--- /dev/null
+++ b/aggregator-microservices/information-microservice/pom.xml
@@ -0,0 +1,79 @@
+
+
+
+
+ aggregator-microservices
+ com.iluwatar
+ 1.13.0-SNAPSHOT
+
+ 4.0.0
+
+ information-microservice
+ jar
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+
+
+
+
+
+ org.springframework
+ spring-webmvc
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ junit
+ junit
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring-boot.version}
+
+
+
+ repackage
+
+
+
+
+
+
+
diff --git a/aggregator-microservices/information-microservice/src/main/java/com/iluwatar/information/microservice/InformationApplication.java b/aggregator-microservices/information-microservice/src/main/java/com/iluwatar/information/microservice/InformationApplication.java
new file mode 100644
index 000000000..c93219c17
--- /dev/null
+++ b/aggregator-microservices/information-microservice/src/main/java/com/iluwatar/information/microservice/InformationApplication.java
@@ -0,0 +1,37 @@
+/**
+ * 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.information.microservice;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * Inventory Application starts container (Spring Boot) and exposes the Inventory micro-service.
+ */
+@SpringBootApplication
+public class InformationApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(InformationApplication.class, args);
+ }
+}
diff --git a/aggregator-microservices/information-microservice/src/main/java/com/iluwatar/information/microservice/InformationController.java b/aggregator-microservices/information-microservice/src/main/java/com/iluwatar/information/microservice/InformationController.java
new file mode 100644
index 000000000..37ec45c1b
--- /dev/null
+++ b/aggregator-microservices/information-microservice/src/main/java/com/iluwatar/information/microservice/InformationController.java
@@ -0,0 +1,41 @@
+/**
+ * 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.information.microservice;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class InformationController {
+
+ /**
+ * Endpoint to retrieve a product's informations.
+ *
+ * @return product inventory.
+ */
+ @RequestMapping(value = "/information", method = RequestMethod.GET)
+ public String getProductTitle() {
+ return "The Product Title.";
+ }
+}
diff --git a/aggregator-microservices/information-microservice/src/main/resources/application.properties b/aggregator-microservices/information-microservice/src/main/resources/application.properties
new file mode 100644
index 000000000..3c8452f1f
--- /dev/null
+++ b/aggregator-microservices/information-microservice/src/main/resources/application.properties
@@ -0,0 +1,24 @@
+#
+# 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.
+#
+
+server.port=51515
\ No newline at end of file
diff --git a/aggregator-microservices/information-microservice/src/test/java/com/iluwatar/information/microservice/InformationControllerTest.java b/aggregator-microservices/information-microservice/src/test/java/com/iluwatar/information/microservice/InformationControllerTest.java
new file mode 100644
index 000000000..9c3a6b98d
--- /dev/null
+++ b/aggregator-microservices/information-microservice/src/test/java/com/iluwatar/information/microservice/InformationControllerTest.java
@@ -0,0 +1,39 @@
+/**
+ * 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.information.microservice;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class InformationControllerTest {
+
+ @Test
+ public void shouldGetProductTitle() {
+ InformationController infoController = new InformationController();
+
+ String title = infoController.getProductTitle();
+
+ Assert.assertEquals("The Product Title.", title);
+ }
+
+}
\ No newline at end of file
diff --git a/aggregator-microservices/inventory-microservice/pom.xml b/aggregator-microservices/inventory-microservice/pom.xml
new file mode 100644
index 000000000..f8844dd39
--- /dev/null
+++ b/aggregator-microservices/inventory-microservice/pom.xml
@@ -0,0 +1,79 @@
+
+
+
+
+ aggregator-microservices
+ com.iluwatar
+ 1.13.0-SNAPSHOT
+
+ 4.0.0
+
+ inventory-microservice
+ jar
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+
+
+
+
+
+ org.springframework
+ spring-webmvc
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ junit
+ junit
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring-boot.version}
+
+
+
+ repackage
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/aggregator-microservices/inventory-microservice/src/main/java/com/iluwatar/inventory/microservice/InventoryApplication.java b/aggregator-microservices/inventory-microservice/src/main/java/com/iluwatar/inventory/microservice/InventoryApplication.java
new file mode 100644
index 000000000..3e2cf9e60
--- /dev/null
+++ b/aggregator-microservices/inventory-microservice/src/main/java/com/iluwatar/inventory/microservice/InventoryApplication.java
@@ -0,0 +1,38 @@
+/**
+ * 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.inventory.microservice;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * Inventory Application starts container (Spring Boot) and exposes the Inventory micro-service.
+ */
+@SpringBootApplication
+public class InventoryApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(InventoryApplication.class, args);
+ }
+
+}
diff --git a/aggregator-microservices/inventory-microservice/src/main/java/com/iluwatar/inventory/microservice/InventoryController.java b/aggregator-microservices/inventory-microservice/src/main/java/com/iluwatar/inventory/microservice/InventoryController.java
new file mode 100644
index 000000000..483e28bf3
--- /dev/null
+++ b/aggregator-microservices/inventory-microservice/src/main/java/com/iluwatar/inventory/microservice/InventoryController.java
@@ -0,0 +1,42 @@
+/**
+ * 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.inventory.microservice;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class InventoryController {
+
+ /**
+ * Endpoint to retrieve a product's inventories.
+ *
+ * @return product inventory.
+ */
+ @RequestMapping(value = "/inventories", method = RequestMethod.GET)
+ public int getProductInventories() {
+ return 5;
+ }
+
+}
diff --git a/aggregator-microservices/inventory-microservice/src/main/resources/application.properties b/aggregator-microservices/inventory-microservice/src/main/resources/application.properties
new file mode 100644
index 000000000..36f7589fc
--- /dev/null
+++ b/aggregator-microservices/inventory-microservice/src/main/resources/application.properties
@@ -0,0 +1,24 @@
+#
+# 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.
+#
+
+server.port=51516
\ No newline at end of file
diff --git a/aggregator-microservices/inventory-microservice/src/test/java/com/iluwatar/inventory/microservice/InventoryControllerTest.java b/aggregator-microservices/inventory-microservice/src/test/java/com/iluwatar/inventory/microservice/InventoryControllerTest.java
new file mode 100644
index 000000000..787ec0e61
--- /dev/null
+++ b/aggregator-microservices/inventory-microservice/src/test/java/com/iluwatar/inventory/microservice/InventoryControllerTest.java
@@ -0,0 +1,38 @@
+/**
+ * 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.inventory.microservice;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class InventoryControllerTest {
+
+ @Test
+ public void testGetProductInventories() throws Exception {
+ InventoryController inventoryController = new InventoryController();
+
+ int numberOfInventories = inventoryController.getProductInventories();
+
+ Assert.assertEquals(5, numberOfInventories);
+ }
+}
\ No newline at end of file
diff --git a/aggregator-microservices/pom.xml b/aggregator-microservices/pom.xml
new file mode 100644
index 000000000..0133e9ea4
--- /dev/null
+++ b/aggregator-microservices/pom.xml
@@ -0,0 +1,43 @@
+
+
+
+
+ java-design-patterns
+ com.iluwatar
+ 1.13.0-SNAPSHOT
+
+ 4.0.0
+ aggregator-microservices
+ pom
+
+
+ information-microservice
+ aggregator-service
+ inventory-microservice
+
+
\ No newline at end of file
diff --git a/api-gateway/README.md b/api-gateway/README.md
new file mode 100644
index 000000000..23014ae0b
--- /dev/null
+++ b/api-gateway/README.md
@@ -0,0 +1,30 @@
+---
+layout: pattern
+title: API Gateway
+folder: api-gateway
+permalink: /patterns/api-gateway/
+categories: Architectural
+tags:
+- Java
+- Difficulty-Intermediate
+- Spring
+---
+
+## Intent
+
+Aggregate calls to microservices in a single location: the API Gateway. The user makes a single
+call to the API Gateway, and the API Gateway then calls each relevant microservice.
+
+
+
+## Applicability
+
+Use the API Gateway pattern when
+
+* you're also using the Microservices pattern and need a single point of aggregation for your
+microservice calls
+
+## Credits
+
+* [microservices.io - API Gateway](http://microservices.io/patterns/apigateway.html)
+* [NGINX - Building Microservices: Using an API Gateway](https://www.nginx.com/blog/building-microservices-using-an-api-gateway/)
diff --git a/api-gateway/api-gateway-service/pom.xml b/api-gateway/api-gateway-service/pom.xml
new file mode 100644
index 000000000..87a1ebb5e
--- /dev/null
+++ b/api-gateway/api-gateway-service/pom.xml
@@ -0,0 +1,87 @@
+
+
+
+
+ api-gateway
+ com.iluwatar
+ 1.13.0-SNAPSHOT
+
+ 4.0.0
+ api-gateway-service
+ jar
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+
+
+
+
+
+ org.springframework
+ spring-webmvc
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ junit
+ junit
+ test
+
+
+ org.mockito
+ mockito-core
+ test
+
+
+ org.apache.httpcomponents
+ httpclient
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring-boot.version}
+
+
+
+ repackage
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/api-gateway/api-gateway-service/src/main/java/com/iluwatar/api/gateway/ApiGateway.java b/api-gateway/api-gateway-service/src/main/java/com/iluwatar/api/gateway/ApiGateway.java
new file mode 100644
index 000000000..60f0b6d54
--- /dev/null
+++ b/api-gateway/api-gateway-service/src/main/java/com/iluwatar/api/gateway/ApiGateway.java
@@ -0,0 +1,64 @@
+/**
+ * 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.api.gateway;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+/**
+ * The ApiGateway aggregates calls to microservices based on the needs of the individual clients.
+ */
+@RestController
+public class ApiGateway {
+
+ @Resource
+ private ImageClient imageClient;
+
+ @Resource
+ private PriceClient priceClient;
+
+ /**
+ * Retrieves product information that desktop clients need
+ * @return Product information for clients on a desktop
+ */
+ @RequestMapping("/desktop")
+ public DesktopProduct getProductDesktop() {
+ DesktopProduct desktopProduct = new DesktopProduct();
+ desktopProduct.setImagePath(imageClient.getImagePath());
+ desktopProduct.setPrice(priceClient.getPrice());
+ return desktopProduct;
+ }
+
+ /**
+ * Retrieves product information that mobile clients need
+ * @return Product information for clients on a mobile device
+ */
+ @RequestMapping("/mobile")
+ public MobileProduct getProductMobile() {
+ MobileProduct mobileProduct = new MobileProduct();
+ mobileProduct.setPrice(priceClient.getPrice());
+ return mobileProduct;
+ }
+}
diff --git a/api-gateway/api-gateway-service/src/main/java/com/iluwatar/api/gateway/App.java b/api-gateway/api-gateway-service/src/main/java/com/iluwatar/api/gateway/App.java
new file mode 100644
index 000000000..9a644a0f7
--- /dev/null
+++ b/api-gateway/api-gateway-service/src/main/java/com/iluwatar/api/gateway/App.java
@@ -0,0 +1,66 @@
+/**
+ * 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.api.gateway;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * With the Microservices pattern, a client may need data from multiple different microservices.
+ * If the client called each microservice directly, that could contribute to longer load times,
+ * since the client would have to make a network request for each microservice called. Moreover,
+ * having the client call each microservice directly ties the client to that microservice - if the
+ * internal implementations of the microservices change (for example, if two microservices are
+ * combined sometime in the future) or if the location (host and port) of a microservice changes,
+ * then every client that makes use of those microservices must be updated.
+ *
+ *
+ * The intent of the API Gateway pattern is to alleviate some of these issues. In the API Gateway
+ * pattern, an additional entity (the API Gateway) is placed between the client and the
+ * microservices. The job of the API Gateway is to aggregate the calls to the microservices.
+ * Rather than the client calling each microservice individually, the client calls the API Gateway
+ * a single time. The API Gateway then calls each of the microservices that the client needs.
+ *
+ *
+ * This implementation shows what the API Gateway pattern could look like for an e-commerce site.
+ * The {@link ApiGateway} makes calls to the Image and Price microservices using the
+ * {@link ImageClientImpl} and {@link PriceClientImpl} respectively. Customers viewing the site on a
+ * desktop device can see both price information and an image of a product, so the {@link ApiGateway}
+ * calls both of the microservices and aggregates the data in the {@link DesktopProduct} model.
+ * However, mobile users only see price information; they do not see a product image. For mobile
+ * users, the {@link ApiGateway} only retrieves price information, which it uses to populate the
+ * {@link MobileProduct}.
+ */
+@SpringBootApplication
+public class App {
+
+ /**
+ * Program entry point
+ *
+ * @param args
+ * command line args
+ */
+ public static void main(String[] args) {
+ SpringApplication.run(App.class, args);
+ }
+}
diff --git a/api-gateway/api-gateway-service/src/main/java/com/iluwatar/api/gateway/DesktopProduct.java b/api-gateway/api-gateway-service/src/main/java/com/iluwatar/api/gateway/DesktopProduct.java
new file mode 100644
index 000000000..0a04db402
--- /dev/null
+++ b/api-gateway/api-gateway-service/src/main/java/com/iluwatar/api/gateway/DesktopProduct.java
@@ -0,0 +1,54 @@
+/**
+ * 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.api.gateway;
+
+/**
+ * Encapsulates all of the information that a desktop client needs to display a product.
+ */
+public class DesktopProduct {
+ /**
+ * The price of the product
+ */
+ private String price;
+
+ /**
+ * The path to the image of the product
+ */
+ private String imagePath;
+
+ public String getPrice() {
+ return price;
+ }
+
+ public void setPrice(String price) {
+ this.price = price;
+ }
+
+ public String getImagePath() {
+ return imagePath;
+ }
+
+ public void setImagePath(String imagePath) {
+ this.imagePath = imagePath;
+ }
+}
diff --git a/api-gateway/api-gateway-service/src/main/java/com/iluwatar/api/gateway/ImageClient.java b/api-gateway/api-gateway-service/src/main/java/com/iluwatar/api/gateway/ImageClient.java
new file mode 100644
index 000000000..935dab778
--- /dev/null
+++ b/api-gateway/api-gateway-service/src/main/java/com/iluwatar/api/gateway/ImageClient.java
@@ -0,0 +1,30 @@
+/**
+ * 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.api.gateway;
+
+/**
+ * An interface used to communicate with the Image microservice
+ */
+public interface ImageClient {
+ String getImagePath();
+}
diff --git a/api-gateway/api-gateway-service/src/main/java/com/iluwatar/api/gateway/ImageClientImpl.java b/api-gateway/api-gateway-service/src/main/java/com/iluwatar/api/gateway/ImageClientImpl.java
new file mode 100644
index 000000000..64fde1e66
--- /dev/null
+++ b/api-gateway/api-gateway-service/src/main/java/com/iluwatar/api/gateway/ImageClientImpl.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.api.gateway;
+
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+
+/**
+ * An adapter to communicate with the Image microservice
+ */
+@Component
+public class ImageClientImpl implements ImageClient{
+ /**
+ * Makes a simple HTTP Get request to the Image microservice
+ * @return The path to the image
+ */
+ @Override
+ public String getImagePath() {
+ String response = null;
+ try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
+ HttpGet httpGet = new HttpGet("http://localhost:50005/image-path");
+ try (CloseableHttpResponse httpResponse = httpClient.execute(httpGet)) {
+ response = EntityUtils.toString(httpResponse.getEntity());
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return response;
+ }
+}
diff --git a/api-gateway/api-gateway-service/src/main/java/com/iluwatar/api/gateway/MobileProduct.java b/api-gateway/api-gateway-service/src/main/java/com/iluwatar/api/gateway/MobileProduct.java
new file mode 100644
index 000000000..db358b781
--- /dev/null
+++ b/api-gateway/api-gateway-service/src/main/java/com/iluwatar/api/gateway/MobileProduct.java
@@ -0,0 +1,41 @@
+/**
+ * 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.api.gateway;
+
+/**
+ * Encapsulates all of the information that mobile client needs to display a product.
+ */
+public class MobileProduct {
+ /**
+ * The price of the product
+ */
+ private String price;
+
+ public String getPrice() {
+ return price;
+ }
+
+ public void setPrice(String price) {
+ this.price = price;
+ }
+}
diff --git a/api-gateway/api-gateway-service/src/main/java/com/iluwatar/api/gateway/PriceClient.java b/api-gateway/api-gateway-service/src/main/java/com/iluwatar/api/gateway/PriceClient.java
new file mode 100644
index 000000000..44497b997
--- /dev/null
+++ b/api-gateway/api-gateway-service/src/main/java/com/iluwatar/api/gateway/PriceClient.java
@@ -0,0 +1,30 @@
+/**
+ * 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.api.gateway;
+
+/**
+ * An interface used to communicate with the Price microservice
+ */
+public interface PriceClient {
+ String getPrice();
+}
diff --git a/api-gateway/api-gateway-service/src/main/java/com/iluwatar/api/gateway/PriceClientImpl.java b/api-gateway/api-gateway-service/src/main/java/com/iluwatar/api/gateway/PriceClientImpl.java
new file mode 100644
index 000000000..bdc7cb00b
--- /dev/null
+++ b/api-gateway/api-gateway-service/src/main/java/com/iluwatar/api/gateway/PriceClientImpl.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.api.gateway;
+
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+
+/**
+ * An adapter to communicate with the Price microservice
+ */
+@Component
+public class PriceClientImpl implements PriceClient{
+ /**
+ * Makes a simple HTTP Get request to the Price microservice
+ * @return The price of the product
+ */
+ @Override
+ public String getPrice() {
+ String response = null;
+ try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
+ HttpGet httpGet = new HttpGet("http://localhost:50006/price");
+ try (CloseableHttpResponse httpResponse = httpClient.execute(httpGet)) {
+ response = EntityUtils.toString(httpResponse.getEntity());
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return response;
+ }
+}
diff --git a/api-gateway/api-gateway-service/src/main/resources/application.properties b/api-gateway/api-gateway-service/src/main/resources/application.properties
new file mode 100644
index 000000000..69f581712
--- /dev/null
+++ b/api-gateway/api-gateway-service/src/main/resources/application.properties
@@ -0,0 +1,24 @@
+#
+# 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.
+#
+
+server.port=50004
\ No newline at end of file
diff --git a/api-gateway/api-gateway-service/src/test/java/com/iluwatar/api/gateway/ApiGatewayTest.java b/api-gateway/api-gateway-service/src/test/java/com/iluwatar/api/gateway/ApiGatewayTest.java
new file mode 100644
index 000000000..d1a210f05
--- /dev/null
+++ b/api-gateway/api-gateway-service/src/test/java/com/iluwatar/api/gateway/ApiGatewayTest.java
@@ -0,0 +1,78 @@
+/**
+ * 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.api.gateway;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+
+public class ApiGatewayTest {
+
+ @InjectMocks
+ private ApiGateway apiGateway;
+
+ @Mock
+ private ImageClient imageClient;
+
+ @Mock
+ private PriceClient priceClient;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ /**
+ * Tests getting the data for a desktop client
+ */
+ @Test
+ public void testGetProductDesktop() {
+ String imagePath = "/product-image.png";
+ String price = "20";
+ when(imageClient.getImagePath()).thenReturn(imagePath);
+ when(priceClient.getPrice()).thenReturn(price);
+
+ DesktopProduct desktopProduct = apiGateway.getProductDesktop();
+
+ assertEquals(price, desktopProduct.getPrice());
+ assertEquals(imagePath, desktopProduct.getImagePath());
+ }
+
+ /**
+ * Tests getting the data for a mobile client
+ */
+ @Test
+ public void testGetProductMobile() {
+ String price = "20";
+ when(priceClient.getPrice()).thenReturn(price);
+
+ MobileProduct mobileProduct = apiGateway.getProductMobile();
+
+ assertEquals(price, mobileProduct.getPrice());
+ }
+}
diff --git a/api-gateway/etc/api-gateway.png b/api-gateway/etc/api-gateway.png
new file mode 100644
index 000000000..bb3ec2e2e
Binary files /dev/null and b/api-gateway/etc/api-gateway.png differ
diff --git a/api-gateway/etc/api-gateway.ucls b/api-gateway/etc/api-gateway.ucls
new file mode 100644
index 000000000..4a74c2108
--- /dev/null
+++ b/api-gateway/etc/api-gateway.ucls
@@ -0,0 +1,97 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/api-gateway/image-microservice/etc/image-microservice.png b/api-gateway/image-microservice/etc/image-microservice.png
new file mode 100644
index 000000000..340285a14
Binary files /dev/null and b/api-gateway/image-microservice/etc/image-microservice.png differ
diff --git a/api-gateway/image-microservice/etc/image-microservice.ucls b/api-gateway/image-microservice/etc/image-microservice.ucls
new file mode 100644
index 000000000..d3520768f
--- /dev/null
+++ b/api-gateway/image-microservice/etc/image-microservice.ucls
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/api-gateway/image-microservice/pom.xml b/api-gateway/image-microservice/pom.xml
new file mode 100644
index 000000000..c29932fae
--- /dev/null
+++ b/api-gateway/image-microservice/pom.xml
@@ -0,0 +1,79 @@
+
+
+
+
+ api-gateway
+ com.iluwatar
+ 1.13.0-SNAPSHOT
+
+
+ 4.0.0
+ image-microservice
+ jar
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+
+
+
+
+
+ org.springframework
+ spring-webmvc
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ junit
+ junit
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring-boot.version}
+
+
+
+ repackage
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/api-gateway/image-microservice/src/main/java/com/iluwatar/image/microservice/ImageApplication.java b/api-gateway/image-microservice/src/main/java/com/iluwatar/image/microservice/ImageApplication.java
new file mode 100644
index 000000000..b4cb3d250
--- /dev/null
+++ b/api-gateway/image-microservice/src/main/java/com/iluwatar/image/microservice/ImageApplication.java
@@ -0,0 +1,43 @@
+/**
+ * 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.image.microservice;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * ImageApplication starts up Spring Boot, exposing endpoints for the Image microservice through
+ * the {@link ImageController}.
+ */
+@SpringBootApplication
+public class ImageApplication {
+
+ /**
+ * Microservice entry point
+ * @param args
+ * command line args
+ */
+ public static void main(String[] args) {
+ SpringApplication.run(ImageApplication.class, args);
+ }
+}
diff --git a/api-gateway/image-microservice/src/main/java/com/iluwatar/image/microservice/ImageController.java b/api-gateway/image-microservice/src/main/java/com/iluwatar/image/microservice/ImageController.java
new file mode 100644
index 000000000..16faf5b70
--- /dev/null
+++ b/api-gateway/image-microservice/src/main/java/com/iluwatar/image/microservice/ImageController.java
@@ -0,0 +1,43 @@
+/**
+ * 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.image.microservice;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * Exposes the Image microservice's endpoints
+ */
+@RestController
+public class ImageController {
+
+ /**
+ * An endpoint for a user to retrieve an image path
+ * @return An image path
+ */
+ @RequestMapping(value = "/image-path", method = RequestMethod.GET)
+ public String getImagePath() {
+ return "/product-image.png";
+ }
+}
diff --git a/api-gateway/image-microservice/src/main/resources/application.properties b/api-gateway/image-microservice/src/main/resources/application.properties
new file mode 100644
index 000000000..aeda0c24c
--- /dev/null
+++ b/api-gateway/image-microservice/src/main/resources/application.properties
@@ -0,0 +1,24 @@
+#
+# 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.
+#
+
+server.port=50005
\ No newline at end of file
diff --git a/api-gateway/image-microservice/src/test/java/com/iluwatar/image/microservice/ImageControllerTest.java b/api-gateway/image-microservice/src/test/java/com/iluwatar/image/microservice/ImageControllerTest.java
new file mode 100644
index 000000000..cf0c099c1
--- /dev/null
+++ b/api-gateway/image-microservice/src/test/java/com/iluwatar/image/microservice/ImageControllerTest.java
@@ -0,0 +1,37 @@
+/**
+ * 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.image.microservice;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ImageControllerTest {
+ @Test
+ public void testGetImagePath() {
+ ImageController imageController = new ImageController();
+
+ String imagePath = imageController.getImagePath();
+
+ Assert.assertEquals("/product-image.png", imagePath);
+ }
+}
diff --git a/api-gateway/pom.xml b/api-gateway/pom.xml
new file mode 100644
index 000000000..471ffda7d
--- /dev/null
+++ b/api-gateway/pom.xml
@@ -0,0 +1,43 @@
+
+
+
+
+ java-design-patterns
+ com.iluwatar
+ 1.13.0-SNAPSHOT
+
+ 4.0.0
+ api-gateway
+ pom
+
+
+ image-microservice
+ price-microservice
+ api-gateway-service
+
+
\ No newline at end of file
diff --git a/api-gateway/price-microservice/etc/price-microservice.png b/api-gateway/price-microservice/etc/price-microservice.png
new file mode 100644
index 000000000..7c5716025
Binary files /dev/null and b/api-gateway/price-microservice/etc/price-microservice.png differ
diff --git a/api-gateway/price-microservice/etc/price-microservice.ucls b/api-gateway/price-microservice/etc/price-microservice.ucls
new file mode 100644
index 000000000..5878395b6
--- /dev/null
+++ b/api-gateway/price-microservice/etc/price-microservice.ucls
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/api-gateway/price-microservice/pom.xml b/api-gateway/price-microservice/pom.xml
new file mode 100644
index 000000000..24e9663aa
--- /dev/null
+++ b/api-gateway/price-microservice/pom.xml
@@ -0,0 +1,79 @@
+
+
+
+
+ api-gateway
+ com.iluwatar
+ 1.13.0-SNAPSHOT
+
+
+ 4.0.0
+ price-microservice
+ jar
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+
+
+
+
+
+ org.springframework
+ spring-webmvc
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ junit
+ junit
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring-boot.version}
+
+
+
+ repackage
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/api-gateway/price-microservice/src/main/java/com/iluwatar/price/microservice/PriceApplication.java b/api-gateway/price-microservice/src/main/java/com/iluwatar/price/microservice/PriceApplication.java
new file mode 100644
index 000000000..e777c7c2b
--- /dev/null
+++ b/api-gateway/price-microservice/src/main/java/com/iluwatar/price/microservice/PriceApplication.java
@@ -0,0 +1,43 @@
+/**
+ * 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.price.microservice;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * PriceApplication starts up Spring Boot, exposing endpoints for the Price microservice through
+ * the {@link PriceController}.
+ */
+@SpringBootApplication
+public class PriceApplication {
+
+ /**
+ * Microservice entry point
+ * @param args
+ * command line args
+ */
+ public static void main(String[] args) {
+ SpringApplication.run(PriceApplication.class, args);
+ }
+}
diff --git a/api-gateway/price-microservice/src/main/java/com/iluwatar/price/microservice/PriceController.java b/api-gateway/price-microservice/src/main/java/com/iluwatar/price/microservice/PriceController.java
new file mode 100644
index 000000000..ec43618fa
--- /dev/null
+++ b/api-gateway/price-microservice/src/main/java/com/iluwatar/price/microservice/PriceController.java
@@ -0,0 +1,43 @@
+/**
+ * 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.price.microservice;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * Exposes the Price microservice's endpoints
+ */
+@RestController
+public class PriceController {
+
+ /**
+ * An endpoint for a user to retrieve a product's price
+ * @return A product's price
+ */
+ @RequestMapping(value = "/price", method = RequestMethod.GET)
+ public String getPrice() {
+ return "20";
+ }
+}
diff --git a/api-gateway/price-microservice/src/main/resources/application.properties b/api-gateway/price-microservice/src/main/resources/application.properties
new file mode 100644
index 000000000..f0b479dfd
--- /dev/null
+++ b/api-gateway/price-microservice/src/main/resources/application.properties
@@ -0,0 +1,24 @@
+#
+# 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.
+#
+
+server.port=50006
\ No newline at end of file
diff --git a/api-gateway/price-microservice/src/test/java/com/iluwatar/price/microservice/PriceControllerTest.java b/api-gateway/price-microservice/src/test/java/com/iluwatar/price/microservice/PriceControllerTest.java
new file mode 100644
index 000000000..c289549f2
--- /dev/null
+++ b/api-gateway/price-microservice/src/test/java/com/iluwatar/price/microservice/PriceControllerTest.java
@@ -0,0 +1,37 @@
+/**
+ * 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.price.microservice;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class PriceControllerTest {
+ @Test
+ public void testgetPrice() {
+ PriceController priceController = new PriceController();
+
+ String price = priceController.getPrice();
+
+ Assert.assertEquals("20", price);
+ }
+}
diff --git a/async-method-invocation/index.md b/async-method-invocation/README.md
similarity index 83%
rename from async-method-invocation/index.md
rename to async-method-invocation/README.md
index dfcee0208..2d99820c5 100644
--- a/async-method-invocation/index.md
+++ b/async-method-invocation/README.md
@@ -4,24 +4,30 @@ title: Async Method Invocation
folder: async-method-invocation
permalink: /patterns/async-method-invocation/
categories: Concurrency
-tags: Java
+tags:
+ - Java
+ - Difficulty-Intermediate
+ - Functional
+ - Reactive
---
-**Intent:** Asynchronous method invocation is pattern where the calling thread
+## Intent
+Asynchronous method invocation is pattern where the calling thread
is not blocked while waiting results of tasks. The pattern provides parallel
processing of multiple independent tasks and retrieving the results via
callbacks or waiting until everything is done.

-**Applicability:** Use async method invocation pattern when
+## Applicability
+Use async method invocation pattern when
* you have multiple independent tasks that can run in parallel
* you need to improve the performance of a group of sequential tasks
* you have limited amount of processing capacity or long running tasks and the
caller should not wait the tasks to be ready
-**Real world examples:**
+## Real world examples
* [FutureTask](http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/FutureTask.html), [CompletableFuture](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html) and [ExecutorService](http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html) (Java)
* [Task-based Asynchronous Pattern](https://msdn.microsoft.com/en-us/library/hh873175.aspx) (.NET)
diff --git a/async-method-invocation/pom.xml b/async-method-invocation/pom.xml
index d5e0e2b3e..d912df965 100644
--- a/async-method-invocation/pom.xml
+++ b/async-method-invocation/pom.xml
@@ -1,11 +1,35 @@
+
4.0.0
com.iluwatar
java-design-patterns
- 1.7.0
+ 1.13.0-SNAPSHOT
async-method-invocation
@@ -14,5 +38,10 @@
junit
test
+
+ org.mockito
+ mockito-core
+ test
+
diff --git a/async-method-invocation/src/main/java/com/iluwatar/async/method/invocation/App.java b/async-method-invocation/src/main/java/com/iluwatar/async/method/invocation/App.java
index 688d8482f..0a56dc166 100644
--- a/async-method-invocation/src/main/java/com/iluwatar/async/method/invocation/App.java
+++ b/async-method-invocation/src/main/java/com/iluwatar/async/method/invocation/App.java
@@ -1,3 +1,25 @@
+/**
+ * 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.async.method.invocation;
import java.util.concurrent.Callable;
@@ -5,22 +27,22 @@ import java.util.concurrent.Callable;
/**
* This application demonstrates the async method invocation pattern. Key parts of the pattern are
* AsyncResult
which is an intermediate container for an asynchronously evaluated value,
- * AsyncCallback
which can be provided to be executed on task completion and
- * AsyncExecutor
that manages the execution of the async tasks.
+ * AsyncCallback
which can be provided to be executed on task completion and AsyncExecutor
+ * that manages the execution of the async tasks.
*
- * The main method shows example flow of async invocations. The main thread starts multiple tasks with
- * variable durations and then continues its own work. When the main thread has done it's job it collects
- * the results of the async tasks. Two of the tasks are handled with callbacks, meaning the callbacks are
- * executed immediately when the tasks complete.
+ * The main method shows example flow of async invocations. The main thread starts multiple tasks with variable
+ * durations and then continues its own work. When the main thread has done it's job it collects the results of the
+ * async tasks. Two of the tasks are handled with callbacks, meaning the callbacks are executed immediately when the
+ * tasks complete.
*
- * Noteworthy difference of thread usage between the async results and callbacks is that the async results
- * are collected in the main thread but the callbacks are executed within the worker threads. This should be
- * noted when working with thread pools.
+ * Noteworthy difference of thread usage between the async results and callbacks is that the async results are collected
+ * in the main thread but the callbacks are executed within the worker threads. This should be noted when working with
+ * thread pools.
*
- * Java provides its own implementations of async method invocation pattern. FutureTask, CompletableFuture
- * and ExecutorService are the real world implementations of this pattern. But due to the nature of parallel
- * programming, the implementations are not trivial. This example does not take all possible scenarios into
- * account but rather provides a simple version that helps to understand the pattern.
+ * Java provides its own implementations of async method invocation pattern. FutureTask, CompletableFuture and
+ * ExecutorService are the real world implementations of this pattern. But due to the nature of parallel programming,
+ * the implementations are not trivial. This example does not take all possible scenarios into account but rather
+ * provides a simple version that helps to understand the pattern.
*
* @see AsyncResult
* @see AsyncCallback
@@ -32,66 +54,72 @@ import java.util.concurrent.Callable;
*/
public class App {
- public static void main(String[] args) throws Exception {
- // construct a new executor that will run async tasks
- AsyncExecutor executor = new ThreadAsyncExecutor();
+ /**
+ * Program entry point
+ */
+ public static void main(String[] args) throws Exception {
+ // construct a new executor that will run async tasks
+ AsyncExecutor executor = new ThreadAsyncExecutor();
- // start few async tasks with varying processing times, two last with callback handlers
- AsyncResult asyncResult1 = executor.startProcess(lazyval(10, 500));
- AsyncResult asyncResult2 = executor.startProcess(lazyval("test", 300));
- AsyncResult asyncResult3 = executor.startProcess(lazyval(50L, 700));
- AsyncResult asyncResult4 = executor.startProcess(lazyval(20, 400), callback("Callback result 4"));
- AsyncResult asyncResult5 = executor.startProcess(lazyval("callback", 600), callback("Callback result 5"));
+ // start few async tasks with varying processing times, two last with callback handlers
+ AsyncResult asyncResult1 = executor.startProcess(lazyval(10, 500));
+ AsyncResult asyncResult2 = executor.startProcess(lazyval("test", 300));
+ AsyncResult asyncResult3 = executor.startProcess(lazyval(50L, 700));
+ AsyncResult asyncResult4 = executor.startProcess(lazyval(20, 400), callback("Callback result 4"));
+ AsyncResult asyncResult5 = executor.startProcess(lazyval("callback", 600), callback("Callback result 5"));
- // emulate processing in the current thread while async tasks are running in their own threads
- Thread.sleep(350); // Oh boy I'm working hard here
- log("Some hard work done");
+ // emulate processing in the current thread while async tasks are running in their own threads
+ Thread.sleep(350); // Oh boy I'm working hard here
+ log("Some hard work done");
- // wait for completion of the tasks
- Integer result1 = executor.endProcess(asyncResult1);
- String result2 = executor.endProcess(asyncResult2);
- Long result3 = executor.endProcess(asyncResult3);
- asyncResult4.await();
- asyncResult5.await();
+ // wait for completion of the tasks
+ Integer result1 = executor.endProcess(asyncResult1);
+ String result2 = executor.endProcess(asyncResult2);
+ Long result3 = executor.endProcess(asyncResult3);
+ asyncResult4.await();
+ asyncResult5.await();
- // log the results of the tasks, callbacks log immediately when complete
- log("Result 1: " + result1);
- log("Result 2: " + result2);
- log("Result 3: " + result3);
- }
+ // log the results of the tasks, callbacks log immediately when complete
+ log("Result 1: " + result1);
+ log("Result 2: " + result2);
+ log("Result 3: " + result3);
+ }
- /**
- * Creates a callable that lazily evaluates to given value with artificial delay.
- *
- * @param value value to evaluate
- * @param delayMillis artificial delay in milliseconds
- * @return new callable for lazy evaluation
- */
- private static Callable lazyval(T value, long delayMillis) {
- return () -> {
- Thread.sleep(delayMillis);
- log("Task completed with: " + value);
- return value;
- };
- }
+ /**
+ * Creates a callable that lazily evaluates to given value with artificial delay.
+ *
+ * @param value
+ * value to evaluate
+ * @param delayMillis
+ * artificial delay in milliseconds
+ * @return new callable for lazy evaluation
+ */
+ private static Callable lazyval(T value, long delayMillis) {
+ return () -> {
+ Thread.sleep(delayMillis);
+ log("Task completed with: " + value);
+ return value;
+ };
+ }
- /**
- * Creates a simple callback that logs the complete status of the async result.
- *
- * @param name callback name
- * @return new async callback
- */
- private static AsyncCallback callback(String name) {
- return (value, ex) -> {
- if (ex.isPresent()) {
- log(name + " failed: " + ex.map(Exception::getMessage).orElse(""));
- } else {
- log(name + ": " + value);
- }
- };
- }
+ /**
+ * Creates a simple callback that logs the complete status of the async result.
+ *
+ * @param name
+ * callback name
+ * @return new async callback
+ */
+ private static AsyncCallback callback(String name) {
+ return (value, ex) -> {
+ if (ex.isPresent()) {
+ log(name + " failed: " + ex.map(Exception::getMessage).orElse(""));
+ } else {
+ log(name + ": " + value);
+ }
+ };
+ }
- private static void log(String msg) {
- System.out.println(String.format("[%1$-10s] - %2$s", Thread.currentThread().getName(), msg));
- }
+ private static void log(String msg) {
+ System.out.println(String.format("[%1$-10s] - %2$s", Thread.currentThread().getName(), msg));
+ }
}
diff --git a/async-method-invocation/src/main/java/com/iluwatar/async/method/invocation/AsyncCallback.java b/async-method-invocation/src/main/java/com/iluwatar/async/method/invocation/AsyncCallback.java
index 46556a48e..2fddba683 100644
--- a/async-method-invocation/src/main/java/com/iluwatar/async/method/invocation/AsyncCallback.java
+++ b/async-method-invocation/src/main/java/com/iluwatar/async/method/invocation/AsyncCallback.java
@@ -1,3 +1,25 @@
+/**
+ * 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.async.method.invocation;
import java.util.Optional;
@@ -11,12 +33,11 @@ import java.util.Optional;
*/
public interface AsyncCallback {
- /**
- * Complete handler which is executed when async task is completed or fails execution.
- *
- * @param value the evaluated value from async task, undefined when execution fails
- * @param ex empty value if execution succeeds, some exception if executions fails
- */
- void onComplete(T value, Optional ex);
-
+ /**
+ * Complete handler which is executed when async task is completed or fails execution.
+ *
+ * @param value the evaluated value from async task, undefined when execution fails
+ * @param ex empty value if execution succeeds, some exception if executions fails
+ */
+ void onComplete(T value, Optional ex);
}
diff --git a/async-method-invocation/src/main/java/com/iluwatar/async/method/invocation/AsyncExecutor.java b/async-method-invocation/src/main/java/com/iluwatar/async/method/invocation/AsyncExecutor.java
index 5c5098487..eb1afa4f3 100644
--- a/async-method-invocation/src/main/java/com/iluwatar/async/method/invocation/AsyncExecutor.java
+++ b/async-method-invocation/src/main/java/com/iluwatar/async/method/invocation/AsyncExecutor.java
@@ -1,3 +1,25 @@
+/**
+ * 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.async.method.invocation;
import java.util.concurrent.Callable;
@@ -10,33 +32,32 @@ import java.util.concurrent.ExecutionException;
*/
public interface AsyncExecutor {
- /**
- * Starts processing of an async task. Returns immediately with async result.
- *
- * @param task task to be executed asynchronously
- * @return async result for the task
- */
- AsyncResult startProcess(Callable task);
+ /**
+ * Starts processing of an async task. Returns immediately with async result.
+ *
+ * @param task task to be executed asynchronously
+ * @return async result for the task
+ */
+ AsyncResult startProcess(Callable task);
- /**
- * Starts processing of an async task. Returns immediately with async result. Executes callback
- * when the task is completed.
- *
- * @param task task to be executed asynchronously
- * @param callback callback to be executed on task completion
- * @return async result for the task
- */
- AsyncResult startProcess(Callable task, AsyncCallback callback);
-
- /**
- * Ends processing of an async task. Blocks the current thread if necessary and returns the
- * evaluated value of the completed task.
- *
- * @param asyncResult async result of a task
- * @return evaluated value of the completed task
- * @throws ExecutionException if execution has failed, containing the root cause
- * @throws InterruptedException if the execution is interrupted
- */
- T endProcess(AsyncResult asyncResult) throws ExecutionException, InterruptedException;
+ /**
+ * Starts processing of an async task. Returns immediately with async result. Executes callback
+ * when the task is completed.
+ *
+ * @param task task to be executed asynchronously
+ * @param callback callback to be executed on task completion
+ * @return async result for the task
+ */
+ AsyncResult startProcess(Callable task, AsyncCallback callback);
+ /**
+ * Ends processing of an async task. Blocks the current thread if necessary and returns the
+ * evaluated value of the completed task.
+ *
+ * @param asyncResult async result of a task
+ * @return evaluated value of the completed task
+ * @throws ExecutionException if execution has failed, containing the root cause
+ * @throws InterruptedException if the execution is interrupted
+ */
+ T endProcess(AsyncResult asyncResult) throws ExecutionException, InterruptedException;
}
diff --git a/async-method-invocation/src/main/java/com/iluwatar/async/method/invocation/AsyncResult.java b/async-method-invocation/src/main/java/com/iluwatar/async/method/invocation/AsyncResult.java
index 405bec251..bcd97adbc 100644
--- a/async-method-invocation/src/main/java/com/iluwatar/async/method/invocation/AsyncResult.java
+++ b/async-method-invocation/src/main/java/com/iluwatar/async/method/invocation/AsyncResult.java
@@ -1,3 +1,25 @@
+/**
+ * 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.async.method.invocation;
import java.util.concurrent.ExecutionException;
@@ -5,31 +27,29 @@ import java.util.concurrent.ExecutionException;
/**
*
* AsyncResult interface
- *
- * @param
*/
public interface AsyncResult {
- /**
- * Status of the async task execution.
- *
- * @return true
if execution is completed or failed
- */
- boolean isCompleted();
+ /**
+ * Status of the async task execution.
+ *
+ * @return true
if execution is completed or failed
+ */
+ boolean isCompleted();
- /**
- * Gets the value of completed async task.
- *
- * @return evaluated value or throws ExecutionException if execution has failed
- * @throws ExecutionException if execution has failed, containing the root cause
- * @throws IllegalStateException if execution is not completed
- */
- T getValue() throws ExecutionException;
+ /**
+ * Gets the value of completed async task.
+ *
+ * @return evaluated value or throws ExecutionException if execution has failed
+ * @throws ExecutionException if execution has failed, containing the root cause
+ * @throws IllegalStateException if execution is not completed
+ */
+ T getValue() throws ExecutionException;
- /**
- * Blocks the current thread until the async task is completed.
- *
- * @throws InterruptedException if the execution is interrupted
- */
- void await() throws InterruptedException;
+ /**
+ * Blocks the current thread until the async task is completed.
+ *
+ * @throws InterruptedException if the execution is interrupted
+ */
+ void await() throws InterruptedException;
}
diff --git a/async-method-invocation/src/main/java/com/iluwatar/async/method/invocation/ThreadAsyncExecutor.java b/async-method-invocation/src/main/java/com/iluwatar/async/method/invocation/ThreadAsyncExecutor.java
index a3ed51af3..7f96d9ab7 100644
--- a/async-method-invocation/src/main/java/com/iluwatar/async/method/invocation/ThreadAsyncExecutor.java
+++ b/async-method-invocation/src/main/java/com/iluwatar/async/method/invocation/ThreadAsyncExecutor.java
@@ -1,3 +1,25 @@
+/**
+ * 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.async.method.invocation;
import java.util.Optional;
@@ -12,116 +34,117 @@ import java.util.concurrent.atomic.AtomicInteger;
*/
public class ThreadAsyncExecutor implements AsyncExecutor {
- /** Index for thread naming */
- private final AtomicInteger idx = new AtomicInteger(0);
+ /** Index for thread naming */
+ private final AtomicInteger idx = new AtomicInteger(0);
- @Override
- public AsyncResult startProcess(Callable task) {
- return startProcess(task, null);
- }
+ @Override
+ public AsyncResult startProcess(Callable task) {
+ return startProcess(task, null);
+ }
- @Override
- public AsyncResult startProcess(Callable task, AsyncCallback callback) {
- CompletableResult result = new CompletableResult<>(callback);
- new Thread(() -> {
- try {
- result.setValue(task.call());
- } catch (Exception ex) {
- result.setException(ex);
- }
- }, "executor-" + idx.incrementAndGet()).start();
- return result;
- }
+ @Override
+ public AsyncResult startProcess(Callable task, AsyncCallback callback) {
+ CompletableResult result = new CompletableResult<>(callback);
+ new Thread(() -> {
+ try {
+ result.setValue(task.call());
+ } catch (Exception ex) {
+ result.setException(ex);
+ }
+ } , "executor-" + idx.incrementAndGet()).start();
+ return result;
+ }
- @Override
- public T endProcess(AsyncResult asyncResult) throws ExecutionException, InterruptedException {
- if (asyncResult.isCompleted()) {
- return asyncResult.getValue();
- } else {
- asyncResult.await();
- return asyncResult.getValue();
- }
- }
+ @Override
+ public T endProcess(AsyncResult asyncResult) throws ExecutionException, InterruptedException {
+ if (asyncResult.isCompleted()) {
+ return asyncResult.getValue();
+ } else {
+ asyncResult.await();
+ return asyncResult.getValue();
+ }
+ }
- /**
- * Simple implementation of async result that allows completing it successfully with a value
- * or exceptionally with an exception. A really simplified version from its real life cousins
- * FutureTask and CompletableFuture.
- *
- * @see java.util.concurrent.FutureTask
- * @see java.util.concurrent.CompletableFuture
- */
- private static class CompletableResult implements AsyncResult {
+ /**
+ * Simple implementation of async result that allows completing it successfully with a value or exceptionally with an
+ * exception. A really simplified version from its real life cousins FutureTask and CompletableFuture.
+ *
+ * @see java.util.concurrent.FutureTask
+ * @see java.util.concurrent.CompletableFuture
+ */
+ private static class CompletableResult implements AsyncResult {
- static final int RUNNING = 1;
- static final int FAILED = 2;
- static final int COMPLETED = 3;
+ static final int RUNNING = 1;
+ static final int FAILED = 2;
+ static final int COMPLETED = 3;
- final Object lock;
- final Optional> callback;
+ final Object lock;
+ final Optional> callback;
- volatile int state = RUNNING;
- T value;
- Exception exception;
+ volatile int state = RUNNING;
+ T value;
+ Exception exception;
- CompletableResult(AsyncCallback callback) {
- this.lock = new Object();
- this.callback = Optional.ofNullable(callback);
- }
+ CompletableResult(AsyncCallback callback) {
+ this.lock = new Object();
+ this.callback = Optional.ofNullable(callback);
+ }
- /**
- * Sets the value from successful execution and executes callback if available. Notifies
- * any thread waiting for completion.
- *
- * @param value value of the evaluated task
- */
- void setValue(T value) {
- this.value = value;
- this.state = COMPLETED;
- this.callback.ifPresent(ac -> ac.onComplete(value, Optional.empty()));
- synchronized (lock) {
- lock.notifyAll();
- }
- }
+ /**
+ * Sets the value from successful execution and executes callback if available. Notifies any thread waiting for
+ * completion.
+ *
+ * @param value
+ * value of the evaluated task
+ */
+ void setValue(T value) {
+ this.value = value;
+ this.state = COMPLETED;
+ this.callback.ifPresent(ac -> ac.onComplete(value, Optional.empty()));
+ synchronized (lock) {
+ lock.notifyAll();
+ }
+ }
- /**
- * Sets the exception from failed execution and executes callback if available. Notifies
- * any thread waiting for completion.
- *
- * @param exception exception of the failed task
- */
- void setException(Exception exception) {
- this.exception = exception;
- this.state = FAILED;
- this.callback.ifPresent(ac -> ac.onComplete(null, Optional.of(exception)));
- synchronized (lock) {
- lock.notifyAll();
- }
- }
+ /**
+ * Sets the exception from failed execution and executes callback if available. Notifies any thread waiting for
+ * completion.
+ *
+ * @param exception
+ * exception of the failed task
+ */
+ void setException(Exception exception) {
+ this.exception = exception;
+ this.state = FAILED;
+ this.callback.ifPresent(ac -> ac.onComplete(null, Optional.of(exception)));
+ synchronized (lock) {
+ lock.notifyAll();
+ }
+ }
- @Override
- public boolean isCompleted() {
- return (state > RUNNING);
- }
+ @Override
+ public boolean isCompleted() {
+ return state > RUNNING;
+ }
- @Override
- public T getValue() throws ExecutionException {
- if (state == COMPLETED) {
- return value;
- } else if (state == FAILED) {
- throw new ExecutionException(exception);
- } else {
- throw new IllegalStateException("Execution not completed yet");
- }
- }
+ @Override
+ public T getValue() throws ExecutionException {
+ if (state == COMPLETED) {
+ return value;
+ } else if (state == FAILED) {
+ throw new ExecutionException(exception);
+ } else {
+ throw new IllegalStateException("Execution not completed yet");
+ }
+ }
- @Override
- public void await() throws InterruptedException {
- synchronized (lock) {
- if (!isCompleted()) {
- lock.wait();
- }
- }
- }
- }
+ @Override
+ public void await() throws InterruptedException {
+ synchronized (lock) {
+ if (!isCompleted()) {
+ lock.wait();
+ }
+ }
+ }
+ }
}
diff --git a/async-method-invocation/src/test/java/com/iluwatar/async/method/invocation/AppTest.java b/async-method-invocation/src/test/java/com/iluwatar/async/method/invocation/AppTest.java
index 5faec5356..117a75f2a 100644
--- a/async-method-invocation/src/test/java/com/iluwatar/async/method/invocation/AppTest.java
+++ b/async-method-invocation/src/test/java/com/iluwatar/async/method/invocation/AppTest.java
@@ -1,3 +1,25 @@
+/**
+ * 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.async.method.invocation;
import org.junit.Test;
@@ -9,10 +31,9 @@ import org.junit.Test;
*/
public class AppTest {
- @Test
- public void test() throws Exception {
- String[] args = {};
- App.main(args);
- }
-
+ @Test
+ public void test() throws Exception {
+ String[] args = {};
+ App.main(args);
+ }
}
diff --git a/async-method-invocation/src/test/java/com/iluwatar/async/method/invocation/ThreadAsyncExecutorTest.java b/async-method-invocation/src/test/java/com/iluwatar/async/method/invocation/ThreadAsyncExecutorTest.java
new file mode 100644
index 000000000..b4a23222a
--- /dev/null
+++ b/async-method-invocation/src/test/java/com/iluwatar/async/method/invocation/ThreadAsyncExecutorTest.java
@@ -0,0 +1,312 @@
+/**
+ * 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.async.method.invocation;
+
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Matchers;
+
+import java.util.Optional;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+
+import static org.junit.Assert.*;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.*;
+import static org.mockito.internal.verification.VerificationModeFactory.times;
+
+/**
+ * Date: 12/6/15 - 10:49 AM
+ *
+ * @author Jeroen Meulemeester
+ */
+public class ThreadAsyncExecutorTest {
+
+ /**
+ * Test used to verify the happy path of {@link ThreadAsyncExecutor#startProcess(Callable)}
+ */
+ @Test(timeout = 3000)
+ public void testSuccessfulTaskWithoutCallback() throws Exception {
+ // Instantiate a new executor and start a new 'null' task ...
+ final ThreadAsyncExecutor executor = new ThreadAsyncExecutor();
+
+ final Object result = new Object();
+ final Callable task = mock(Callable.class);
+ when(task.call()).thenReturn(result);
+
+ final AsyncResult asyncResult = executor.startProcess(task);
+ assertNotNull(asyncResult);
+ asyncResult.await(); // Prevent timing issues, and wait until the result is available
+ assertTrue(asyncResult.isCompleted());
+
+ // Our task should only execute once ...
+ verify(task, times(1)).call();
+
+ // ... and the result should be exactly the same object
+ assertSame(result, asyncResult.getValue());
+ }
+
+ /**
+ * Test used to verify the happy path of {@link ThreadAsyncExecutor#startProcess(Callable, AsyncCallback)}
+ */
+ @Test(timeout = 3000)
+ public void testSuccessfulTaskWithCallback() throws Exception {
+ // Instantiate a new executor and start a new 'null' task ...
+ final ThreadAsyncExecutor executor = new ThreadAsyncExecutor();
+
+ final Object result = new Object();
+ final Callable task = mock(Callable.class);
+ when(task.call()).thenReturn(result);
+
+ final AsyncCallback callback = mock(AsyncCallback.class);
+ final AsyncResult asyncResult = executor.startProcess(task, callback);
+ assertNotNull(asyncResult);
+ asyncResult.await(); // Prevent timing issues, and wait until the result is available
+ assertTrue(asyncResult.isCompleted());
+
+ // Our task should only execute once ...
+ verify(task, times(1)).call();
+
+ // ... same for the callback, we expect our object
+ final ArgumentCaptor> optionalCaptor = ArgumentCaptor.forClass((Class) Optional.class);
+ verify(callback, times(1)).onComplete(eq(result), optionalCaptor.capture());
+
+ final Optional optionalException = optionalCaptor.getValue();
+ assertNotNull(optionalException);
+ assertFalse(optionalException.isPresent());
+
+ // ... and the result should be exactly the same object
+ assertSame(result, asyncResult.getValue());
+ }
+
+ /**
+ * Test used to verify the happy path of {@link ThreadAsyncExecutor#startProcess(Callable)} when a task takes a while
+ * to execute
+ */
+ @Test(timeout = 5000)
+ public void testLongRunningTaskWithoutCallback() throws Exception {
+ // Instantiate a new executor and start a new 'null' task ...
+ final ThreadAsyncExecutor executor = new ThreadAsyncExecutor();
+
+ final Object result = new Object();
+ final Callable task = mock(Callable.class);
+ when(task.call()).thenAnswer(i -> {
+ Thread.sleep(1500);
+ return result;
+ });
+
+ final AsyncResult asyncResult = executor.startProcess(task);
+ assertNotNull(asyncResult);
+ assertFalse(asyncResult.isCompleted());
+
+ try {
+ asyncResult.getValue();
+ fail("Expected IllegalStateException when calling AsyncResult#getValue on a non-completed task");
+ } catch (IllegalStateException e) {
+ assertNotNull(e.getMessage());
+ }
+
+ // Our task should only execute once, but it can take a while ...
+ verify(task, timeout(3000).times(1)).call();
+
+ // Prevent timing issues, and wait until the result is available
+ asyncResult.await();
+ assertTrue(asyncResult.isCompleted());
+ verifyNoMoreInteractions(task);
+
+ // ... and the result should be exactly the same object
+ assertSame(result, asyncResult.getValue());
+ }
+
+ /**
+ * Test used to verify the happy path of {@link ThreadAsyncExecutor#startProcess(Callable, AsyncCallback)} when a task
+ * takes a while to execute
+ */
+ @Test(timeout = 5000)
+ public void testLongRunningTaskWithCallback() throws Exception {
+ // Instantiate a new executor and start a new 'null' task ...
+ final ThreadAsyncExecutor executor = new ThreadAsyncExecutor();
+
+ final Object result = new Object();
+ final Callable task = mock(Callable.class);
+ when(task.call()).thenAnswer(i -> {
+ Thread.sleep(1500);
+ return result;
+ });
+
+ final AsyncCallback callback = mock(AsyncCallback.class);
+ final AsyncResult asyncResult = executor.startProcess(task, callback);
+ assertNotNull(asyncResult);
+ assertFalse(asyncResult.isCompleted());
+
+ verifyZeroInteractions(callback);
+
+ try {
+ asyncResult.getValue();
+ fail("Expected IllegalStateException when calling AsyncResult#getValue on a non-completed task");
+ } catch (IllegalStateException e) {
+ assertNotNull(e.getMessage());
+ }
+
+ // Our task should only execute once, but it can take a while ...
+ verify(task, timeout(3000).times(1)).call();
+
+ final ArgumentCaptor> optionalCaptor = ArgumentCaptor.forClass((Class) Optional.class);
+ verify(callback, timeout(3000).times(1)).onComplete(eq(result), optionalCaptor.capture());
+
+ final Optional optionalException = optionalCaptor.getValue();
+ assertNotNull(optionalException);
+ assertFalse(optionalException.isPresent());
+
+ // Prevent timing issues, and wait until the result is available
+ asyncResult.await();
+ assertTrue(asyncResult.isCompleted());
+ verifyNoMoreInteractions(task, callback);
+
+ // ... and the result should be exactly the same object
+ assertSame(result, asyncResult.getValue());
+ }
+
+ /**
+ * Test used to verify the happy path of {@link ThreadAsyncExecutor#startProcess(Callable)} when a task takes a while
+ * to execute, while waiting on the result using {@link ThreadAsyncExecutor#endProcess(AsyncResult)}
+ */
+ @Test(timeout = 5000)
+ public void testEndProcess() throws Exception {
+ // Instantiate a new executor and start a new 'null' task ...
+ final ThreadAsyncExecutor executor = new ThreadAsyncExecutor();
+
+ final Object result = new Object();
+ final Callable task = mock(Callable.class);
+ when(task.call()).thenAnswer(i -> {
+ Thread.sleep(1500);
+ return result;
+ });
+
+ final AsyncResult asyncResult = executor.startProcess(task);
+ assertNotNull(asyncResult);
+ assertFalse(asyncResult.isCompleted());
+
+ try {
+ asyncResult.getValue();
+ fail("Expected IllegalStateException when calling AsyncResult#getValue on a non-completed task");
+ } catch (IllegalStateException e) {
+ assertNotNull(e.getMessage());
+ }
+
+ assertSame(result, executor.endProcess(asyncResult));
+ verify(task, times(1)).call();
+ assertTrue(asyncResult.isCompleted());
+
+ // Calling end process a second time while already finished should give the same result
+ assertSame(result, executor.endProcess(asyncResult));
+ verifyNoMoreInteractions(task);
+ }
+
+ /**
+ * Test used to verify the behaviour of {@link ThreadAsyncExecutor#startProcess(Callable)} when the callable is 'null'
+ */
+ @Test(timeout = 3000)
+ public void testNullTask() throws Exception {
+ // Instantiate a new executor and start a new 'null' task ...
+ final ThreadAsyncExecutor executor = new ThreadAsyncExecutor();
+ final AsyncResult asyncResult = executor.startProcess(null);
+
+ assertNotNull("The AsyncResult should not be 'null', even though the task was 'null'.", asyncResult);
+ asyncResult.await(); // Prevent timing issues, and wait until the result is available
+ assertTrue(asyncResult.isCompleted());
+
+ try {
+ asyncResult.getValue();
+ fail("Expected ExecutionException with NPE as cause");
+ } catch (final ExecutionException e) {
+ assertNotNull(e.getMessage());
+ assertNotNull(e.getCause());
+ assertEquals(NullPointerException.class, e.getCause().getClass());
+ }
+
+ }
+
+ /**
+ * Test used to verify the behaviour of {@link ThreadAsyncExecutor#startProcess(Callable, AsyncCallback)} when the
+ * callable is 'null', but the asynchronous callback is provided
+ */
+ @Test(timeout = 3000)
+ public void testNullTaskWithCallback() throws Exception {
+ // Instantiate a new executor and start a new 'null' task ...
+ final ThreadAsyncExecutor executor = new ThreadAsyncExecutor();
+ final AsyncCallback callback = mock(AsyncCallback.class);
+ final AsyncResult asyncResult = executor.startProcess(null, callback);
+
+ assertNotNull("The AsyncResult should not be 'null', even though the task was 'null'.", asyncResult);
+ asyncResult.await(); // Prevent timing issues, and wait until the result is available
+ assertTrue(asyncResult.isCompleted());
+
+ final ArgumentCaptor> optionalCaptor = ArgumentCaptor.forClass((Class) Optional.class);
+ verify(callback, times(1)).onComplete(Matchers.isNull(), optionalCaptor.capture());
+
+ final Optional optionalException = optionalCaptor.getValue();
+ assertNotNull(optionalException);
+ assertTrue(optionalException.isPresent());
+
+ final Exception exception = optionalException.get();
+ assertNotNull(exception);
+ assertEquals(NullPointerException.class, exception.getClass());
+
+ try {
+ asyncResult.getValue();
+ fail("Expected ExecutionException with NPE as cause");
+ } catch (final ExecutionException e) {
+ assertNotNull(e.getMessage());
+ assertNotNull(e.getCause());
+ assertEquals(NullPointerException.class, e.getCause().getClass());
+ }
+
+ }
+
+ /**
+ * Test used to verify the behaviour of {@link ThreadAsyncExecutor#startProcess(Callable, AsyncCallback)} when both
+ * the callable and the asynchronous callback are 'null'
+ */
+ @Test(timeout = 3000)
+ public void testNullTaskWithNullCallback() throws Exception {
+ // Instantiate a new executor and start a new 'null' task ...
+ final ThreadAsyncExecutor executor = new ThreadAsyncExecutor();
+ final AsyncResult asyncResult = executor.startProcess(null, null);
+
+ assertNotNull("The AsyncResult should not be 'null', even though the task and callback were 'null'.", asyncResult);
+ asyncResult.await(); // Prevent timing issues, and wait until the result is available
+ assertTrue(asyncResult.isCompleted());
+
+ try {
+ asyncResult.getValue();
+ fail("Expected ExecutionException with NPE as cause");
+ } catch (final ExecutionException e) {
+ assertNotNull(e.getMessage());
+ assertNotNull(e.getCause());
+ assertEquals(NullPointerException.class, e.getCause().getClass());
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/bridge/index.md b/bridge/README.md
similarity index 87%
rename from bridge/index.md
rename to bridge/README.md
index 1ad969183..49dad14e4 100644
--- a/bridge/index.md
+++ b/bridge/README.md
@@ -7,15 +7,20 @@ categories: Structural
tags:
- Java
- Gang Of Four
+ - Difficulty-Intermediate
---
-**Intent:** Decouple an abstraction from its implementation so that the two can
-vary independently.
+## Also known as
+Handle/Body
+## Intent
+Decouple an abstraction from its implementation so that the two can
+vary independently.

-**Applicability:** Use the Bridge pattern when
+## Applicability
+Use the Bridge pattern when
* you want to avoid a permanent binding between an abstraction and its implementation. This might be the case, for example, when the implementation must be selected or switched at run-time.
* both the abstractions and their implementations should be extensible by subclassing. In this case, the Bridge pattern lets you combine the different abstractions and implementations and extend them independently
@@ -23,6 +28,6 @@ vary independently.
* 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.
-**Credits**
+## Credits
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)
diff --git a/bridge/pom.xml b/bridge/pom.xml
index 533074d72..a7a3883c8 100644
--- a/bridge/pom.xml
+++ b/bridge/pom.xml
@@ -1,11 +1,35 @@
+
4.0.0
com.iluwatar
java-design-patterns
- 1.7.0
+ 1.13.0-SNAPSHOT
bridge
@@ -14,5 +38,10 @@
junit
test
+
+ org.mockito
+ mockito-core
+ test
+
diff --git a/bridge/src/main/java/com/iluwatar/bridge/App.java b/bridge/src/main/java/com/iluwatar/bridge/App.java
index 972f49b2f..27b37b6b3 100644
--- a/bridge/src/main/java/com/iluwatar/bridge/App.java
+++ b/bridge/src/main/java/com/iluwatar/bridge/App.java
@@ -1,42 +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.bridge;
/**
*
- * The Bridge pattern can also be thought of as two layers of abstraction. With Bridge,
- * you can decouple an abstraction from its implementation so that the two can vary independently.
+ * The Bridge pattern can also be thought of as two layers of abstraction. With Bridge, you can
+ * decouple an abstraction from its implementation so that the two can vary independently.
*
- * In Bridge pattern both abstraction ({@link MagicWeapon}) and implementation
- * ({@link MagicWeaponImpl}) have their own class hierarchies. The interface of the
- * implementations can be changed without affecting the clients.
+ * In Bridge pattern both abstraction ({@link MagicWeapon}) and implementation (
+ * {@link MagicWeaponImpl}) have their own class hierarchies. The interface of the implementations
+ * can be changed without affecting the clients.
*
*/
public class App {
- /**
- * Program entry point
- * @param args command line args
- */
- public static void main(String[] args) {
- BlindingMagicWeapon blindingMagicWeapon = new BlindingMagicWeapon(
- new Excalibur());
- blindingMagicWeapon.wield();
- blindingMagicWeapon.blind();
- blindingMagicWeapon.swing();
- blindingMagicWeapon.unwield();
+ /**
+ * Program entry point
+ *
+ * @param args command line args
+ */
+ public static void main(String[] args) {
+ BlindingMagicWeapon blindingMagicWeapon = new BlindingMagicWeapon(new Excalibur());
+ blindingMagicWeapon.wield();
+ blindingMagicWeapon.blind();
+ blindingMagicWeapon.swing();
+ blindingMagicWeapon.unwield();
- FlyingMagicWeapon flyingMagicWeapon = new FlyingMagicWeapon(
- new Mjollnir());
- flyingMagicWeapon.wield();
- flyingMagicWeapon.fly();
- flyingMagicWeapon.swing();
- flyingMagicWeapon.unwield();
+ FlyingMagicWeapon flyingMagicWeapon = new FlyingMagicWeapon(new Mjollnir());
+ flyingMagicWeapon.wield();
+ flyingMagicWeapon.fly();
+ flyingMagicWeapon.swing();
+ flyingMagicWeapon.unwield();
- SoulEatingMagicWeapon soulEatingMagicWeapon = new SoulEatingMagicWeapon(
- new Stormbringer());
- soulEatingMagicWeapon.wield();
- soulEatingMagicWeapon.swing();
- soulEatingMagicWeapon.eatSoul();
- soulEatingMagicWeapon.unwield();
-
- }
+ SoulEatingMagicWeapon soulEatingMagicWeapon = new SoulEatingMagicWeapon(new Stormbringer());
+ soulEatingMagicWeapon.wield();
+ soulEatingMagicWeapon.swing();
+ soulEatingMagicWeapon.eatSoul();
+ soulEatingMagicWeapon.unwield();
+ }
}
diff --git a/bridge/src/main/java/com/iluwatar/bridge/BlindingMagicWeapon.java b/bridge/src/main/java/com/iluwatar/bridge/BlindingMagicWeapon.java
index bf4bac8f9..045039ef0 100644
--- a/bridge/src/main/java/com/iluwatar/bridge/BlindingMagicWeapon.java
+++ b/bridge/src/main/java/com/iluwatar/bridge/BlindingMagicWeapon.java
@@ -1,3 +1,25 @@
+/**
+ * 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.bridge;
/**
@@ -7,32 +29,31 @@ package com.iluwatar.bridge;
*/
public class BlindingMagicWeapon extends MagicWeapon {
- public BlindingMagicWeapon(BlindingMagicWeaponImpl imp) {
- super(imp);
- }
+ public BlindingMagicWeapon(BlindingMagicWeaponImpl imp) {
+ super(imp);
+ }
- @Override
- public BlindingMagicWeaponImpl getImp() {
- return (BlindingMagicWeaponImpl) imp;
- }
+ @Override
+ public BlindingMagicWeaponImpl getImp() {
+ return (BlindingMagicWeaponImpl) imp;
+ }
- @Override
- public void wield() {
- getImp().wieldImp();
- }
+ @Override
+ public void wield() {
+ getImp().wieldImp();
+ }
- @Override
- public void swing() {
- getImp().swingImp();
- }
+ @Override
+ public void swing() {
+ getImp().swingImp();
+ }
- @Override
- public void unwield() {
- getImp().unwieldImp();
- }
-
- public void blind() {
- getImp().blindImp();
- }
+ @Override
+ public void unwield() {
+ getImp().unwieldImp();
+ }
+ public void blind() {
+ getImp().blindImp();
+ }
}
diff --git a/bridge/src/main/java/com/iluwatar/bridge/BlindingMagicWeaponImpl.java b/bridge/src/main/java/com/iluwatar/bridge/BlindingMagicWeaponImpl.java
index 31dffb042..83f31e709 100644
--- a/bridge/src/main/java/com/iluwatar/bridge/BlindingMagicWeaponImpl.java
+++ b/bridge/src/main/java/com/iluwatar/bridge/BlindingMagicWeaponImpl.java
@@ -1,3 +1,25 @@
+/**
+ * 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.bridge;
/**
@@ -7,6 +29,6 @@ package com.iluwatar.bridge;
*/
public abstract class BlindingMagicWeaponImpl extends MagicWeaponImpl {
- public abstract void blindImp();
+ public abstract void blindImp();
}
diff --git a/bridge/src/main/java/com/iluwatar/bridge/Excalibur.java b/bridge/src/main/java/com/iluwatar/bridge/Excalibur.java
index 9f7078139..2523b3557 100644
--- a/bridge/src/main/java/com/iluwatar/bridge/Excalibur.java
+++ b/bridge/src/main/java/com/iluwatar/bridge/Excalibur.java
@@ -1,3 +1,25 @@
+/**
+ * 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.bridge;
/**
@@ -7,25 +29,23 @@ package com.iluwatar.bridge;
*/
public class Excalibur extends BlindingMagicWeaponImpl {
- @Override
- public void wieldImp() {
- System.out.println("wielding Excalibur");
- }
+ @Override
+ public void wieldImp() {
+ System.out.println("wielding Excalibur");
+ }
- @Override
- public void swingImp() {
- System.out.println("swinging Excalibur");
- }
+ @Override
+ public void swingImp() {
+ System.out.println("swinging Excalibur");
+ }
- @Override
- public void unwieldImp() {
- System.out.println("unwielding Excalibur");
- }
-
- @Override
- public void blindImp() {
- System.out
- .println("bright light streams from Excalibur blinding the enemy");
- }
+ @Override
+ public void unwieldImp() {
+ System.out.println("unwielding Excalibur");
+ }
+ @Override
+ public void blindImp() {
+ System.out.println("bright light streams from Excalibur blinding the enemy");
+ }
}
diff --git a/bridge/src/main/java/com/iluwatar/bridge/FlyingMagicWeapon.java b/bridge/src/main/java/com/iluwatar/bridge/FlyingMagicWeapon.java
index 542e7d97e..0988c179c 100644
--- a/bridge/src/main/java/com/iluwatar/bridge/FlyingMagicWeapon.java
+++ b/bridge/src/main/java/com/iluwatar/bridge/FlyingMagicWeapon.java
@@ -1,3 +1,25 @@
+/**
+ * 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.bridge;
/**
@@ -7,31 +29,31 @@ package com.iluwatar.bridge;
*/
public class FlyingMagicWeapon extends MagicWeapon {
- public FlyingMagicWeapon(FlyingMagicWeaponImpl imp) {
- super(imp);
- }
+ public FlyingMagicWeapon(FlyingMagicWeaponImpl imp) {
+ super(imp);
+ }
- public FlyingMagicWeaponImpl getImp() {
- return (FlyingMagicWeaponImpl) imp;
- }
+ public FlyingMagicWeaponImpl getImp() {
+ return (FlyingMagicWeaponImpl) imp;
+ }
- @Override
- public void wield() {
- getImp().wieldImp();
- }
+ @Override
+ public void wield() {
+ getImp().wieldImp();
+ }
- @Override
- public void swing() {
- getImp().swingImp();
- }
+ @Override
+ public void swing() {
+ getImp().swingImp();
+ }
- @Override
- public void unwield() {
- getImp().unwieldImp();
- }
+ @Override
+ public void unwield() {
+ getImp().unwieldImp();
+ }
- public void fly() {
- getImp().flyImp();
- }
+ public void fly() {
+ getImp().flyImp();
+ }
}
diff --git a/bridge/src/main/java/com/iluwatar/bridge/FlyingMagicWeaponImpl.java b/bridge/src/main/java/com/iluwatar/bridge/FlyingMagicWeaponImpl.java
index 8b7a10f2f..4bdb8801b 100644
--- a/bridge/src/main/java/com/iluwatar/bridge/FlyingMagicWeaponImpl.java
+++ b/bridge/src/main/java/com/iluwatar/bridge/FlyingMagicWeaponImpl.java
@@ -1,3 +1,25 @@
+/**
+ * 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.bridge;
/**
@@ -7,6 +29,6 @@ package com.iluwatar.bridge;
*/
public abstract class FlyingMagicWeaponImpl extends MagicWeaponImpl {
- public abstract void flyImp();
+ public abstract void flyImp();
}
diff --git a/bridge/src/main/java/com/iluwatar/bridge/MagicWeapon.java b/bridge/src/main/java/com/iluwatar/bridge/MagicWeapon.java
index b2b82839c..038da7c4f 100644
--- a/bridge/src/main/java/com/iluwatar/bridge/MagicWeapon.java
+++ b/bridge/src/main/java/com/iluwatar/bridge/MagicWeapon.java
@@ -1,3 +1,25 @@
+/**
+ * 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.bridge;
/**
@@ -7,20 +29,19 @@ package com.iluwatar.bridge;
*/
public abstract class MagicWeapon {
- protected MagicWeaponImpl imp;
+ protected MagicWeaponImpl imp;
- public MagicWeapon(MagicWeaponImpl imp) {
- this.imp = imp;
- }
+ public MagicWeapon(MagicWeaponImpl imp) {
+ this.imp = imp;
+ }
- public abstract void wield();
+ public abstract void wield();
- public abstract void swing();
+ public abstract void swing();
- public abstract void unwield();
-
- public MagicWeaponImpl getImp() {
- return imp;
- }
+ public abstract void unwield();
+ public MagicWeaponImpl getImp() {
+ return imp;
+ }
}
diff --git a/bridge/src/main/java/com/iluwatar/bridge/MagicWeaponImpl.java b/bridge/src/main/java/com/iluwatar/bridge/MagicWeaponImpl.java
index bd2a3b8d7..01f91825b 100644
--- a/bridge/src/main/java/com/iluwatar/bridge/MagicWeaponImpl.java
+++ b/bridge/src/main/java/com/iluwatar/bridge/MagicWeaponImpl.java
@@ -1,3 +1,25 @@
+/**
+ * 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.bridge;
/**
@@ -7,10 +29,10 @@ package com.iluwatar.bridge;
*/
public abstract class MagicWeaponImpl {
- public abstract void wieldImp();
+ public abstract void wieldImp();
- public abstract void swingImp();
+ public abstract void swingImp();
- public abstract void unwieldImp();
+ public abstract void unwieldImp();
}
diff --git a/bridge/src/main/java/com/iluwatar/bridge/Mjollnir.java b/bridge/src/main/java/com/iluwatar/bridge/Mjollnir.java
index 887173add..0cc31b471 100644
--- a/bridge/src/main/java/com/iluwatar/bridge/Mjollnir.java
+++ b/bridge/src/main/java/com/iluwatar/bridge/Mjollnir.java
@@ -1,3 +1,25 @@
+/**
+ * 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.bridge;
/**
@@ -7,25 +29,23 @@ package com.iluwatar.bridge;
*/
public class Mjollnir extends FlyingMagicWeaponImpl {
- @Override
- public void wieldImp() {
- System.out.println("wielding Mjollnir");
- }
+ @Override
+ public void wieldImp() {
+ System.out.println("wielding Mjollnir");
+ }
- @Override
- public void swingImp() {
- System.out.println("swinging Mjollnir");
- }
+ @Override
+ public void swingImp() {
+ System.out.println("swinging Mjollnir");
+ }
- @Override
- public void unwieldImp() {
- System.out.println("unwielding Mjollnir");
- }
-
- @Override
- public void flyImp() {
- System.out
- .println("Mjollnir hits the enemy in the air and returns back to the owner's hand");
- }
+ @Override
+ public void unwieldImp() {
+ System.out.println("unwielding Mjollnir");
+ }
+ @Override
+ public void flyImp() {
+ System.out.println("Mjollnir hits the enemy in the air and returns back to the owner's hand");
+ }
}
diff --git a/bridge/src/main/java/com/iluwatar/bridge/SoulEatingMagicWeapon.java b/bridge/src/main/java/com/iluwatar/bridge/SoulEatingMagicWeapon.java
index 3310b6488..d62f7644b 100644
--- a/bridge/src/main/java/com/iluwatar/bridge/SoulEatingMagicWeapon.java
+++ b/bridge/src/main/java/com/iluwatar/bridge/SoulEatingMagicWeapon.java
@@ -1,3 +1,25 @@
+/**
+ * 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.bridge;
/**
@@ -7,32 +29,32 @@ package com.iluwatar.bridge;
*/
public class SoulEatingMagicWeapon extends MagicWeapon {
- public SoulEatingMagicWeapon(SoulEatingMagicWeaponImpl imp) {
- super(imp);
- }
+ public SoulEatingMagicWeapon(SoulEatingMagicWeaponImpl imp) {
+ super(imp);
+ }
- @Override
- public SoulEatingMagicWeaponImpl getImp() {
- return (SoulEatingMagicWeaponImpl) imp;
- }
+ @Override
+ public SoulEatingMagicWeaponImpl getImp() {
+ return (SoulEatingMagicWeaponImpl) imp;
+ }
- @Override
- public void wield() {
- getImp().wieldImp();
- }
+ @Override
+ public void wield() {
+ getImp().wieldImp();
+ }
- @Override
- public void swing() {
- getImp().swingImp();
- }
+ @Override
+ public void swing() {
+ getImp().swingImp();
+ }
- @Override
- public void unwield() {
- getImp().unwieldImp();
- }
+ @Override
+ public void unwield() {
+ getImp().unwieldImp();
+ }
- public void eatSoul() {
- getImp().eatSoulImp();
- }
+ public void eatSoul() {
+ getImp().eatSoulImp();
+ }
}
diff --git a/bridge/src/main/java/com/iluwatar/bridge/SoulEatingMagicWeaponImpl.java b/bridge/src/main/java/com/iluwatar/bridge/SoulEatingMagicWeaponImpl.java
index 9ec112031..ad8bec48f 100644
--- a/bridge/src/main/java/com/iluwatar/bridge/SoulEatingMagicWeaponImpl.java
+++ b/bridge/src/main/java/com/iluwatar/bridge/SoulEatingMagicWeaponImpl.java
@@ -1,3 +1,25 @@
+/**
+ * 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.bridge;
/**
@@ -7,6 +29,6 @@ package com.iluwatar.bridge;
*/
public abstract class SoulEatingMagicWeaponImpl extends MagicWeaponImpl {
- public abstract void eatSoulImp();
+ public abstract void eatSoulImp();
}
diff --git a/bridge/src/main/java/com/iluwatar/bridge/Stormbringer.java b/bridge/src/main/java/com/iluwatar/bridge/Stormbringer.java
index 589156fe3..91cad9cc2 100644
--- a/bridge/src/main/java/com/iluwatar/bridge/Stormbringer.java
+++ b/bridge/src/main/java/com/iluwatar/bridge/Stormbringer.java
@@ -1,3 +1,25 @@
+/**
+ * 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.bridge;
/**
@@ -7,24 +29,23 @@ package com.iluwatar.bridge;
*/
public class Stormbringer extends SoulEatingMagicWeaponImpl {
- @Override
- public void wieldImp() {
- System.out.println("wielding Stormbringer");
- }
+ @Override
+ public void wieldImp() {
+ System.out.println("wielding Stormbringer");
+ }
- @Override
- public void swingImp() {
- System.out.println("swinging Stormbringer");
- }
+ @Override
+ public void swingImp() {
+ System.out.println("swinging Stormbringer");
+ }
- @Override
- public void unwieldImp() {
- System.out.println("unwielding Stormbringer");
- }
-
- @Override
- public void eatSoulImp() {
- System.out.println("Stormbringer devours the enemy's soul");
- }
+ @Override
+ public void unwieldImp() {
+ System.out.println("unwielding Stormbringer");
+ }
+ @Override
+ public void eatSoulImp() {
+ System.out.println("Stormbringer devours the enemy's soul");
+ }
}
diff --git a/bridge/src/test/java/com/iluwatar/bridge/AppTest.java b/bridge/src/test/java/com/iluwatar/bridge/AppTest.java
index b53111c8e..1b9b63d7f 100644
--- a/bridge/src/test/java/com/iluwatar/bridge/AppTest.java
+++ b/bridge/src/test/java/com/iluwatar/bridge/AppTest.java
@@ -1,9 +1,29 @@
+/**
+ * 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.bridge;
import org.junit.Test;
-import com.iluwatar.bridge.App;
-
/**
*
* Application test
@@ -11,9 +31,9 @@ import com.iluwatar.bridge.App;
*/
public class AppTest {
- @Test
- public void test() {
- String[] args = {};
- App.main(args);
- }
+ @Test
+ public void test() {
+ String[] args = {};
+ App.main(args);
+ }
}
diff --git a/bridge/src/test/java/com/iluwatar/bridge/BlindingMagicWeaponTest.java b/bridge/src/test/java/com/iluwatar/bridge/BlindingMagicWeaponTest.java
new file mode 100644
index 000000000..54435555e
--- /dev/null
+++ b/bridge/src/test/java/com/iluwatar/bridge/BlindingMagicWeaponTest.java
@@ -0,0 +1,55 @@
+/**
+ * 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.bridge;
+
+import org.junit.Test;
+
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.internal.verification.VerificationModeFactory.times;
+
+/**
+ * Date: 12/6/15 - 11:15 PM
+ *
+ * @author Jeroen Meulemeester
+ */
+public class BlindingMagicWeaponTest extends MagicWeaponTest {
+
+ /**
+ * Invoke all possible actions on the weapon and check if the actions are executed on the actual
+ * underlying weapon implementation.
+ */
+ @Test
+ public void testExcalibur() throws Exception {
+ final Excalibur excalibur = spy(new Excalibur());
+ final BlindingMagicWeapon blindingMagicWeapon = new BlindingMagicWeapon(excalibur);
+
+ testBasicWeaponActions(blindingMagicWeapon, excalibur);
+
+ blindingMagicWeapon.blind();
+ verify(excalibur, times(1)).blindImp();
+ verifyNoMoreInteractions(excalibur);
+ }
+
+}
diff --git a/bridge/src/test/java/com/iluwatar/bridge/FlyingMagicWeaponTest.java b/bridge/src/test/java/com/iluwatar/bridge/FlyingMagicWeaponTest.java
new file mode 100644
index 000000000..9053a7bb0
--- /dev/null
+++ b/bridge/src/test/java/com/iluwatar/bridge/FlyingMagicWeaponTest.java
@@ -0,0 +1,55 @@
+/**
+ * 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.bridge;
+
+import org.junit.Test;
+
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.internal.verification.VerificationModeFactory.times;
+
+/**
+ * Date: 12/6/15 - 11:26 PM
+ *
+ * @author Jeroen Meulemeester
+ */
+public class FlyingMagicWeaponTest extends MagicWeaponTest {
+
+ /**
+ * Invoke all possible actions on the weapon and check if the actions are executed on the actual
+ * underlying weapon implementation.
+ */
+ @Test
+ public void testMjollnir() throws Exception {
+ final Mjollnir mjollnir = spy(new Mjollnir());
+ final FlyingMagicWeapon flyingMagicWeapon = new FlyingMagicWeapon(mjollnir);
+
+ testBasicWeaponActions(flyingMagicWeapon, mjollnir);
+
+ flyingMagicWeapon.fly();
+ verify(mjollnir, times(1)).flyImp();
+ verifyNoMoreInteractions(mjollnir);
+ }
+
+}
\ No newline at end of file
diff --git a/bridge/src/test/java/com/iluwatar/bridge/MagicWeaponTest.java b/bridge/src/test/java/com/iluwatar/bridge/MagicWeaponTest.java
new file mode 100644
index 000000000..6408fd256
--- /dev/null
+++ b/bridge/src/test/java/com/iluwatar/bridge/MagicWeaponTest.java
@@ -0,0 +1,64 @@
+/**
+ * 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.bridge;
+
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.internal.verification.VerificationModeFactory.times;
+
+/**
+ * Date: 12/6/15 - 11:28 PM
+ *
+ * @author Jeroen Meulemeester
+ */
+public abstract class MagicWeaponTest {
+
+ /**
+ * Invoke the basic actions of the given weapon, and test if the underlying weapon implementation
+ * is invoked
+ *
+ * @param weaponImpl The spied weapon implementation where actions are bridged to
+ * @param weapon The weapon, handled by the app
+ */
+ protected final void testBasicWeaponActions(final MagicWeapon weapon,
+ final MagicWeaponImpl weaponImpl) {
+ assertNotNull(weapon);
+ assertNotNull(weaponImpl);
+ assertNotNull(weapon.getImp());
+
+ weapon.swing();
+ verify(weaponImpl, times(1)).swingImp();
+ verifyNoMoreInteractions(weaponImpl);
+
+ weapon.wield();
+ verify(weaponImpl, times(1)).wieldImp();
+ verifyNoMoreInteractions(weaponImpl);
+
+ weapon.unwield();
+ verify(weaponImpl, times(1)).unwieldImp();
+ verifyNoMoreInteractions(weaponImpl);
+
+ }
+
+}
diff --git a/bridge/src/test/java/com/iluwatar/bridge/SoulEatingMagicWeaponTest.java b/bridge/src/test/java/com/iluwatar/bridge/SoulEatingMagicWeaponTest.java
new file mode 100644
index 000000000..0bd0a6b8d
--- /dev/null
+++ b/bridge/src/test/java/com/iluwatar/bridge/SoulEatingMagicWeaponTest.java
@@ -0,0 +1,55 @@
+/**
+ * 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.bridge;
+
+import org.junit.Test;
+
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.internal.verification.VerificationModeFactory.times;
+
+/**
+ * Date: 12/6/15 - 11:43 PM
+ *
+ * @author Jeroen Meulemeester
+ */
+public class SoulEatingMagicWeaponTest extends MagicWeaponTest {
+
+ /**
+ * Invoke all possible actions on the weapon and check if the actions are executed on the actual
+ * underlying weapon implementation.
+ */
+ @Test
+ public void testStormBringer() throws Exception {
+ final Stormbringer stormbringer = spy(new Stormbringer());
+ final SoulEatingMagicWeapon soulEatingMagicWeapon = new SoulEatingMagicWeapon(stormbringer);
+
+ testBasicWeaponActions(soulEatingMagicWeapon, stormbringer);
+
+ soulEatingMagicWeapon.eatSoul();
+ verify(stormbringer, times(1)).eatSoulImp();
+ verifyNoMoreInteractions(stormbringer);
+ }
+
+}
\ No newline at end of file
diff --git a/builder/index.md b/builder/README.md
similarity index 76%
rename from builder/index.md
rename to builder/README.md
index f350638d2..5d1f3d24d 100644
--- a/builder/index.md
+++ b/builder/README.md
@@ -7,24 +7,28 @@ categories: Creational
tags:
- Java
- Gang Of Four
+ - Difficulty-Intermediate
---
-**Intent:** Separate the construction of a complex object from its
+## Intent
+Separate the construction of a complex object from its
representation so that the same construction process can create different
representations.

-**Applicability:** Use the Builder pattern when
+## Applicability
+Use the Builder pattern when
* the algorithm for creating a complex object should be independent of the parts that make up the object and how they're assembled
* the construction process must allow different representations for the object that's constructed
-**Real world examples:**
+## Real world examples
* [java.lang.StringBuilder](http://docs.oracle.com/javase/8/docs/api/java/lang/StringBuilder.html)
* [Apache Camel builders](https://github.com/apache/camel/tree/0e195428ee04531be27a0b659005e3aa8d159d23/camel-core/src/main/java/org/apache/camel/builder)
-**Credits**
+## Credits
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)
+* [Effective Java (2nd Edition)](http://www.amazon.com/Effective-Java-Edition-Joshua-Bloch/dp/0321356683)
diff --git a/builder/etc/builder.ucls b/builder/etc/builder.ucls
index 06a83ced7..073c5cea7 100644
--- a/builder/etc/builder.ucls
+++ b/builder/etc/builder.ucls
@@ -28,7 +28,7 @@
-
+
4.0.0
com.iluwatar
java-design-patterns
- 1.7.0
+ 1.13.0-SNAPSHOT
builder
diff --git a/builder/src/main/java/com/iluwatar/builder/App.java b/builder/src/main/java/com/iluwatar/builder/App.java
index b6131c3ab..d421de7b6 100644
--- a/builder/src/main/java/com/iluwatar/builder/App.java
+++ b/builder/src/main/java/com/iluwatar/builder/App.java
@@ -1,55 +1,77 @@
+/**
+ * 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.builder;
-import com.iluwatar. builder.Hero.HeroBuilder;
+import com.iluwatar.builder.Hero.Builder;
/**
*
- * The intention of the Builder pattern is to find a solution to the telescoping
- * constructor anti-pattern. The telescoping constructor anti-pattern occurs when the
- * increase of object constructor parameter combination leads to an exponential list
- * of constructors. Instead of using numerous constructors, the builder pattern uses
- * another object, a builder, that receives each initialization parameter step by step
- * and then returns the resulting constructed object at once.
+ * The intention of the Builder pattern is to find a solution to the telescoping constructor
+ * anti-pattern. The telescoping constructor anti-pattern occurs when the increase of object
+ * constructor parameter combination leads to an exponential list of constructors. Instead of using
+ * numerous constructors, the builder pattern uses another object, a builder, that receives each
+ * initialization parameter step by step and then returns the resulting constructed object at once.
*
- * The Builder pattern has another benefit. It can be used for objects that contain
- * flat data (html code, SQL query, X.509 certificate...), that is to say, data that
- * can't be easily edited. This type of data cannot be edited step by step and must
- * be edited at once. The best way to construct such an object is to use a builder
- * class.
+ * The Builder pattern has another benefit. It can be used for objects that contain flat data (html
+ * code, SQL query, X.509 certificate...), that is to say, data that can't be easily edited. This
+ * type of data cannot be edited step by step and must be edited at once. The best way to construct
+ * such an object is to use a builder class.
*
- * In this example we have the Builder pattern variation as described by Joshua Bloch in
- * Effective Java 2nd Edition.
+ * In this example we have the Builder pattern variation as described by Joshua Bloch in Effective
+ * Java 2nd Edition.
*
- * We want to build {@link Hero} objects, but its construction is complex because of the
- * many parameters needed. To aid the user we introduce {@link HeroBuilder} class.
- * {@link HeroBuilder} takes the minimum parameters to build {@link Hero} object in its
- * constructor. After that additional configuration for the {@link Hero} object can be
- * done using the fluent {@link HeroBuilder} interface. When configuration is ready the
- * build method is called to receive the final {@link Hero} object.
+ * We want to build {@link Hero} objects, but its construction is complex because of the many
+ * parameters needed. To aid the user we introduce {@link Builder} class. {@link Hero.Builder}
+ * takes the minimum parameters to build {@link Hero} object in its constructor. After that
+ * additional configuration for the {@link Hero} object can be done using the fluent
+ * {@link Builder} interface. When configuration is ready the build method is called to receive
+ * the final {@link Hero} object.
*
*/
public class App {
- /**
- * Program entry point
- * @param args command line args
- */
- public static void main(String[] args) {
+ /**
+ * Program entry point
+ *
+ * @param args command line args
+ */
+ public static void main(String[] args) {
- Hero mage = new HeroBuilder(Profession.MAGE, "Riobard")
- .withHairColor(HairColor.BLACK).withWeapon(Weapon.DAGGER)
- .build();
- System.out.println(mage);
+ Hero mage =
+ new Hero.Builder(Profession.MAGE, "Riobard").withHairColor(HairColor.BLACK)
+ .withWeapon(Weapon.DAGGER).build();
+ System.out.println(mage);
- Hero warrior = new HeroBuilder(Profession.WARRIOR, "Amberjill")
- .withHairColor(HairColor.BLOND)
- .withHairType(HairType.LONG_CURLY).withArmor(Armor.CHAIN_MAIL)
- .withWeapon(Weapon.SWORD).build();
- System.out.println(warrior);
+ Hero warrior =
+ new Hero.Builder(Profession.WARRIOR, "Amberjill").withHairColor(HairColor.BLOND)
+ .withHairType(HairType.LONG_CURLY).withArmor(Armor.CHAIN_MAIL).withWeapon(Weapon.SWORD)
+ .build();
+ System.out.println(warrior);
- Hero thief = new HeroBuilder(Profession.THIEF, "Desmond")
- .withHairType(HairType.BALD).withWeapon(Weapon.BOW).build();
- System.out.println(thief);
+ Hero thief =
+ new Hero.Builder(Profession.THIEF, "Desmond").withHairType(HairType.BALD)
+ .withWeapon(Weapon.BOW).build();
+ System.out.println(thief);
- }
+ }
}
diff --git a/builder/src/main/java/com/iluwatar/builder/Armor.java b/builder/src/main/java/com/iluwatar/builder/Armor.java
index 95fcba43b..a0a4fe582 100644
--- a/builder/src/main/java/com/iluwatar/builder/Armor.java
+++ b/builder/src/main/java/com/iluwatar/builder/Armor.java
@@ -1,3 +1,25 @@
+/**
+ * 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.builder;
/**
@@ -7,16 +29,16 @@ package com.iluwatar.builder;
*/
public enum Armor {
- CLOTHES("clothes"), LEATHER("leather"), CHAIN_MAIL("chain mail"), PLATE_MAIL("plate mail");
+ CLOTHES("clothes"), LEATHER("leather"), CHAIN_MAIL("chain mail"), PLATE_MAIL("plate mail");
- private String title;
+ private String title;
- Armor(String title) {
- this.title = title;
- }
+ Armor(String title) {
+ this.title = title;
+ }
- @Override
- public String toString() {
- return title;
- }
+ @Override
+ public String toString() {
+ return title;
+ }
}
diff --git a/builder/src/main/java/com/iluwatar/builder/HairColor.java b/builder/src/main/java/com/iluwatar/builder/HairColor.java
index dd8ec2ecc..3c3195cc6 100644
--- a/builder/src/main/java/com/iluwatar/builder/HairColor.java
+++ b/builder/src/main/java/com/iluwatar/builder/HairColor.java
@@ -1,3 +1,25 @@
+/**
+ * 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.builder;
/**
@@ -7,11 +29,11 @@ package com.iluwatar.builder;
*/
public enum HairColor {
- WHITE, BLOND, RED, BROWN, BLACK;
+ WHITE, BLOND, RED, BROWN, BLACK;
- @Override
- public String toString() {
- return name().toLowerCase();
- }
+ @Override
+ public String toString() {
+ return name().toLowerCase();
+ }
}
diff --git a/builder/src/main/java/com/iluwatar/builder/HairType.java b/builder/src/main/java/com/iluwatar/builder/HairType.java
index ea49c0470..8d15b0f30 100644
--- a/builder/src/main/java/com/iluwatar/builder/HairType.java
+++ b/builder/src/main/java/com/iluwatar/builder/HairType.java
@@ -1,3 +1,25 @@
+/**
+ * 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.builder;
/**
@@ -7,16 +29,17 @@ package com.iluwatar.builder;
*/
public enum HairType {
- BALD("bald"), SHORT("short"), CURLY("curly"), LONG_STRAIGHT("long straight"), LONG_CURLY("long curly");
+ BALD("bald"), SHORT("short"), CURLY("curly"), LONG_STRAIGHT("long straight"), LONG_CURLY(
+ "long curly");
- private String title;
+ private String title;
- HairType(String title) {
- this.title = title;
- }
+ HairType(String title) {
+ this.title = title;
+ }
- @Override
- public String toString() {
- return title;
- }
+ @Override
+ public String toString() {
+ return title;
+ }
}
diff --git a/builder/src/main/java/com/iluwatar/builder/Hero.java b/builder/src/main/java/com/iluwatar/builder/Hero.java
index 05304bf09..25445851a 100644
--- a/builder/src/main/java/com/iluwatar/builder/Hero.java
+++ b/builder/src/main/java/com/iluwatar/builder/Hero.java
@@ -1,3 +1,25 @@
+/**
+ * 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.builder;
/**
@@ -5,125 +27,123 @@ package com.iluwatar.builder;
* Hero, the class with many parameters.
*
*/
-public class Hero {
+public final class Hero {
- private final Profession profession;
- private final String name;
- private final HairType hairType;
- private final HairColor hairColor;
- private final Armor armor;
- private final Weapon weapon;
+ private final Profession profession;
+ private final String name;
+ private final HairType hairType;
+ private final HairColor hairColor;
+ private final Armor armor;
+ private final Weapon weapon;
- public Profession getProfession() {
- return profession;
- }
+ private Hero(Builder builder) {
+ this.profession = builder.profession;
+ this.name = builder.name;
+ this.hairColor = builder.hairColor;
+ this.hairType = builder.hairType;
+ this.weapon = builder.weapon;
+ this.armor = builder.armor;
+ }
- public String getName() {
- return name;
- }
+ public Profession getProfession() {
+ return profession;
+ }
- public HairType getHairType() {
- return hairType;
- }
+ public String getName() {
+ return name;
+ }
- public HairColor getHairColor() {
- return hairColor;
- }
+ public HairType getHairType() {
+ return hairType;
+ }
- public Armor getArmor() {
- return armor;
- }
+ public HairColor getHairColor() {
+ return hairColor;
+ }
- public Weapon getWeapon() {
- return weapon;
- }
+ public Armor getArmor() {
+ return armor;
+ }
- @Override
- public String toString() {
+ public Weapon getWeapon() {
+ return weapon;
+ }
- StringBuilder sb = new StringBuilder();
- sb.append("This is a ");
- sb.append(profession);
- sb.append(" named ");
- sb.append(name);
- if (hairColor != null || hairType != null) {
- sb.append(" with ");
- if (hairColor != null) {
- sb.append(hairColor);
- sb.append(" ");
- }
- if (hairType != null) {
- sb.append(hairType);
- sb.append(" ");
- }
- sb.append(hairType != HairType.BALD ? "hair" : "head");
- }
- if (armor != null) {
- sb.append(" wearing ");
- sb.append(armor);
- }
- if (weapon != null) {
- sb.append(" and wielding a ");
- sb.append(weapon);
- }
- sb.append(".");
- return sb.toString();
- }
+ @Override
+ public String toString() {
- private Hero(HeroBuilder builder) {
- this.profession = builder.profession;
- this.name = builder.name;
- this.hairColor = builder.hairColor;
- this.hairType = builder.hairType;
- this.weapon = builder.weapon;
- this.armor = builder.armor;
- }
+ StringBuilder sb = new StringBuilder();
+ sb.append("This is a ")
+ .append(profession)
+ .append(" named ")
+ .append(name);
+ if (hairColor != null || hairType != null) {
+ sb.append(" with ");
+ if (hairColor != null) {
+ sb.append(hairColor).append(' ');
+ }
+ if (hairType != null) {
+ sb.append(hairType).append(' ');
+ }
+ sb.append(hairType != HairType.BALD ? "hair" : "head");
+ }
+ if (armor != null) {
+ sb.append(" wearing ").append(armor);
+ }
+ if (weapon != null) {
+ sb.append(" and wielding a ").append(weapon);
+ }
+ sb.append('.');
+ return sb.toString();
+ }
- /**
- *
- * The builder class.
- *
- */
- public static class HeroBuilder {
+ /**
+ *
+ * The builder class.
+ *
+ */
+ public static class Builder {
- private final Profession profession;
- private final String name;
- private HairType hairType;
- private HairColor hairColor;
- private Armor armor;
- private Weapon weapon;
+ private final Profession profession;
+ private final String name;
+ private HairType hairType;
+ private HairColor hairColor;
+ private Armor armor;
+ private Weapon weapon;
- public HeroBuilder(Profession profession, String name) {
- if (profession == null || name == null) {
- throw new IllegalArgumentException(
- "profession and name can not be null");
- }
- this.profession = profession;
- this.name = name;
- }
+ /**
+ * Constructor
+ */
+ public Builder(Profession profession, String name) {
+ if (profession == null || name == null) {
+ throw new IllegalArgumentException("profession and name can not be null");
+ }
+ this.profession = profession;
+ this.name = name;
+ }
- public HeroBuilder withHairType(HairType hairType) {
- this.hairType = hairType;
- return this;
- }
+ public Builder withHairType(HairType hairType) {
+ this.hairType = hairType;
+ return this;
+ }
- public HeroBuilder withHairColor(HairColor hairColor) {
- this.hairColor = hairColor;
- return this;
- }
+ public Builder withHairColor(HairColor hairColor) {
+ this.hairColor = hairColor;
+ return this;
+ }
- public HeroBuilder withArmor(Armor armor) {
- this.armor = armor;
- return this;
- }
+ public Builder withArmor(Armor armor) {
+ this.armor = armor;
+ return this;
+ }
- public HeroBuilder withWeapon(Weapon weapon) {
- this.weapon = weapon;
- return this;
- }
+ public Builder withWeapon(Weapon weapon) {
+ this.weapon = weapon;
+ return this;
+ }
- public Hero build() {
- return new Hero(this);
- }
- }
+ public Hero build() {
+ return new Hero(this);
+ }
+ }
}
diff --git a/builder/src/main/java/com/iluwatar/builder/Profession.java b/builder/src/main/java/com/iluwatar/builder/Profession.java
index c9a7cc4e9..7be5b999e 100644
--- a/builder/src/main/java/com/iluwatar/builder/Profession.java
+++ b/builder/src/main/java/com/iluwatar/builder/Profession.java
@@ -1,3 +1,25 @@
+/**
+ * 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.builder;
/**
@@ -7,11 +29,10 @@ package com.iluwatar.builder;
*/
public enum Profession {
- WARRIOR, THIEF, MAGE, PRIEST;
-
- @Override
- public String toString() {
- return name().toLowerCase();
- }
+ WARRIOR, THIEF, MAGE, PRIEST;
+ @Override
+ public String toString() {
+ return name().toLowerCase();
+ }
}
diff --git a/builder/src/main/java/com/iluwatar/builder/Weapon.java b/builder/src/main/java/com/iluwatar/builder/Weapon.java
index af71c596d..97d347d24 100644
--- a/builder/src/main/java/com/iluwatar/builder/Weapon.java
+++ b/builder/src/main/java/com/iluwatar/builder/Weapon.java
@@ -1,3 +1,25 @@
+/**
+ * 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.builder;
/**
@@ -7,11 +29,10 @@ package com.iluwatar.builder;
*/
public enum Weapon {
- DAGGER, SWORD, AXE, WARHAMMER, BOW;
-
- @Override
- public String toString() {
- return name().toLowerCase();
- }
+ DAGGER, SWORD, AXE, WARHAMMER, BOW;
+ @Override
+ public String toString() {
+ return name().toLowerCase();
+ }
}
diff --git a/builder/src/test/java/com/iluwatar/builder/AppTest.java b/builder/src/test/java/com/iluwatar/builder/AppTest.java
index acae1ca70..e83db9f9f 100644
--- a/builder/src/test/java/com/iluwatar/builder/AppTest.java
+++ b/builder/src/test/java/com/iluwatar/builder/AppTest.java
@@ -1,9 +1,29 @@
+/**
+ * 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.builder;
import org.junit.Test;
-import com.iluwatar. builder.App;
-
/**
*
* Application test
@@ -11,9 +31,9 @@ import com.iluwatar. builder.App;
*/
public class AppTest {
- @Test
- public void test() {
- String[] args = {};
- App.main(args);
- }
+ @Test
+ public void test() {
+ String[] args = {};
+ App.main(args);
+ }
}
diff --git a/builder/src/test/java/com/iluwatar/builder/HeroTest.java b/builder/src/test/java/com/iluwatar/builder/HeroTest.java
new file mode 100644
index 000000000..b0a73a9d0
--- /dev/null
+++ b/builder/src/test/java/com/iluwatar/builder/HeroTest.java
@@ -0,0 +1,78 @@
+/**
+ * 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.builder;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * Date: 12/6/15 - 11:01 PM
+ *
+ * @author Jeroen Meulemeester
+ */
+public class HeroTest {
+
+ /**
+ * Test if we get the expected exception when trying to create a hero without a profession
+ */
+ @Test(expected = IllegalArgumentException.class)
+ public void testMissingProfession() throws Exception {
+ new Hero.Builder(null, "Sir without a job");
+ }
+
+ /**
+ * Test if we get the expected exception when trying to create a hero without a name
+ */
+ @Test(expected = IllegalArgumentException.class)
+ public void testMissingName() throws Exception {
+ new Hero.Builder(Profession.THIEF, null);
+ }
+
+ /**
+ * Test if the hero build by the builder has the correct attributes, as requested
+ */
+ @Test
+ public void testBuildHero() throws Exception {
+ final String heroName = "Sir Lancelot";
+
+ final Hero hero = new Hero.Builder(Profession.WARRIOR, heroName)
+ .withArmor(Armor.CHAIN_MAIL)
+ .withWeapon(Weapon.SWORD)
+ .withHairType(HairType.LONG_CURLY)
+ .withHairColor(HairColor.BLOND)
+ .build();
+
+ assertNotNull(hero);
+ assertNotNull(hero.toString());
+ assertEquals(Profession.WARRIOR, hero.getProfession());
+ assertEquals(heroName, hero.getName());
+ assertEquals(Armor.CHAIN_MAIL, hero.getArmor());
+ assertEquals(Weapon.SWORD, hero.getWeapon());
+ assertEquals(HairType.LONG_CURLY, hero.getHairType());
+ assertEquals(HairColor.BLOND, hero.getHairColor());
+
+ }
+
+}
\ No newline at end of file
diff --git a/business-delegate/index.md b/business-delegate/README.md
similarity index 67%
rename from business-delegate/index.md
rename to business-delegate/README.md
index a55febaf9..e6e249122 100644
--- a/business-delegate/index.md
+++ b/business-delegate/README.md
@@ -4,18 +4,26 @@ title: Business Delegate
folder: business-delegate
permalink: /patterns/business-delegate/
categories: Business Tier
-tags: Java
+tags:
+ - Java
+ - Difficulty-Intermediate
---
-**Intent:** The Business Delegate pattern adds an abstraction layer between
+## Intent
+The Business Delegate pattern adds an abstraction layer between
presentation and business tiers. By using the pattern we gain loose coupling
between the tiers and encapsulate knowledge about how to locate, connect to,
and interact with the business objects that make up the application.

-**Applicability:** Use the Business Delegate pattern when
+## Applicability
+Use the Business Delegate pattern when
* you want loose coupling between presentation and business tiers
* you want to orchestrate calls to multiple business services
* you want to encapsulate service lookups and service calls
+
+## Credits
+
+* [J2EE Design Patterns](http://www.amazon.com/J2EE-Design-Patterns-William-Crawford/dp/0596004273/ref=sr_1_2)
diff --git a/business-delegate/pom.xml b/business-delegate/pom.xml
index 84ae64a17..c6f7e0c37 100644
--- a/business-delegate/pom.xml
+++ b/business-delegate/pom.xml
@@ -1,4 +1,28 @@
+
@@ -6,7 +30,7 @@
com.iluwatar
java-design-patterns
- 1.7.0
+ 1.13.0-SNAPSHOT
business-delegate
@@ -15,5 +39,10 @@
junit
test
+
+ org.mockito
+ mockito-core
+ test
+
diff --git a/business-delegate/src/main/java/com/iluwatar/business/delegate/App.java b/business-delegate/src/main/java/com/iluwatar/business/delegate/App.java
index eea7608eb..e9a264322 100644
--- a/business-delegate/src/main/java/com/iluwatar/business/delegate/App.java
+++ b/business-delegate/src/main/java/com/iluwatar/business/delegate/App.java
@@ -1,35 +1,62 @@
+/**
+ * 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.business.delegate;
/**
+ * The Business Delegate pattern adds an abstraction layer between the presentation and business
+ * tiers. By using the pattern we gain loose coupling between the tiers. The Business Delegate
+ * encapsulates knowledge about how to locate, connect to, and interact with the business objects
+ * that make up the application.
*
- * The Business Delegate pattern adds an abstraction layer between the presentation and business tiers.
- * By using the pattern we gain loose coupling between the tiers. The Business Delegate encapsulates
- * knowledge about how to locate, connect to, and interact with the business objects that make up
- * the application.
- *
- * Some of the services the Business Delegate uses are instantiated directly, and some can be retrieved
- * through service lookups. The Business Delegate itself may contain business logic too potentially tying
- * together multiple service calls, exception handling, retrying etc.
- *
- * In this example the client ({@link Client}) utilizes a business delegate ({@link BusinessDelegate}) to execute a task.
- * The Business Delegate then selects the appropriate service and makes the service call.
- *
+ *
Some of the services the Business Delegate uses are instantiated directly, and some can be
+ * retrieved through service lookups. The Business Delegate itself may contain business logic too
+ * potentially tying together multiple service calls, exception handling, retrying etc.
+ *
+ *
In this example the client ({@link Client}) utilizes a business delegate (
+ * {@link BusinessDelegate}) to execute a task. The Business Delegate then selects the appropriate
+ * service and makes the service call.
*/
public class App {
-
- /**
- * Program entry point
- * @param args command line args
- */
- public static void main(String[] args) {
-
- BusinessDelegate businessDelegate = new BusinessDelegate();
- businessDelegate.setServiceType(ServiceType.EJB);
- Client client = new Client(businessDelegate);
- client.doTask();
+ /**
+ * Program entry point.
+ *
+ * @param args command line args
+ */
+ public static void main(String[] args) {
- businessDelegate.setServiceType(ServiceType.JMS);
- client.doTask();
- }
+ BusinessDelegate businessDelegate = new BusinessDelegate();
+ BusinessLookup businessLookup = new BusinessLookup();
+ businessLookup.setEjbService(new EjbService());
+ businessLookup.setJmsService(new JmsService());
+
+ businessDelegate.setLookupService(businessLookup);
+ businessDelegate.setServiceType(ServiceType.EJB);
+
+ Client client = new Client(businessDelegate);
+ client.doTask();
+
+ businessDelegate.setServiceType(ServiceType.JMS);
+ client.doTask();
+ }
}
diff --git a/business-delegate/src/main/java/com/iluwatar/business/delegate/BusinessDelegate.java b/business-delegate/src/main/java/com/iluwatar/business/delegate/BusinessDelegate.java
index cf0809b97..81aa9a0f1 100644
--- a/business-delegate/src/main/java/com/iluwatar/business/delegate/BusinessDelegate.java
+++ b/business-delegate/src/main/java/com/iluwatar/business/delegate/BusinessDelegate.java
@@ -1,22 +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.business.delegate;
/**
- *
* BusinessDelegate separates the presentation and business tiers
- *
*/
public class BusinessDelegate {
-
- private BusinessLookup lookupService = new BusinessLookup();
- private BusinessService businessService;
- private ServiceType serviceType;
- public void setServiceType(ServiceType serviceType) {
- this.serviceType = serviceType;
- }
+ private BusinessLookup lookupService;
+ private BusinessService businessService;
+ private ServiceType serviceType;
- public void doTask() {
- businessService = lookupService.getBusinessService(serviceType);
- businessService.doProcessing();
- }
+ public void setLookupService(BusinessLookup businessLookup) {
+ this.lookupService = businessLookup;
+ }
+
+ public void setServiceType(ServiceType serviceType) {
+ this.serviceType = serviceType;
+ }
+
+ public void doTask() {
+ businessService = lookupService.getBusinessService(serviceType);
+ businessService.doProcessing();
+ }
}
diff --git a/business-delegate/src/main/java/com/iluwatar/business/delegate/BusinessLookup.java b/business-delegate/src/main/java/com/iluwatar/business/delegate/BusinessLookup.java
index 6a5f2d504..7e1045e7f 100644
--- a/business-delegate/src/main/java/com/iluwatar/business/delegate/BusinessLookup.java
+++ b/business-delegate/src/main/java/com/iluwatar/business/delegate/BusinessLookup.java
@@ -1,17 +1,53 @@
+/**
+ * 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.business.delegate;
/**
- *
- * Class for performing service lookups
- *
+ * Class for performing service lookups.
*/
public class BusinessLookup {
- public BusinessService getBusinessService(ServiceType serviceType) {
- if (serviceType.equals(ServiceType.EJB)) {
- return new EjbService();
- } else {
- return new JmsService();
- }
- }
+ private EjbService ejbService;
+
+ private JmsService jmsService;
+
+ /**
+ * @param serviceType Type of service instance to be returned.
+ * @return Service instance.
+ */
+ public BusinessService getBusinessService(ServiceType serviceType) {
+ if (serviceType.equals(ServiceType.EJB)) {
+ return ejbService;
+ } else {
+ return jmsService;
+ }
+ }
+
+ public void setJmsService(JmsService jmsService) {
+ this.jmsService = jmsService;
+ }
+
+ public void setEjbService(EjbService ejbService) {
+ this.ejbService = ejbService;
+ }
}
diff --git a/business-delegate/src/main/java/com/iluwatar/business/delegate/BusinessService.java b/business-delegate/src/main/java/com/iluwatar/business/delegate/BusinessService.java
index 7e39745d5..f5784964a 100644
--- a/business-delegate/src/main/java/com/iluwatar/business/delegate/BusinessService.java
+++ b/business-delegate/src/main/java/com/iluwatar/business/delegate/BusinessService.java
@@ -1,3 +1,25 @@
+/**
+ * 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.business.delegate;
/**
@@ -7,5 +29,5 @@ package com.iluwatar.business.delegate;
*/
public interface BusinessService {
- void doProcessing();
+ void doProcessing();
}
diff --git a/business-delegate/src/main/java/com/iluwatar/business/delegate/Client.java b/business-delegate/src/main/java/com/iluwatar/business/delegate/Client.java
index 2dc0cc662..8c6bf59a1 100644
--- a/business-delegate/src/main/java/com/iluwatar/business/delegate/Client.java
+++ b/business-delegate/src/main/java/com/iluwatar/business/delegate/Client.java
@@ -1,3 +1,25 @@
+/**
+ * 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.business.delegate;
/**
@@ -7,13 +29,13 @@ package com.iluwatar.business.delegate;
*/
public class Client {
- private BusinessDelegate businessDelegate;
+ private BusinessDelegate businessDelegate;
- public Client(BusinessDelegate businessDelegate) {
- this.businessDelegate = businessDelegate;
- }
+ public Client(BusinessDelegate businessDelegate) {
+ this.businessDelegate = businessDelegate;
+ }
- public void doTask() {
- businessDelegate.doTask();
- }
+ public void doTask() {
+ businessDelegate.doTask();
+ }
}
diff --git a/business-delegate/src/main/java/com/iluwatar/business/delegate/EjbService.java b/business-delegate/src/main/java/com/iluwatar/business/delegate/EjbService.java
index bd03db45d..7296f63b4 100644
--- a/business-delegate/src/main/java/com/iluwatar/business/delegate/EjbService.java
+++ b/business-delegate/src/main/java/com/iluwatar/business/delegate/EjbService.java
@@ -1,3 +1,25 @@
+/**
+ * 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.business.delegate;
/**
@@ -7,8 +29,8 @@ package com.iluwatar.business.delegate;
*/
public class EjbService implements BusinessService {
- @Override
- public void doProcessing() {
- System.out.println("EjbService is now processing");
- }
+ @Override
+ public void doProcessing() {
+ System.out.println("EjbService is now processing");
+ }
}
diff --git a/business-delegate/src/main/java/com/iluwatar/business/delegate/JmsService.java b/business-delegate/src/main/java/com/iluwatar/business/delegate/JmsService.java
index 37425755a..5b71ce57d 100644
--- a/business-delegate/src/main/java/com/iluwatar/business/delegate/JmsService.java
+++ b/business-delegate/src/main/java/com/iluwatar/business/delegate/JmsService.java
@@ -1,3 +1,25 @@
+/**
+ * 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.business.delegate;
/**
@@ -7,8 +29,8 @@ package com.iluwatar.business.delegate;
*/
public class JmsService implements BusinessService {
- @Override
- public void doProcessing() {
- System.out.println("JmsService is now processing");
- }
+ @Override
+ public void doProcessing() {
+ System.out.println("JmsService is now processing");
+ }
}
diff --git a/business-delegate/src/main/java/com/iluwatar/business/delegate/ServiceType.java b/business-delegate/src/main/java/com/iluwatar/business/delegate/ServiceType.java
index e26d71ae6..06d0a42b9 100644
--- a/business-delegate/src/main/java/com/iluwatar/business/delegate/ServiceType.java
+++ b/business-delegate/src/main/java/com/iluwatar/business/delegate/ServiceType.java
@@ -1,3 +1,25 @@
+/**
+ * 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.business.delegate;
/**
@@ -6,6 +28,6 @@ package com.iluwatar.business.delegate;
*
*/
public enum ServiceType {
-
- EJB, JMS;
+
+ EJB, JMS;
}
diff --git a/business-delegate/src/test/java/com/iluwatar/business/delegate/AppTest.java b/business-delegate/src/test/java/com/iluwatar/business/delegate/AppTest.java
index 7ce63c2b4..1767b7ac5 100644
--- a/business-delegate/src/test/java/com/iluwatar/business/delegate/AppTest.java
+++ b/business-delegate/src/test/java/com/iluwatar/business/delegate/AppTest.java
@@ -1,19 +1,38 @@
+/**
+ * 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.business.delegate;
import org.junit.Test;
-import com.iluwatar.business.delegate.App;
+import java.io.IOException;
/**
- *
- * Application test
- *
+ * Tests that Business Delegate example runs without errors.
*/
public class AppTest {
-
- @Test
- public void test() {
- String[] args = {};
- App.main(args);
- }
+ @Test
+ public void test() throws IOException {
+ String[] args = {};
+ App.main(args);
+ }
}
diff --git a/business-delegate/src/test/java/com/iluwatar/business/delegate/BusinessDelegateTest.java b/business-delegate/src/test/java/com/iluwatar/business/delegate/BusinessDelegateTest.java
new file mode 100644
index 000000000..aec4ea14b
--- /dev/null
+++ b/business-delegate/src/test/java/com/iluwatar/business/delegate/BusinessDelegateTest.java
@@ -0,0 +1,100 @@
+/**
+ * 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.business.delegate;
+
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * The Business Delegate pattern adds an abstraction layer between the presentation and business
+ * tiers. By using the pattern we gain loose coupling between the tiers. The Business Delegate
+ * encapsulates knowledge about how to locate, connect to, and interact with the business objects
+ * that make up the application.
+ *
+ *
Some of the services the Business Delegate uses are instantiated directly, and some can be
+ * retrieved through service lookups. The Business Delegate itself may contain business logic too
+ * potentially tying together multiple service calls, exception handling, retrying etc.
+ */
+public class BusinessDelegateTest {
+
+ private EjbService ejbService;
+
+ private JmsService jmsService;
+
+ private BusinessLookup businessLookup;
+
+ private BusinessDelegate businessDelegate;
+
+ /**
+ * This method sets up the instance variables of this test class. It is executed before the
+ * execution of every test.
+ */
+ @Before
+ public void setup() {
+ ejbService = spy(new EjbService());
+ jmsService = spy(new JmsService());
+
+ businessLookup = spy(new BusinessLookup());
+ businessLookup.setEjbService(ejbService);
+ businessLookup.setJmsService(jmsService);
+
+ businessDelegate = spy(new BusinessDelegate());
+ businessDelegate.setLookupService(businessLookup);
+ }
+
+ /**
+ * In this example the client ({@link Client}) utilizes a business delegate (
+ * {@link BusinessDelegate}) to execute a task. The Business Delegate then selects the appropriate
+ * service and makes the service call.
+ */
+ @Test
+ public void testBusinessDelegate() {
+
+ // setup a client object
+ Client client = new Client(businessDelegate);
+
+ // set the service type
+ businessDelegate.setServiceType(ServiceType.EJB);
+
+ // action
+ client.doTask();
+
+ // verifying that the businessDelegate was used by client during doTask() method.
+ verify(businessDelegate).doTask();
+ verify(ejbService).doProcessing();
+
+ // set the service type
+ businessDelegate.setServiceType(ServiceType.JMS);
+
+ // action
+ client.doTask();
+
+ // verifying that the businessDelegate was used by client during doTask() method.
+ verify(businessDelegate, times(2)).doTask();
+ verify(jmsService).doProcessing();
+ }
+}
diff --git a/caching/index.md b/caching/README.md
similarity index 81%
rename from caching/index.md
rename to caching/README.md
index f79f13e42..2b89d0559 100644
--- a/caching/index.md
+++ b/caching/README.md
@@ -6,19 +6,23 @@ permalink: /patterns/caching/
categories: Other
tags:
- Java
+ - Difficulty-Intermediate
+ - Performance
---
-**Intent:** To avoid expensive re-acquisition of resources by not releasing
+## Intent
+To avoid expensive re-acquisition of resources by not releasing
the resources immediately after their use. The resources retain their identity, are kept in some
fast-access storage, and are re-used to avoid having to acquire them again.

-**Applicability:** Use the Caching pattern(s) when
+## Applicability
+Use the Caching pattern(s) when
* Repetitious acquisition, initialization, and release of the same resource causes unnecessary performance overhead.
-**Credits**
+## Credits
* [Write-through, write-around, write-back: Cache explained](http://www.computerweekly.com/feature/Write-through-write-around-write-back-Cache-explained)
* [Read-Through, Write-Through, Write-Behind, and Refresh-Ahead Caching](https://docs.oracle.com/cd/E15357_01/coh.360/e15723/cache_rtwtwbra.htm#COHDG5177)
diff --git a/caching/pom.xml b/caching/pom.xml
index d2284a5f1..c20842a89 100644
--- a/caching/pom.xml
+++ b/caching/pom.xml
@@ -1,11 +1,35 @@
+
4.0.0
com.iluwatar
java-design-patterns
- 1.7.0
+ 1.13.0-SNAPSHOT
caching
diff --git a/caching/src/main/java/com/iluwatar/caching/App.java b/caching/src/main/java/com/iluwatar/caching/App.java
index c7f55db70..8e5a84085 100644
--- a/caching/src/main/java/com/iluwatar/caching/App.java
+++ b/caching/src/main/java/com/iluwatar/caching/App.java
@@ -1,3 +1,25 @@
+/**
+ * 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.caching;
/**
@@ -21,7 +43,7 @@ package com.iluwatar.caching;
* application data. The cache itself is implemented as an internal (Java) data structure. It adopts
* a Least-Recently-Used (LRU) strategy for evicting data from itself when its full. The three
* strategies are individually tested. The testing of the cache is restricted towards saving and
- * querying of user accounts from the underlying data store ( {@link DBManager}). The main class (
+ * querying of user accounts from the underlying data store ( {@link DbManager}). The main class (
* {@link App} is not aware of the underlying mechanics of the application (i.e. save and query) and
* whether the data is coming from the cache or the DB (i.e. separation of concern). The AppManager
* ({@link AppManager}) handles the transaction of data to-and-from the underlying data store
@@ -43,7 +65,7 @@ public class App {
* @param args command line args
*/
public static void main(String[] args) {
- AppManager.initDB(false); // VirtualDB (instead of MongoDB) was used in running the JUnit tests
+ AppManager.initDb(false); // VirtualDB (instead of MongoDB) was used in running the JUnit tests
// and the App class to avoid Maven compilation errors. Set flag to
// true to run the tests with MongoDB (provided that MongoDB is
// installed and socket connection is open).
@@ -65,8 +87,8 @@ public class App {
AppManager.save(userAccount1);
System.out.println(AppManager.printCacheContent());
- userAccount1 = AppManager.find("001");
- userAccount1 = AppManager.find("001");
+ AppManager.find("001");
+ AppManager.find("001");
}
/**
@@ -80,15 +102,15 @@ public class App {
AppManager.save(userAccount2);
System.out.println(AppManager.printCacheContent());
- userAccount2 = AppManager.find("002");
+ AppManager.find("002");
System.out.println(AppManager.printCacheContent());
userAccount2 = AppManager.find("002");
userAccount2.setUserName("Jane G.");
AppManager.save(userAccount2);
System.out.println(AppManager.printCacheContent());
- userAccount2 = AppManager.find("002");
+ AppManager.find("002");
System.out.println(AppManager.printCacheContent());
- userAccount2 = AppManager.find("002");
+ AppManager.find("002");
}
/**
@@ -106,12 +128,12 @@ public class App {
AppManager.save(userAccount4);
AppManager.save(userAccount5);
System.out.println(AppManager.printCacheContent());
- userAccount3 = AppManager.find("003");
+ AppManager.find("003");
System.out.println(AppManager.printCacheContent());
UserAccount userAccount6 = new UserAccount("006", "Yasha", "She is an only child.");
AppManager.save(userAccount6);
System.out.println(AppManager.printCacheContent());
- userAccount4 = AppManager.find("004");
+ AppManager.find("004");
System.out.println(AppManager.printCacheContent());
}
}
diff --git a/caching/src/main/java/com/iluwatar/caching/AppManager.java b/caching/src/main/java/com/iluwatar/caching/AppManager.java
index 08132e327..2967c759f 100644
--- a/caching/src/main/java/com/iluwatar/caching/AppManager.java
+++ b/caching/src/main/java/com/iluwatar/caching/AppManager.java
@@ -1,3 +1,25 @@
+/**
+ * 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.caching;
import java.text.ParseException;
@@ -11,28 +33,34 @@ import java.text.ParseException;
* CacheStore class.
*
*/
-public class AppManager {
+public final class AppManager {
private static CachingPolicy cachingPolicy;
+ private AppManager() {
+ }
+
/**
*
* Developer/Tester is able to choose whether the application should use MongoDB as its underlying
* data storage or a simple Java data structure to (temporarily) store the data/objects during
* runtime.
*/
- public static void initDB(boolean useMongoDB) {
- if (useMongoDB) {
+ public static void initDb(boolean useMongoDb) {
+ if (useMongoDb) {
try {
- DBManager.connect();
+ DbManager.connect();
} catch (ParseException e) {
e.printStackTrace();
}
} else {
- DBManager.createVirtualDB();
+ DbManager.createVirtualDb();
}
}
+ /**
+ * Initialize caching policy
+ */
public static void initCachingPolicy(CachingPolicy policy) {
cachingPolicy = policy;
if (cachingPolicy == CachingPolicy.BEHIND) {
@@ -50,15 +78,21 @@ public class AppManager {
CacheStore.initCapacity(capacity);
}
- public static UserAccount find(String userID) {
+ /**
+ * Find user account
+ */
+ public static UserAccount find(String userId) {
if (cachingPolicy == CachingPolicy.THROUGH || cachingPolicy == CachingPolicy.AROUND) {
- return CacheStore.readThrough(userID);
+ return CacheStore.readThrough(userId);
} else if (cachingPolicy == CachingPolicy.BEHIND) {
- return CacheStore.readThroughWithWriteBackPolicy(userID);
+ return CacheStore.readThroughWithWriteBackPolicy(userId);
}
return null;
}
+ /**
+ * Save user account
+ */
public static void save(UserAccount userAccount) {
if (cachingPolicy == CachingPolicy.THROUGH) {
CacheStore.writeThrough(userAccount);
diff --git a/caching/src/main/java/com/iluwatar/caching/CacheStore.java b/caching/src/main/java/com/iluwatar/caching/CacheStore.java
index 2041ac14f..5903f8219 100644
--- a/caching/src/main/java/com/iluwatar/caching/CacheStore.java
+++ b/caching/src/main/java/com/iluwatar/caching/CacheStore.java
@@ -1,6 +1,28 @@
+/**
+ * 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.caching;
-import java.util.ArrayList;
+import java.util.List;
/**
*
@@ -9,73 +31,99 @@ import java.util.ArrayList;
*/
public class CacheStore {
- static LRUCache cache = null;
+ static LruCache cache;
- public static void initCapacity(int capacity) {
- if (null == cache)
- cache = new LRUCache(capacity);
- else
- cache.setCapacity(capacity);
+ private CacheStore() {
}
- public static UserAccount readThrough(String userID) {
- if (cache.contains(userID)) {
+ /**
+ * Init cache capacity
+ */
+ public static void initCapacity(int capacity) {
+ if (null == cache) {
+ cache = new LruCache(capacity);
+ } else {
+ cache.setCapacity(capacity);
+ }
+ }
+
+ /**
+ * Get user account using read-through cache
+ */
+ public static UserAccount readThrough(String userId) {
+ if (cache.contains(userId)) {
System.out.println("# Cache Hit!");
- return cache.get(userID);
+ return cache.get(userId);
}
System.out.println("# Cache Miss!");
- UserAccount userAccount = DBManager.readFromDB(userID);
- cache.set(userID, userAccount);
+ UserAccount userAccount = DbManager.readFromDb(userId);
+ cache.set(userId, userAccount);
return userAccount;
}
+ /**
+ * Get user account using write-through cache
+ */
public static void writeThrough(UserAccount userAccount) {
- if (cache.contains(userAccount.getUserID())) {
- DBManager.updateDB(userAccount);
+ if (cache.contains(userAccount.getUserId())) {
+ DbManager.updateDb(userAccount);
} else {
- DBManager.writeToDB(userAccount);
+ DbManager.writeToDb(userAccount);
}
- cache.set(userAccount.getUserID(), userAccount);
+ cache.set(userAccount.getUserId(), userAccount);
}
+ /**
+ * Get user account using write-around cache
+ */
public static void writeAround(UserAccount userAccount) {
- if (cache.contains(userAccount.getUserID())) {
- DBManager.updateDB(userAccount);
- cache.invalidate(userAccount.getUserID()); // Cache data has been updated -- remove older
+ if (cache.contains(userAccount.getUserId())) {
+ DbManager.updateDb(userAccount);
+ cache.invalidate(userAccount.getUserId()); // Cache data has been updated -- remove older
// version from cache.
} else {
- DBManager.writeToDB(userAccount);
+ DbManager.writeToDb(userAccount);
}
}
- public static UserAccount readThroughWithWriteBackPolicy(String userID) {
- if (cache.contains(userID)) {
+ /**
+ * Get user account using read-through cache with write-back policy
+ */
+ public static UserAccount readThroughWithWriteBackPolicy(String userId) {
+ if (cache.contains(userId)) {
System.out.println("# Cache Hit!");
- return cache.get(userID);
+ return cache.get(userId);
}
System.out.println("# Cache Miss!");
- UserAccount userAccount = DBManager.readFromDB(userID);
+ UserAccount userAccount = DbManager.readFromDb(userId);
if (cache.isFull()) {
System.out.println("# Cache is FULL! Writing LRU data to DB...");
- UserAccount toBeWrittenToDB = cache.getLRUData();
- DBManager.upsertDB(toBeWrittenToDB);
+ UserAccount toBeWrittenToDb = cache.getLruData();
+ DbManager.upsertDb(toBeWrittenToDb);
}
- cache.set(userID, userAccount);
+ cache.set(userId, userAccount);
return userAccount;
}
+ /**
+ * Set user account
+ */
public static void writeBehind(UserAccount userAccount) {
- if (cache.isFull() && !cache.contains(userAccount.getUserID())) {
+ if (cache.isFull() && !cache.contains(userAccount.getUserId())) {
System.out.println("# Cache is FULL! Writing LRU data to DB...");
- UserAccount toBeWrittenToDB = cache.getLRUData();
- DBManager.upsertDB(toBeWrittenToDB);
+ UserAccount toBeWrittenToDb = cache.getLruData();
+ DbManager.upsertDb(toBeWrittenToDb);
}
- cache.set(userAccount.getUserID(), userAccount);
+ cache.set(userAccount.getUserId(), userAccount);
}
+ /**
+ * Clears cache
+ */
public static void clearCache() {
- if (null != cache)
+ if (null != cache) {
cache.clear();
+ }
}
/**
@@ -83,16 +131,20 @@ public class CacheStore {
*/
public static void flushCache() {
System.out.println("# flushCache...");
- if (null == cache)
+ if (null == cache) {
return;
- ArrayList listOfUserAccounts = cache.getCacheDataInListForm();
+ }
+ List listOfUserAccounts = cache.getCacheDataInListForm();
for (UserAccount userAccount : listOfUserAccounts) {
- DBManager.upsertDB(userAccount);
+ DbManager.upsertDb(userAccount);
}
}
+ /**
+ * Print user accounts
+ */
public static String print() {
- ArrayList listOfUserAccounts = cache.getCacheDataInListForm();
+ List listOfUserAccounts = cache.getCacheDataInListForm();
StringBuilder sb = new StringBuilder();
sb.append("\n--CACHE CONTENT--\n");
for (UserAccount userAccount : listOfUserAccounts) {
diff --git a/caching/src/main/java/com/iluwatar/caching/CachingPolicy.java b/caching/src/main/java/com/iluwatar/caching/CachingPolicy.java
index 314cfaa36..490113baa 100644
--- a/caching/src/main/java/com/iluwatar/caching/CachingPolicy.java
+++ b/caching/src/main/java/com/iluwatar/caching/CachingPolicy.java
@@ -1,3 +1,25 @@
+/**
+ * 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.caching;
/**
diff --git a/caching/src/main/java/com/iluwatar/caching/DBManager.java b/caching/src/main/java/com/iluwatar/caching/DbManager.java
similarity index 52%
rename from caching/src/main/java/com/iluwatar/caching/DBManager.java
rename to caching/src/main/java/com/iluwatar/caching/DbManager.java
index 07a5daeac..c12461d0c 100644
--- a/caching/src/main/java/com/iluwatar/caching/DBManager.java
+++ b/caching/src/main/java/com/iluwatar/caching/DbManager.java
@@ -1,7 +1,30 @@
+/**
+ * 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.caching;
import java.text.ParseException;
import java.util.HashMap;
+import java.util.Map;
import org.bson.Document;
@@ -21,29 +44,42 @@ import com.mongodb.client.model.UpdateOptions;
* during runtime (createVirtualDB()).
*
*/
-public class DBManager {
+public final class DbManager {
private static MongoClient mongoClient;
private static MongoDatabase db;
private static boolean useMongoDB;
- private static HashMap virtualDB;
+ private static Map virtualDB;
- public static void createVirtualDB() {
- useMongoDB = false;
- virtualDB = new HashMap();
+ private DbManager() {
}
+ /**
+ * Create DB
+ */
+ public static void createVirtualDb() {
+ useMongoDB = false;
+ virtualDB = new HashMap<>();
+ }
+
+ /**
+ * Connect to DB
+ */
public static void connect() throws ParseException {
useMongoDB = true;
mongoClient = new MongoClient();
db = mongoClient.getDatabase("test");
}
- public static UserAccount readFromDB(String userID) {
+ /**
+ * Read user account from DB
+ */
+ public static UserAccount readFromDb(String userId) {
if (!useMongoDB) {
- if (virtualDB.containsKey(userID))
- return virtualDB.get(userID);
+ if (virtualDB.containsKey(userId)) {
+ return virtualDB.get(userId);
+ }
return null;
}
if (null == db) {
@@ -54,18 +90,20 @@ public class DBManager {
}
}
FindIterable iterable =
- db.getCollection("user_accounts").find(new Document("userID", userID));
- if (iterable == null)
+ db.getCollection("user_accounts").find(new Document("userID", userId));
+ if (iterable == null) {
return null;
+ }
Document doc = iterable.first();
- UserAccount userAccount =
- new UserAccount(userID, doc.getString("userName"), doc.getString("additionalInfo"));
- return userAccount;
+ return new UserAccount(userId, doc.getString("userName"), doc.getString("additionalInfo"));
}
- public static void writeToDB(UserAccount userAccount) {
+ /**
+ * Write user account to DB
+ */
+ public static void writeToDb(UserAccount userAccount) {
if (!useMongoDB) {
- virtualDB.put(userAccount.getUserID(), userAccount);
+ virtualDB.put(userAccount.getUserId(), userAccount);
return;
}
if (null == db) {
@@ -76,13 +114,16 @@ public class DBManager {
}
}
db.getCollection("user_accounts").insertOne(
- new Document("userID", userAccount.getUserID()).append("userName",
+ new Document("userID", userAccount.getUserId()).append("userName",
userAccount.getUserName()).append("additionalInfo", userAccount.getAdditionalInfo()));
}
- public static void updateDB(UserAccount userAccount) {
+ /**
+ * Update DB
+ */
+ public static void updateDb(UserAccount userAccount) {
if (!useMongoDB) {
- virtualDB.put(userAccount.getUserID(), userAccount);
+ virtualDB.put(userAccount.getUserId(), userAccount);
return;
}
if (null == db) {
@@ -93,7 +134,7 @@ public class DBManager {
}
}
db.getCollection("user_accounts").updateOne(
- new Document("userID", userAccount.getUserID()),
+ new Document("userID", userAccount.getUserId()),
new Document("$set", new Document("userName", userAccount.getUserName()).append(
"additionalInfo", userAccount.getAdditionalInfo())));
}
@@ -102,9 +143,9 @@ public class DBManager {
*
* Insert data into DB if it does not exist. Else, update it.
*/
- public static void upsertDB(UserAccount userAccount) {
+ public static void upsertDb(UserAccount userAccount) {
if (!useMongoDB) {
- virtualDB.put(userAccount.getUserID(), userAccount);
+ virtualDB.put(userAccount.getUserId(), userAccount);
return;
}
if (null == db) {
@@ -115,8 +156,8 @@ public class DBManager {
}
}
db.getCollection("user_accounts").updateOne(
- new Document("userID", userAccount.getUserID()),
- new Document("$set", new Document("userID", userAccount.getUserID()).append("userName",
+ new Document("userID", userAccount.getUserId()),
+ new Document("$set", new Document("userID", userAccount.getUserId()).append("userName",
userAccount.getUserName()).append("additionalInfo", userAccount.getAdditionalInfo())),
new UpdateOptions().upsert(true));
}
diff --git a/caching/src/main/java/com/iluwatar/caching/LRUCache.java b/caching/src/main/java/com/iluwatar/caching/LRUCache.java
deleted file mode 100644
index 872f97256..000000000
--- a/caching/src/main/java/com/iluwatar/caching/LRUCache.java
+++ /dev/null
@@ -1,146 +0,0 @@
-package com.iluwatar.caching;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-
-/**
- *
- * Data structure/implementation of the application's cache. The data structure consists of a hash
- * table attached with a doubly linked-list. The linked-list helps in capturing and maintaining the
- * LRU data in the cache. When a data is queried (from the cache), added (to the cache), or updated,
- * the data is moved to the front of the list to depict itself as the most-recently-used data. The
- * LRU data is always at the end of the list.
- *
- */
-public class LRUCache {
-
- class Node {
- String userID;
- UserAccount userAccount;
- Node previous;
- Node next;
-
- public Node(String userID, UserAccount userAccount) {
- this.userID = userID;
- this.userAccount = userAccount;
- }
- }
-
- int capacity;
- HashMap cache = new HashMap();
- Node head = null;
- Node end = null;
-
- public LRUCache(int capacity) {
- this.capacity = capacity;
- }
-
- public UserAccount get(String userID) {
- if (cache.containsKey(userID)) {
- Node node = cache.get(userID);
- remove(node);
- setHead(node);
- return node.userAccount;
- }
- return null;
- }
-
- /**
- *
- * Remove node from linked list.
- */
- public void remove(Node node) {
- if (node.previous != null) {
- node.previous.next = node.next;
- } else {
- head = node.next;
- }
- if (node.next != null) {
- node.next.previous = node.previous;
- } else {
- end = node.previous;
- }
- }
-
- /**
- *
- * Move node to the front of the list.
- */
- public void setHead(Node node) {
- node.next = head;
- node.previous = null;
- if (head != null)
- head.previous = node;
- head = node;
- if (end == null)
- end = head;
- }
-
- public void set(String userID, UserAccount userAccount) {
- if (cache.containsKey(userID)) {
- Node old = cache.get(userID);
- old.userAccount = userAccount;
- remove(old);
- setHead(old);
- } else {
- Node newNode = new Node(userID, userAccount);
- if (cache.size() >= capacity) {
- System.out.println("# Cache is FULL! Removing " + end.userID + " from cache...");
- cache.remove(end.userID); // remove LRU data from cache.
- remove(end);
- setHead(newNode);
- } else {
- setHead(newNode);
- }
- cache.put(userID, newNode);
- }
- }
-
- public boolean contains(String userID) {
- return cache.containsKey(userID);
- }
-
- public void invalidate(String userID) {
- System.out.println("# " + userID + " has been updated! Removing older version from cache...");
- Node toBeRemoved = cache.get(userID);
- remove(toBeRemoved);
- cache.remove(userID);
- }
-
- public boolean isFull() {
- return cache.size() >= capacity;
- }
-
- public UserAccount getLRUData() {
- return end.userAccount;
- }
-
- public void clear() {
- head = null;
- end = null;
- cache.clear();
- }
-
- /**
- *
- * Returns cache data in list form.
- */
- public ArrayList getCacheDataInListForm() {
- ArrayList listOfCacheData = new ArrayList();
- Node temp = head;
- while (temp != null) {
- listOfCacheData.add(temp.userAccount);
- temp = temp.next;
- }
- return listOfCacheData;
- }
-
- public void setCapacity(int newCapacity) {
- if (capacity > newCapacity) {
- clear(); // Behavior can be modified to accommodate for decrease in cache size. For now, we'll
- // just clear the cache.
- } else {
- this.capacity = newCapacity;
- }
- }
-}
diff --git a/caching/src/main/java/com/iluwatar/caching/LruCache.java b/caching/src/main/java/com/iluwatar/caching/LruCache.java
new file mode 100644
index 000000000..5c5549afd
--- /dev/null
+++ b/caching/src/main/java/com/iluwatar/caching/LruCache.java
@@ -0,0 +1,187 @@
+/**
+ * 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.caching;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ *
+ * Data structure/implementation of the application's cache. The data structure consists of a hash
+ * table attached with a doubly linked-list. The linked-list helps in capturing and maintaining the
+ * LRU data in the cache. When a data is queried (from the cache), added (to the cache), or updated,
+ * the data is moved to the front of the list to depict itself as the most-recently-used data. The
+ * LRU data is always at the end of the list.
+ *
+ */
+public class LruCache {
+
+ class Node {
+ String userId;
+ UserAccount userAccount;
+ Node previous;
+ Node next;
+
+ public Node(String userId, UserAccount userAccount) {
+ this.userId = userId;
+ this.userAccount = userAccount;
+ }
+ }
+
+ int capacity;
+ Map cache = new HashMap<>();
+ Node head;
+ Node end;
+
+ public LruCache(int capacity) {
+ this.capacity = capacity;
+ }
+
+ /**
+ * Get user account
+ */
+ public UserAccount get(String userId) {
+ if (cache.containsKey(userId)) {
+ Node node = cache.get(userId);
+ remove(node);
+ setHead(node);
+ return node.userAccount;
+ }
+ return null;
+ }
+
+ /**
+ *
+ * Remove node from linked list.
+ */
+ public void remove(Node node) {
+ if (node.previous != null) {
+ node.previous.next = node.next;
+ } else {
+ head = node.next;
+ }
+ if (node.next != null) {
+ node.next.previous = node.previous;
+ } else {
+ end = node.previous;
+ }
+ }
+
+ /**
+ *
+ * Move node to the front of the list.
+ */
+ public void setHead(Node node) {
+ node.next = head;
+ node.previous = null;
+ if (head != null) {
+ head.previous = node;
+ }
+ head = node;
+ if (end == null) {
+ end = head;
+ }
+ }
+
+ /**
+ * Set user account
+ */
+ public void set(String userId, UserAccount userAccount) {
+ if (cache.containsKey(userId)) {
+ Node old = cache.get(userId);
+ old.userAccount = userAccount;
+ remove(old);
+ setHead(old);
+ } else {
+ Node newNode = new Node(userId, userAccount);
+ if (cache.size() >= capacity) {
+ System.out.println("# Cache is FULL! Removing " + end.userId + " from cache...");
+ cache.remove(end.userId); // remove LRU data from cache.
+ remove(end);
+ setHead(newNode);
+ } else {
+ setHead(newNode);
+ }
+ cache.put(userId, newNode);
+ }
+ }
+
+ public boolean contains(String userId) {
+ return cache.containsKey(userId);
+ }
+
+ /**
+ * Invalidate cache for user
+ */
+ public void invalidate(String userId) {
+ System.out.println("# " + userId + " has been updated! Removing older version from cache...");
+ Node toBeRemoved = cache.get(userId);
+ remove(toBeRemoved);
+ cache.remove(userId);
+ }
+
+ public boolean isFull() {
+ return cache.size() >= capacity;
+ }
+
+ public UserAccount getLruData() {
+ return end.userAccount;
+ }
+
+ /**
+ * Clear cache
+ */
+ public void clear() {
+ head = null;
+ end = null;
+ cache.clear();
+ }
+
+ /**
+ *
+ * Returns cache data in list form.
+ */
+ public List getCacheDataInListForm() {
+ ArrayList listOfCacheData = new ArrayList<>();
+ Node temp = head;
+ while (temp != null) {
+ listOfCacheData.add(temp.userAccount);
+ temp = temp.next;
+ }
+ return listOfCacheData;
+ }
+
+ /**
+ * Set cache capacity
+ */
+ public void setCapacity(int newCapacity) {
+ if (capacity > newCapacity) {
+ clear(); // Behavior can be modified to accommodate for decrease in cache size. For now, we'll
+ // just clear the cache.
+ } else {
+ this.capacity = newCapacity;
+ }
+ }
+}
diff --git a/caching/src/main/java/com/iluwatar/caching/UserAccount.java b/caching/src/main/java/com/iluwatar/caching/UserAccount.java
index eff0878ad..e2444ad72 100644
--- a/caching/src/main/java/com/iluwatar/caching/UserAccount.java
+++ b/caching/src/main/java/com/iluwatar/caching/UserAccount.java
@@ -1,3 +1,25 @@
+/**
+ * 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.caching;
/**
@@ -6,22 +28,25 @@ package com.iluwatar.caching;
*
*/
public class UserAccount {
- private String userID;
+ private String userId;
private String userName;
private String additionalInfo;
- public UserAccount(String userID, String userName, String additionalInfo) {
- this.userID = userID;
+ /**
+ * Constructor
+ */
+ public UserAccount(String userId, String userName, String additionalInfo) {
+ this.userId = userId;
this.userName = userName;
this.additionalInfo = additionalInfo;
}
- public String getUserID() {
- return userID;
+ public String getUserId() {
+ return userId;
}
- public void setUserID(String userID) {
- this.userID = userID;
+ public void setUserId(String userId) {
+ this.userId = userId;
}
public String getUserName() {
@@ -42,6 +67,6 @@ public class UserAccount {
@Override
public String toString() {
- return userID + ", " + userName + ", " + additionalInfo;
+ return userId + ", " + userName + ", " + additionalInfo;
}
}
diff --git a/caching/src/test/java/com/iluwatar/caching/AppTest.java b/caching/src/test/java/com/iluwatar/caching/AppTest.java
index ce5cddf08..90ed1c275 100644
--- a/caching/src/test/java/com/iluwatar/caching/AppTest.java
+++ b/caching/src/test/java/com/iluwatar/caching/AppTest.java
@@ -1,41 +1,38 @@
+/**
+ * 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.caching;
-import org.junit.Before;
import org.junit.Test;
+import java.io.IOException;
+
/**
- *
- * Application test
- *
+ * Tests that Caching example runs without errors.
*/
public class AppTest {
- App app;
-
- /**
- * Setup of application test includes: initializing DB connection and cache size/capacity.
- */
- @Before
- public void setUp() {
- AppManager.initDB(false); // VirtualDB (instead of MongoDB) was used in running the JUnit tests
- // to avoid Maven compilation errors. Set flag to true to run the
- // tests with MongoDB (provided that MongoDB is installed and socket
- // connection is open).
- AppManager.initCacheCapacity(3);
- app = new App();
- }
-
@Test
- public void testReadAndWriteThroughStrategy() {
- app.useReadAndWriteThroughStrategy();
- }
-
- @Test
- public void testReadThroughAndWriteAroundStrategy() {
- app.useReadThroughAndWriteAroundStrategy();
- }
-
- @Test
- public void testReadThroughAndWriteBehindStrategy() {
- app.useReadThroughAndWriteBehindStrategy();
+ public void test() throws IOException {
+ String[] args = {};
+ App.main(args);
}
}
diff --git a/caching/src/test/java/com/iluwatar/caching/CachingTest.java b/caching/src/test/java/com/iluwatar/caching/CachingTest.java
new file mode 100644
index 000000000..19262a3b6
--- /dev/null
+++ b/caching/src/test/java/com/iluwatar/caching/CachingTest.java
@@ -0,0 +1,63 @@
+/**
+ * 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.caching;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ *
+ * Application test
+ *
+ */
+public class CachingTest {
+ App app;
+
+ /**
+ * Setup of application test includes: initializing DB connection and cache size/capacity.
+ */
+ @Before
+ public void setUp() {
+ AppManager.initDb(false); // VirtualDB (instead of MongoDB) was used in running the JUnit tests
+ // to avoid Maven compilation errors. Set flag to true to run the
+ // tests with MongoDB (provided that MongoDB is installed and socket
+ // connection is open).
+ AppManager.initCacheCapacity(3);
+ app = new App();
+ }
+
+ @Test
+ public void testReadAndWriteThroughStrategy() {
+ app.useReadAndWriteThroughStrategy();
+ }
+
+ @Test
+ public void testReadThroughAndWriteAroundStrategy() {
+ app.useReadThroughAndWriteAroundStrategy();
+ }
+
+ @Test
+ public void testReadThroughAndWriteBehindStrategy() {
+ app.useReadThroughAndWriteBehindStrategy();
+ }
+}
diff --git a/callback/README.md b/callback/README.md
new file mode 100644
index 000000000..a408fd5e0
--- /dev/null
+++ b/callback/README.md
@@ -0,0 +1,28 @@
+---
+layout: pattern
+title: Callback
+folder: callback
+permalink: /patterns/callback/
+categories: Other
+tags:
+ - Java
+ - Difficulty-Beginner
+ - Functional
+ - Idiom
+---
+
+## Intent
+Callback is a piece of executable code that is passed as an
+argument to other code, which is expected to call back (execute) the argument
+at some convenient time.
+
+
+
+## Applicability
+Use the Callback pattern when
+
+* when some arbitrary synchronous or asynchronous action must be performed after execution of some defined activity.
+
+## Real world examples
+
+* [CyclicBarrier](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CyclicBarrier.html#CyclicBarrier%28int,%20java.lang.Runnable%29) constructor can accept callback that will be triggered every time when barrier is tripped.
diff --git a/callback/index.md b/callback/index.md
deleted file mode 100644
index b724f1edc..000000000
--- a/callback/index.md
+++ /dev/null
@@ -1,22 +0,0 @@
----
-layout: pattern
-title: Callback
-folder: callback
-permalink: /patterns/callback/
-categories: Other
-tags: Java
----
-
-**Intent:** Callback is a piece of executable code that is passed as an
-argument to other code, which is expected to call back (execute) the argument
-at some convenient time.
-
-
-
-**Applicability:** Use the Callback pattern when
-
-* when some arbitrary synchronous or asynchronous action must be performed after execution of some defined activity.
-
-**Real world examples:**
-
-* [CyclicBarrier] (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CyclicBarrier.html#CyclicBarrier%28int,%20java.lang.Runnable%29) constructor can accept callback that will be triggered every time when barrier is tripped.
diff --git a/callback/pom.xml b/callback/pom.xml
index 7e66f6e2b..4fe17d143 100644
--- a/callback/pom.xml
+++ b/callback/pom.xml
@@ -1,11 +1,35 @@
+
4.0.0
com.iluwatar
java-design-patterns
- 1.7.0
+ 1.13.0-SNAPSHOT
callback
diff --git a/callback/src/main/java/com/iluwatar/callback/App.java b/callback/src/main/java/com/iluwatar/callback/App.java
index 513a32415..bc1b2890e 100644
--- a/callback/src/main/java/com/iluwatar/callback/App.java
+++ b/callback/src/main/java/com/iluwatar/callback/App.java
@@ -1,21 +1,47 @@
+/**
+ * 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.callback;
/**
*
- * Callback pattern is more native for functional languages where functions are treated as first-class citizens.
- * Prior to Java 8 callbacks can be simulated using simple (alike command) interfaces.
+ * Callback pattern is more native for functional languages where functions are treated as
+ * first-class citizens. Prior to Java 8 callbacks can be simulated using simple (alike command)
+ * interfaces.
*
*/
public class App {
- public static void main(String[] args) {
- Task task = new SimpleTask();
- Callback callback = new Callback() {
- @Override
- public void call() {
- System.out.println("I'm done now.");
- }
- };
- task.executeWith(callback);
- }
+ /**
+ * Program entry point
+ */
+ public static void main(String[] args) {
+ Task task = new SimpleTask();
+ Callback callback = new Callback() {
+ @Override
+ public void call() {
+ System.out.println("I'm done now.");
+ }
+ };
+ task.executeWith(callback);
+ }
}
diff --git a/callback/src/main/java/com/iluwatar/callback/Callback.java b/callback/src/main/java/com/iluwatar/callback/Callback.java
index 81a421c0d..78932a24e 100644
--- a/callback/src/main/java/com/iluwatar/callback/Callback.java
+++ b/callback/src/main/java/com/iluwatar/callback/Callback.java
@@ -1,3 +1,25 @@
+/**
+ * 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.callback;
/**
@@ -7,5 +29,5 @@ package com.iluwatar.callback;
*/
public interface Callback {
- public void call();
+ void call();
}
diff --git a/callback/src/main/java/com/iluwatar/callback/LambdasApp.java b/callback/src/main/java/com/iluwatar/callback/LambdasApp.java
new file mode 100644
index 000000000..78ca63e0b
--- /dev/null
+++ b/callback/src/main/java/com/iluwatar/callback/LambdasApp.java
@@ -0,0 +1,41 @@
+/**
+ * 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.callback;
+
+/**
+ *
+ * This example generates the exact same output as {@link App} however the callback has been
+ * defined as a Lambdas expression.
+ *
+ */
+public class LambdasApp {
+
+ /**
+ * Program entry point
+ */
+ public static void main(String[] args) {
+ Task task = new SimpleTask();
+ Callback c = () -> System.out.println("I'm done now.");
+ task.executeWith(c);
+ }
+}
diff --git a/callback/src/main/java/com/iluwatar/callback/SimpleTask.java b/callback/src/main/java/com/iluwatar/callback/SimpleTask.java
index 70b844ce3..2a7385607 100644
--- a/callback/src/main/java/com/iluwatar/callback/SimpleTask.java
+++ b/callback/src/main/java/com/iluwatar/callback/SimpleTask.java
@@ -1,3 +1,25 @@
+/**
+ * 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.callback;
/**
@@ -7,9 +29,8 @@ package com.iluwatar.callback;
*/
public class SimpleTask extends Task {
- @Override
- public void execute() {
- System.out.println("Perform some important activity and after call the callback method.");
- }
-
+ @Override
+ public void execute() {
+ System.out.println("Perform some important activity and after call the callback method.");
+ }
}
diff --git a/callback/src/main/java/com/iluwatar/callback/Task.java b/callback/src/main/java/com/iluwatar/callback/Task.java
index db4b66dc5..9580c91cb 100644
--- a/callback/src/main/java/com/iluwatar/callback/Task.java
+++ b/callback/src/main/java/com/iluwatar/callback/Task.java
@@ -1,3 +1,25 @@
+/**
+ * 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.callback;
/**
@@ -7,12 +29,15 @@ package com.iluwatar.callback;
*/
public abstract class Task {
- public final void executeWith(Callback callback) {
- execute();
- if (callback != null) {
- callback.call();
- }
- }
+ /**
+ * Execute with callback
+ */
+ public final void executeWith(Callback callback) {
+ execute();
+ if (callback != null) {
+ callback.call();
+ }
+ }
- public abstract void execute();
+ public abstract void execute();
}
diff --git a/callback/src/test/java/com/iluwatar/callback/AppTest.java b/callback/src/test/java/com/iluwatar/callback/AppTest.java
index 0f7a6f45e..b7ab3fe75 100644
--- a/callback/src/test/java/com/iluwatar/callback/AppTest.java
+++ b/callback/src/test/java/com/iluwatar/callback/AppTest.java
@@ -1,39 +1,38 @@
+/**
+ * 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.callback;
import org.junit.Test;
-import static org.junit.Assert.assertEquals;
+import java.io.IOException;
/**
- * Add a field as a counter. Every time the callback method is called increment this
- * field. Unit test checks that the field is being incremented.
- *
- * Could be done with mock objects as well where the call method call is verified.
+ * Tests that Callback example runs without errors.
*/
public class AppTest {
-
- private Integer callingCount = 0;
-
- @Test
- public void test() {
- Callback callback = new Callback() {
- @Override
- public void call() {
- callingCount++;
- }
- };
-
- Task task = new SimpleTask();
-
- assertEquals("Initial calling count of 0", new Integer(0), callingCount);
-
- task.executeWith(callback);
-
- assertEquals("Callback called once", new Integer(1), callingCount);
-
- task.executeWith(callback);
-
- assertEquals("Callback called twice", new Integer(2), callingCount);
-
- }
+ @Test
+ public void test() throws IOException {
+ String[] args = {};
+ App.main(args);
+ }
}
diff --git a/callback/src/test/java/com/iluwatar/callback/CallbackTest.java b/callback/src/test/java/com/iluwatar/callback/CallbackTest.java
new file mode 100644
index 000000000..b48ac36ff
--- /dev/null
+++ b/callback/src/test/java/com/iluwatar/callback/CallbackTest.java
@@ -0,0 +1,79 @@
+/**
+ * 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.callback;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Add a field as a counter. Every time the callback method is called increment this field. Unit
+ * test checks that the field is being incremented.
+ *
+ * Could be done with mock objects as well where the call method call is verified.
+ */
+public class CallbackTest {
+
+ private Integer callingCount = 0;
+
+ @Test
+ public void test() {
+ Callback callback = new Callback() {
+ @Override
+ public void call() {
+ callingCount++;
+ }
+ };
+
+ Task task = new SimpleTask();
+
+ assertEquals("Initial calling count of 0", new Integer(0), callingCount);
+
+ task.executeWith(callback);
+
+ assertEquals("Callback called once", new Integer(1), callingCount);
+
+ task.executeWith(callback);
+
+ assertEquals("Callback called twice", new Integer(2), callingCount);
+
+ }
+
+ @Test
+ public void testWithLambdasExample() {
+ Callback callback = () -> callingCount++;
+
+ Task task = new SimpleTask();
+
+ assertEquals("Initial calling count of 0", new Integer(0), callingCount);
+
+ task.executeWith(callback);
+
+ assertEquals("Callback called once", new Integer(1), callingCount);
+
+ task.executeWith(callback);
+
+ assertEquals("Callback called twice", new Integer(2), callingCount);
+
+ }
+}
diff --git a/chain/index.md b/chain/README.md
similarity index 85%
rename from chain/index.md
rename to chain/README.md
index 9be376324..ef18f6f64 100644
--- a/chain/index.md
+++ b/chain/README.md
@@ -7,25 +7,28 @@ categories: Behavioral
tags:
- Java
- Gang Of Four
+ - Difficulty-Intermediate
---
-**Intent:** Avoid coupling the sender of a request to its receiver by giving
+## Intent
+Avoid coupling the sender of a request to its receiver by giving
more than one object a chance to handle the request. Chain the receiving
objects and pass the request along the chain until an object handles it.

-**Applicability:** Use Chain of Responsibility when
+## Applicability
+Use Chain of Responsibility when
* more than one object may handle a request, and the handler isn't known a priori. The handler should be ascertained automatically
* you want to issue a request to one of several objects without specifying the receiver explicitly
* the set of objects that can handle a request should be specified dynamically
-**Real world examples:**
+## Real world examples
* [java.util.logging.Logger#log()](http://docs.oracle.com/javase/8/docs/api/java/util/logging/Logger.html#log%28java.util.logging.Level,%20java.lang.String%29)
* [Apache Commons Chain](https://commons.apache.org/proper/commons-chain/index.html)
-**Credits**
+## Credits
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)
diff --git a/chain/pom.xml b/chain/pom.xml
index 80591a477..ee3b92401 100644
--- a/chain/pom.xml
+++ b/chain/pom.xml
@@ -1,11 +1,35 @@
+
4.0.0
com.iluwatar
java-design-patterns
- 1.7.0
+ 1.13.0-SNAPSHOT
chain
diff --git a/chain/src/main/java/com/iluwatar/chain/App.java b/chain/src/main/java/com/iluwatar/chain/App.java
index 4d3ca69db..cd6a200de 100644
--- a/chain/src/main/java/com/iluwatar/chain/App.java
+++ b/chain/src/main/java/com/iluwatar/chain/App.java
@@ -1,32 +1,53 @@
+/**
+ * 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.chain;
/**
*
- * The Chain of Responsibility pattern is a design pattern consisting of command
- * objects and a series of processing objects. Each processing object contains
- * logic that defines the types of command objects that it can handle; the rest are
- * passed to the next processing object in the chain. A mechanism also exists for
- * adding new processing objects to the end of this chain.
+ * The Chain of Responsibility pattern is a design pattern consisting of command objects and a
+ * series of processing objects. Each processing object contains logic that defines the types of
+ * command objects that it can handle; the rest are passed to the next processing object in the
+ * chain. A mechanism also exists for adding new processing objects to the end of this chain.
*
- * In this example we organize the request handlers ({@link RequestHandler}) into a
- * chain where each handler has a chance to act on the request on its turn. Here
- * the king ({@link OrcKing}) makes requests and the military orcs ({@link OrcCommander},
- * {@link OrcOfficer}, {@link OrcSoldier}) form the handler chain.
+ * In this example we organize the request handlers ({@link RequestHandler}) into a chain where each
+ * handler has a chance to act on the request on its turn. Here the king ({@link OrcKing}) makes
+ * requests and the military orcs ({@link OrcCommander}, {@link OrcOfficer}, {@link OrcSoldier})
+ * form the handler chain.
*
*/
public class App {
- /**
- * Program entry point
- * @param args command line args
- */
- public static void main(String[] args) {
+ /**
+ * Program entry point
+ *
+ * @param args command line args
+ */
+ public static void main(String[] args) {
- OrcKing king = new OrcKing();
- king.makeRequest(new Request(RequestType.DEFEND_CASTLE, "defend castle"));
- king.makeRequest(new Request(RequestType.TORTURE_PRISONER,
- "torture prisoner"));
- king.makeRequest(new Request(RequestType.COLLECT_TAX, "collect tax"));
+ OrcKing king = new OrcKing();
+ king.makeRequest(new Request(RequestType.DEFEND_CASTLE, "defend castle"));
+ king.makeRequest(new Request(RequestType.TORTURE_PRISONER, "torture prisoner"));
+ king.makeRequest(new Request(RequestType.COLLECT_TAX, "collect tax"));
- }
+ }
}
diff --git a/chain/src/main/java/com/iluwatar/chain/OrcCommander.java b/chain/src/main/java/com/iluwatar/chain/OrcCommander.java
index fb5134e01..a1f2bf284 100644
--- a/chain/src/main/java/com/iluwatar/chain/OrcCommander.java
+++ b/chain/src/main/java/com/iluwatar/chain/OrcCommander.java
@@ -1,3 +1,25 @@
+/**
+ * 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.chain;
/**
@@ -7,21 +29,22 @@ package com.iluwatar.chain;
*/
public class OrcCommander extends RequestHandler {
- public OrcCommander(RequestHandler handler) {
- super(handler);
- }
+ public OrcCommander(RequestHandler handler) {
+ super(handler);
+ }
- @Override
- public void handleRequest(Request req) {
- if (req.getRequestType().equals(RequestType.DEFEND_CASTLE)) {
- printHandling(req);
- } else {
- super.handleRequest(req);
- }
- }
+ @Override
+ public void handleRequest(Request req) {
+ if (req.getRequestType().equals(RequestType.DEFEND_CASTLE)) {
+ printHandling(req);
+ req.markHandled();
+ } else {
+ super.handleRequest(req);
+ }
+ }
- @Override
- public String toString() {
- return "Orc commander";
- }
+ @Override
+ public String toString() {
+ return "Orc commander";
+ }
}
diff --git a/chain/src/main/java/com/iluwatar/chain/OrcKing.java b/chain/src/main/java/com/iluwatar/chain/OrcKing.java
index b39959935..3b13c4a53 100644
--- a/chain/src/main/java/com/iluwatar/chain/OrcKing.java
+++ b/chain/src/main/java/com/iluwatar/chain/OrcKing.java
@@ -1,3 +1,25 @@
+/**
+ * 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.chain;
/**
@@ -7,18 +29,18 @@ package com.iluwatar.chain;
*/
public class OrcKing {
- RequestHandler chain;
+ RequestHandler chain;
- public OrcKing() {
- buildChain();
- }
+ public OrcKing() {
+ buildChain();
+ }
- private void buildChain() {
- chain = new OrcCommander(new OrcOfficer(new OrcSoldier(null)));
- }
+ private void buildChain() {
+ chain = new OrcCommander(new OrcOfficer(new OrcSoldier(null)));
+ }
- public void makeRequest(Request req) {
- chain.handleRequest(req);
- }
+ public void makeRequest(Request req) {
+ chain.handleRequest(req);
+ }
}
diff --git a/chain/src/main/java/com/iluwatar/chain/OrcOfficer.java b/chain/src/main/java/com/iluwatar/chain/OrcOfficer.java
index 131cb1101..ea35722c1 100644
--- a/chain/src/main/java/com/iluwatar/chain/OrcOfficer.java
+++ b/chain/src/main/java/com/iluwatar/chain/OrcOfficer.java
@@ -1,3 +1,25 @@
+/**
+ * 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.chain;
/**
@@ -7,22 +29,23 @@ package com.iluwatar.chain;
*/
public class OrcOfficer extends RequestHandler {
- public OrcOfficer(RequestHandler handler) {
- super(handler);
- }
+ public OrcOfficer(RequestHandler handler) {
+ super(handler);
+ }
- @Override
- public void handleRequest(Request req) {
- if (req.getRequestType().equals(RequestType.TORTURE_PRISONER)) {
- printHandling(req);
- } else {
- super.handleRequest(req);
- }
- }
+ @Override
+ public void handleRequest(Request req) {
+ if (req.getRequestType().equals(RequestType.TORTURE_PRISONER)) {
+ printHandling(req);
+ req.markHandled();
+ } else {
+ super.handleRequest(req);
+ }
+ }
- @Override
- public String toString() {
- return "Orc officer";
- }
+ @Override
+ public String toString() {
+ return "Orc officer";
+ }
}
diff --git a/chain/src/main/java/com/iluwatar/chain/OrcSoldier.java b/chain/src/main/java/com/iluwatar/chain/OrcSoldier.java
index a681dfb77..d7601bf4f 100644
--- a/chain/src/main/java/com/iluwatar/chain/OrcSoldier.java
+++ b/chain/src/main/java/com/iluwatar/chain/OrcSoldier.java
@@ -1,3 +1,25 @@
+/**
+ * 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.chain;
/**
@@ -7,21 +29,22 @@ package com.iluwatar.chain;
*/
public class OrcSoldier extends RequestHandler {
- public OrcSoldier(RequestHandler handler) {
- super(handler);
- }
+ public OrcSoldier(RequestHandler handler) {
+ super(handler);
+ }
- @Override
- public void handleRequest(Request req) {
- if (req.getRequestType().equals(RequestType.COLLECT_TAX)) {
- printHandling(req);
- } else {
- super.handleRequest(req);
- }
- }
+ @Override
+ public void handleRequest(Request req) {
+ if (req.getRequestType().equals(RequestType.COLLECT_TAX)) {
+ printHandling(req);
+ req.markHandled();
+ } else {
+ super.handleRequest(req);
+ }
+ }
- @Override
- public String toString() {
- return "Orc soldier";
- }
+ @Override
+ public String toString() {
+ return "Orc soldier";
+ }
}
diff --git a/chain/src/main/java/com/iluwatar/chain/Request.java b/chain/src/main/java/com/iluwatar/chain/Request.java
index 558ee65d1..399eddb36 100644
--- a/chain/src/main/java/com/iluwatar/chain/Request.java
+++ b/chain/src/main/java/com/iluwatar/chain/Request.java
@@ -1,38 +1,100 @@
+/**
+ * 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.chain;
+import java.util.Objects;
+
/**
- *
* Request
- *
*/
public class Request {
- private String requestDescription;
- private RequestType requestType;
+ /**
+ * The type of this request, used by each item in the chain to see if they should or can handle
+ * this particular request
+ */
+ private final RequestType requestType;
- public Request(RequestType requestType, String requestDescription) {
- this.setRequestType(requestType);
- this.setRequestDescription(requestDescription);
- }
+ /**
+ * A description of the request
+ */
+ private final String requestDescription;
- public String getRequestDescription() {
- return requestDescription;
- }
+ /**
+ * Indicates if the request is handled or not. A request can only switch state from unhandled to
+ * handled, there's no way to 'unhandle' a request
+ */
+ private boolean handled;
- public void setRequestDescription(String requestDescription) {
- this.requestDescription = requestDescription;
- }
+ /**
+ * Create a new request of the given type and accompanied description.
+ *
+ * @param requestType The type of request
+ * @param requestDescription The description of the request
+ */
+ public Request(final RequestType requestType, final String requestDescription) {
+ this.requestType = Objects.requireNonNull(requestType);
+ this.requestDescription = Objects.requireNonNull(requestDescription);
+ }
- public RequestType getRequestType() {
- return requestType;
- }
+ /**
+ * Get a description of the request
+ *
+ * @return A human readable description of the request
+ */
+ public String getRequestDescription() {
+ return requestDescription;
+ }
- public void setRequestType(RequestType requestType) {
- this.requestType = requestType;
- }
+ /**
+ * Get the type of this request, used by each person in the chain of command to see if they should
+ * or can handle this particular request
+ *
+ * @return The request type
+ */
+ public RequestType getRequestType() {
+ return requestType;
+ }
+
+ /**
+ * Mark the request as handled
+ */
+ public void markHandled() {
+ this.handled = true;
+ }
+
+ /**
+ * Indicates if this request is handled or not
+ *
+ * @return true when the request is handled, false if not
+ */
+ public boolean isHandled() {
+ return this.handled;
+ }
+
+ @Override
+ public String toString() {
+ return getRequestDescription();
+ }
- @Override
- public String toString() {
- return getRequestDescription();
- }
}
diff --git a/chain/src/main/java/com/iluwatar/chain/RequestHandler.java b/chain/src/main/java/com/iluwatar/chain/RequestHandler.java
index 5570c20ce..78d68e5dc 100644
--- a/chain/src/main/java/com/iluwatar/chain/RequestHandler.java
+++ b/chain/src/main/java/com/iluwatar/chain/RequestHandler.java
@@ -1,3 +1,25 @@
+/**
+ * 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.chain;
/**
@@ -7,22 +29,25 @@ package com.iluwatar.chain;
*/
public abstract class RequestHandler {
- private RequestHandler next;
+ private RequestHandler next;
- public RequestHandler(RequestHandler next) {
- this.next = next;
- }
+ public RequestHandler(RequestHandler next) {
+ this.next = next;
+ }
- public void handleRequest(Request req) {
- if (next != null) {
- next.handleRequest(req);
- }
- }
+ /**
+ * Request handler
+ */
+ public void handleRequest(Request req) {
+ if (next != null) {
+ next.handleRequest(req);
+ }
+ }
- protected void printHandling(Request req) {
- System.out.println(this + " handling request \"" + req + "\"");
- }
+ protected void printHandling(Request req) {
+ System.out.println(this + " handling request \"" + req + "\"");
+ }
- @Override
- public abstract String toString();
+ @Override
+ public abstract String toString();
}
diff --git a/chain/src/main/java/com/iluwatar/chain/RequestType.java b/chain/src/main/java/com/iluwatar/chain/RequestType.java
index 9ad975d2f..ff6dcff4d 100644
--- a/chain/src/main/java/com/iluwatar/chain/RequestType.java
+++ b/chain/src/main/java/com/iluwatar/chain/RequestType.java
@@ -1,3 +1,25 @@
+/**
+ * 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.chain;
/**
@@ -7,6 +29,6 @@ package com.iluwatar.chain;
*/
public enum RequestType {
- DEFEND_CASTLE, TORTURE_PRISONER, COLLECT_TAX
+ DEFEND_CASTLE, TORTURE_PRISONER, COLLECT_TAX
}
diff --git a/chain/src/test/java/com/iluwatar/chain/AppTest.java b/chain/src/test/java/com/iluwatar/chain/AppTest.java
index aa52e60e2..93a8a4096 100644
--- a/chain/src/test/java/com/iluwatar/chain/AppTest.java
+++ b/chain/src/test/java/com/iluwatar/chain/AppTest.java
@@ -1,9 +1,29 @@
+/**
+ * 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.chain;
import org.junit.Test;
-import com.iluwatar.chain.App;
-
/**
*
* Application test
@@ -11,9 +31,9 @@ import com.iluwatar.chain.App;
*/
public class AppTest {
- @Test
- public void test() {
- String[] args = {};
- App.main(args);
- }
+ @Test
+ public void test() {
+ String[] args = {};
+ App.main(args);
+ }
}
diff --git a/chain/src/test/java/com/iluwatar/chain/OrcKingTest.java b/chain/src/test/java/com/iluwatar/chain/OrcKingTest.java
new file mode 100644
index 000000000..be3650613
--- /dev/null
+++ b/chain/src/test/java/com/iluwatar/chain/OrcKingTest.java
@@ -0,0 +1,59 @@
+/**
+ * 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.chain;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Date: 12/6/15 - 9:29 PM
+ *
+ * @author Jeroen Meulemeester
+ */
+public class OrcKingTest {
+
+ /**
+ * All possible requests
+ */
+ private static final Request[] REQUESTS = new Request[]{
+ new Request(RequestType.DEFEND_CASTLE, "Don't let the barbarians enter my castle!!"),
+ new Request(RequestType.TORTURE_PRISONER, "Don't just stand there, tickle him!"),
+ new Request(RequestType.COLLECT_TAX, "Don't steal, the King hates competition ..."),
+ };
+
+ @Test
+ public void testMakeRequest() throws Exception {
+ final OrcKing king = new OrcKing();
+
+ for (final Request request : REQUESTS) {
+ king.makeRequest(request);
+ assertTrue(
+ "Expected all requests from King to be handled, but [" + request + "] was not!",
+ request.isHandled()
+ );
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/checkstyle-suppressions.xml b/checkstyle-suppressions.xml
new file mode 100644
index 000000000..60de4a697
--- /dev/null
+++ b/checkstyle-suppressions.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
diff --git a/checkstyle.xml b/checkstyle.xml
index 0ff943d95..19b6d2ec4 100644
--- a/checkstyle.xml
+++ b/checkstyle.xml
@@ -1,4 +1,28 @@
+
@@ -25,8 +49,10 @@
+
+
-
+
@@ -48,7 +74,7 @@
-
+
@@ -61,7 +87,7 @@
-
+
@@ -86,9 +112,6 @@
-
-
-
@@ -97,42 +120,19 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
@@ -180,11 +172,6 @@
-
-
-
-
@@ -195,7 +182,7 @@
-
+
@@ -205,4 +192,5 @@
+
diff --git a/command/index.md b/command/README.md
similarity index 88%
rename from command/index.md
rename to command/README.md
index c9790819f..a5478394c 100644
--- a/command/index.md
+++ b/command/README.md
@@ -7,15 +7,22 @@ categories: Behavioral
tags:
- Java
- Gang Of Four
+ - Difficulty-Intermediate
+ - Functional
---
-**Intent:** Encapsulate a request as an object, thereby letting you
+## Also known as
+Action, Transaction
+
+## Intent
+Encapsulate a request as an object, thereby letting you
parameterize clients with different requests, queue or log requests, and
support undoable operations.

-**Applicability:** Use the Command pattern when you want to
+## Applicability
+Use the Command pattern when you want to
* parameterize objects by an action to perform. You can express such parameterization in a procedural language with a callback function, that is, a function that's registered somewhere to be called at a later point. Commands are an object-oriented replacement for callbacks.
* specify, queue, and execute requests at different times. A Command object can have a lifetime independent of the original request. If the receiver of a request can be represented in an address space-independent way, then you can transfer a command object for the request to a different process and fulfill the request there
@@ -23,16 +30,17 @@ support undoable operations.
* support logging changes so that they can be reapplied in case of a system crash. By augmenting the Command interface with load and store operations, you can keep a persistent log of changes. Recovering from a crash involves reloading logged commands from disk and re-executing them with the execute operation
* structure a system around high-level operations build on primitive operations. Such a structure is common in information systems that support transactions. A transaction encapsulates a set of changes to data. The Command pattern offers a way to model transactions. Commands have a common interface, letting you invoke all transactions the same way. The pattern also makes it easy to extend the system with new transactions
-**Typical Use Case:**
+## Typical Use Case
* to keep a history of requests
* implement callback functionality
* implement the undo functionality
-**Real world examples:**
+## Real world examples
* [java.lang.Runnable](http://docs.oracle.com/javase/8/docs/api/java/lang/Runnable.html)
+* [Netflix Hystrix](https://github.com/Netflix/Hystrix/wiki)
-**Credits**
+## Credits
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)
diff --git a/command/pom.xml b/command/pom.xml
index 22f1c256b..a27a56e54 100644
--- a/command/pom.xml
+++ b/command/pom.xml
@@ -1,11 +1,35 @@
+
4.0.0
com.iluwatar
java-design-patterns
- 1.7.0
+ 1.13.0-SNAPSHOT
command
@@ -14,5 +38,10 @@
junit
test
+
+ org.mockito
+ mockito-core
+ test
+
diff --git a/command/src/main/java/com/iluwatar/command/App.java b/command/src/main/java/com/iluwatar/command/App.java
index b421b683b..93f9c376a 100644
--- a/command/src/main/java/com/iluwatar/command/App.java
+++ b/command/src/main/java/com/iluwatar/command/App.java
@@ -1,53 +1,77 @@
+/**
+ * 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.command;
/**
*
- * The Command pattern is a behavioral design pattern in which an object is used to encapsulate all information
- * needed to perform an action or trigger an event at a later time. This information includes the method name,
- * the object that owns the method and values for the method parameters.
+ * The Command pattern is a behavioral design pattern in which an object is used to encapsulate all
+ * information needed to perform an action or trigger an event at a later time. This information
+ * includes the method name, the object that owns the method and values for the method parameters.
*
- * Four terms always associated with the command pattern are command, receiver, invoker and client. A command
- * object (spell) knows about the receiver (target) and invokes a method of the receiver. Values for parameters of
- * the receiver method are stored in the command. The receiver then does the work. An invoker object (wizard)
- * knows how to execute a command, and optionally does bookkeeping about the command execution. The invoker
- * does not know anything about a concrete command, it knows only about command interface. Both an invoker object
- * and several command objects are held by a client object (app). The client decides which commands to execute at
- * which points. To execute a command, it passes the command object to the invoker object.
+ * Four terms always associated with the command pattern are command, receiver, invoker and client.
+ * A command object (spell) knows about the receiver (target) and invokes a method of the receiver.
+ * Values for parameters of the receiver method are stored in the command. The receiver then does
+ * the work. An invoker object (wizard) knows how to execute a command, and optionally does
+ * bookkeeping about the command execution. The invoker does not know anything about a concrete
+ * command, it knows only about command interface. Both an invoker object and several command
+ * objects are held by a client object (app). The client decides which commands to execute at which
+ * points. To execute a command, it passes the command object to the invoker object.
*
- * In other words, in this example the wizard casts spells on the goblin. The wizard keeps track of the previous
- * spells cast, so it is easy to undo them. In addition, the wizard keeps track of the spells undone, so they
- * can be redone.
+ * In other words, in this example the wizard casts spells on the goblin. The wizard keeps track of
+ * the previous spells cast, so it is easy to undo them. In addition, the wizard keeps track of the
+ * spells undone, so they can be redone.
*
*
*/
public class App {
- /**
- * Program entry point
- * @param args command line args
- */
- public static void main(String[] args) {
- Wizard wizard = new Wizard();
- Goblin goblin = new Goblin();
+ /**
+ * Program entry point
+ *
+ * @param args command line args
+ */
+ public static void main(String[] args) {
+ Wizard wizard = new Wizard();
+ Goblin goblin = new Goblin();
- goblin.printStatus();
+ goblin.printStatus();
- wizard.castSpell(new ShrinkSpell(), goblin);
- goblin.printStatus();
+ wizard.castSpell(new ShrinkSpell(), goblin);
+ goblin.printStatus();
- wizard.castSpell(new InvisibilitySpell(), goblin);
- goblin.printStatus();
+ wizard.castSpell(new InvisibilitySpell(), goblin);
+ goblin.printStatus();
- wizard.undoLastSpell();
- goblin.printStatus();
+ wizard.undoLastSpell();
+ goblin.printStatus();
- wizard.undoLastSpell();
- goblin.printStatus();
+ wizard.undoLastSpell();
+ goblin.printStatus();
- wizard.redoLastSpell();
- goblin.printStatus();
+ wizard.redoLastSpell();
+ goblin.printStatus();
- wizard.redoLastSpell();
- goblin.printStatus();
- }
+ wizard.redoLastSpell();
+ goblin.printStatus();
+ }
}
diff --git a/command/src/main/java/com/iluwatar/command/Command.java b/command/src/main/java/com/iluwatar/command/Command.java
index 9ffeed24d..c7b0c43bb 100644
--- a/command/src/main/java/com/iluwatar/command/Command.java
+++ b/command/src/main/java/com/iluwatar/command/Command.java
@@ -1,3 +1,25 @@
+/**
+ * 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.command;
/**
@@ -7,13 +29,13 @@ package com.iluwatar.command;
*/
public abstract class Command {
- public abstract void execute(Target target);
+ public abstract void execute(Target target);
- public abstract void undo();
+ public abstract void undo();
- public abstract void redo();
+ public abstract void redo();
- @Override
- public abstract String toString();
+ @Override
+ public abstract String toString();
}
diff --git a/command/src/main/java/com/iluwatar/command/Goblin.java b/command/src/main/java/com/iluwatar/command/Goblin.java
index 7d0804b0c..9e21cdefd 100644
--- a/command/src/main/java/com/iluwatar/command/Goblin.java
+++ b/command/src/main/java/com/iluwatar/command/Goblin.java
@@ -1,3 +1,25 @@
+/**
+ * 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.command;
/**
@@ -7,14 +29,14 @@ package com.iluwatar.command;
*/
public class Goblin extends Target {
- public Goblin() {
- setSize(Size.NORMAL);
- setVisibility(Visibility.VISIBLE);
- }
+ public Goblin() {
+ setSize(Size.NORMAL);
+ setVisibility(Visibility.VISIBLE);
+ }
- @Override
- public String toString() {
- return "Goblin";
- }
+ @Override
+ public String toString() {
+ return "Goblin";
+ }
}
diff --git a/command/src/main/java/com/iluwatar/command/InvisibilitySpell.java b/command/src/main/java/com/iluwatar/command/InvisibilitySpell.java
index b72c34cc2..9435e7245 100644
--- a/command/src/main/java/com/iluwatar/command/InvisibilitySpell.java
+++ b/command/src/main/java/com/iluwatar/command/InvisibilitySpell.java
@@ -1,3 +1,25 @@
+/**
+ * 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.command;
/**
@@ -7,30 +29,30 @@ package com.iluwatar.command;
*/
public class InvisibilitySpell extends Command {
- private Target target;
+ private Target target;
- @Override
- public void execute(Target target) {
- target.setVisibility(Visibility.INVISIBLE);
- this.target = target;
- }
+ @Override
+ public void execute(Target target) {
+ target.setVisibility(Visibility.INVISIBLE);
+ this.target = target;
+ }
- @Override
- public void undo() {
- if (target != null) {
- target.setVisibility(Visibility.VISIBLE);
- }
- }
+ @Override
+ public void undo() {
+ if (target != null) {
+ target.setVisibility(Visibility.VISIBLE);
+ }
+ }
- @Override
- public void redo() {
- if (target != null) {
- target.setVisibility(Visibility.INVISIBLE);
- }
- }
+ @Override
+ public void redo() {
+ if (target != null) {
+ target.setVisibility(Visibility.INVISIBLE);
+ }
+ }
- @Override
- public String toString() {
- return "Invisibility spell";
- }
+ @Override
+ public String toString() {
+ return "Invisibility spell";
+ }
}
diff --git a/command/src/main/java/com/iluwatar/command/ShrinkSpell.java b/command/src/main/java/com/iluwatar/command/ShrinkSpell.java
index f36438082..e88447353 100644
--- a/command/src/main/java/com/iluwatar/command/ShrinkSpell.java
+++ b/command/src/main/java/com/iluwatar/command/ShrinkSpell.java
@@ -1,3 +1,25 @@
+/**
+ * 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.command;
/**
@@ -7,32 +29,32 @@ package com.iluwatar.command;
*/
public class ShrinkSpell extends Command {
- private Size oldSize;
- private Target target;
+ private Size oldSize;
+ private Target target;
- @Override
- public void execute(Target target) {
- oldSize = target.getSize();
- target.setSize(Size.SMALL);
- this.target = target;
- }
+ @Override
+ public void execute(Target target) {
+ oldSize = target.getSize();
+ target.setSize(Size.SMALL);
+ this.target = target;
+ }
- @Override
- public void undo() {
- if (oldSize != null && target != null) {
- Size temp = target.getSize();
- target.setSize(oldSize);
- oldSize = temp;
- }
- }
+ @Override
+ public void undo() {
+ if (oldSize != null && target != null) {
+ Size temp = target.getSize();
+ target.setSize(oldSize);
+ oldSize = temp;
+ }
+ }
- @Override
- public void redo() {
- undo();
- }
+ @Override
+ public void redo() {
+ undo();
+ }
- @Override
- public String toString() {
- return "Shrink spell";
- }
+ @Override
+ public String toString() {
+ return "Shrink spell";
+ }
}
diff --git a/command/src/main/java/com/iluwatar/command/Size.java b/command/src/main/java/com/iluwatar/command/Size.java
index a9c20bd59..d33a19453 100644
--- a/command/src/main/java/com/iluwatar/command/Size.java
+++ b/command/src/main/java/com/iluwatar/command/Size.java
@@ -1,3 +1,25 @@
+/**
+ * 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.command;
/**
@@ -7,16 +29,16 @@ package com.iluwatar.command;
*/
public enum Size {
- SMALL("small"), NORMAL("normal"), LARGE("large"), UNDEFINED("");
-
- private String title;
+ SMALL("small"), NORMAL("normal"), LARGE("large"), UNDEFINED("");
- Size(String title) {
- this.title = title;
- }
+ private String title;
- @Override
- public String toString() {
- return title;
- }
+ Size(String title) {
+ this.title = title;
+ }
+
+ @Override
+ public String toString() {
+ return title;
+ }
}
diff --git a/command/src/main/java/com/iluwatar/command/Target.java b/command/src/main/java/com/iluwatar/command/Target.java
index 6ea2681d3..2e49ab663 100644
--- a/command/src/main/java/com/iluwatar/command/Target.java
+++ b/command/src/main/java/com/iluwatar/command/Target.java
@@ -1,3 +1,25 @@
+/**
+ * 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.command;
/**
@@ -7,32 +29,35 @@ package com.iluwatar.command;
*/
public abstract class Target {
- private Size size;
+ private Size size;
- private Visibility visibility;
+ private Visibility visibility;
- public Size getSize() {
- return size;
- }
+ public Size getSize() {
+ return size;
+ }
- public void setSize(Size size) {
- this.size = size;
- }
+ public void setSize(Size size) {
+ this.size = size;
+ }
- public Visibility getVisibility() {
- return visibility;
- }
+ public Visibility getVisibility() {
+ return visibility;
+ }
- public void setVisibility(Visibility visibility) {
- this.visibility = visibility;
- }
+ public void setVisibility(Visibility visibility) {
+ this.visibility = visibility;
+ }
- @Override
- public abstract String toString();
+ @Override
+ public abstract String toString();
- public void printStatus() {
- System.out.println(String.format("%s, [size=%s] [visibility=%s]", this,
- getSize(), getVisibility()));
- System.out.println();
- }
+ /**
+ * Print status
+ */
+ public void printStatus() {
+ System.out.println(String.format("%s, [size=%s] [visibility=%s]", this, getSize(),
+ getVisibility()));
+ System.out.println();
+ }
}
diff --git a/command/src/main/java/com/iluwatar/command/Visibility.java b/command/src/main/java/com/iluwatar/command/Visibility.java
index 3316ac9e3..4ab079d18 100644
--- a/command/src/main/java/com/iluwatar/command/Visibility.java
+++ b/command/src/main/java/com/iluwatar/command/Visibility.java
@@ -1,3 +1,25 @@
+/**
+ * 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.command;
/**
@@ -7,16 +29,16 @@ package com.iluwatar.command;
*/
public enum Visibility {
- VISIBLE("visible"), INVISIBLE("invisible"), UNDEFINED("");
+ VISIBLE("visible"), INVISIBLE("invisible"), UNDEFINED("");
- private String title;
+ private String title;
- Visibility(String title) {
- this.title = title;
- }
+ Visibility(String title) {
+ this.title = title;
+ }
- @Override
- public String toString() {
- return title;
- }
+ @Override
+ public String toString() {
+ return title;
+ }
}
diff --git a/command/src/main/java/com/iluwatar/command/Wizard.java b/command/src/main/java/com/iluwatar/command/Wizard.java
index 995b4441a..bd0ef85d4 100644
--- a/command/src/main/java/com/iluwatar/command/Wizard.java
+++ b/command/src/main/java/com/iluwatar/command/Wizard.java
@@ -1,3 +1,25 @@
+/**
+ * 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.command;
import java.util.Deque;
@@ -10,38 +32,46 @@ import java.util.LinkedList;
*/
public class Wizard {
- private Deque undoStack = new LinkedList<>();
- private Deque redoStack = new LinkedList<>();
+ private Deque undoStack = new LinkedList<>();
+ private Deque redoStack = new LinkedList<>();
- public Wizard() {
- }
+ public Wizard() {}
- public void castSpell(Command command, Target target) {
- System.out.println(this + " casts " + command + " at " + target);
- command.execute(target);
- undoStack.offerLast(command);
- }
+ /**
+ * Cast spell
+ */
+ public void castSpell(Command command, Target target) {
+ System.out.println(this + " casts " + command + " at " + target);
+ command.execute(target);
+ undoStack.offerLast(command);
+ }
- public void undoLastSpell() {
- if (!undoStack.isEmpty()) {
- Command previousSpell = undoStack.pollLast();
- redoStack.offerLast(previousSpell);
- System.out.println(this + " undoes " + previousSpell);
- previousSpell.undo();
- }
- }
+ /**
+ * Undo last spell
+ */
+ public void undoLastSpell() {
+ if (!undoStack.isEmpty()) {
+ Command previousSpell = undoStack.pollLast();
+ redoStack.offerLast(previousSpell);
+ System.out.println(this + " undoes " + previousSpell);
+ previousSpell.undo();
+ }
+ }
- public void redoLastSpell() {
- if (!redoStack.isEmpty()) {
- Command previousSpell = redoStack.pollLast();
- undoStack.offerLast(previousSpell);
- System.out.println(this + " redoes " + previousSpell);
- previousSpell.redo();
- }
- }
+ /**
+ * Redo last spell
+ */
+ public void redoLastSpell() {
+ if (!redoStack.isEmpty()) {
+ Command previousSpell = redoStack.pollLast();
+ undoStack.offerLast(previousSpell);
+ System.out.println(this + " redoes " + previousSpell);
+ previousSpell.redo();
+ }
+ }
- @Override
- public String toString() {
- return "Wizard";
- }
+ @Override
+ public String toString() {
+ return "Wizard";
+ }
}
diff --git a/command/src/test/java/com/iluwatar/command/AppTest.java b/command/src/test/java/com/iluwatar/command/AppTest.java
index 2fd5c16b4..560594272 100644
--- a/command/src/test/java/com/iluwatar/command/AppTest.java
+++ b/command/src/test/java/com/iluwatar/command/AppTest.java
@@ -1,19 +1,38 @@
+/**
+ * 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.command;
import org.junit.Test;
-import com.iluwatar.command.App;
+import java.io.IOException;
/**
- *
- * Application test
- *
+ * Tests that Command example runs without errors.
*/
public class AppTest {
-
- @Test
- public void test() {
- String[] args = {};
- App.main(args);
- }
+ @Test
+ public void test() throws IOException {
+ String[] args = {};
+ App.main(args);
+ }
}
diff --git a/command/src/test/java/com/iluwatar/command/CommandTest.java b/command/src/test/java/com/iluwatar/command/CommandTest.java
new file mode 100644
index 000000000..8201d50c6
--- /dev/null
+++ b/command/src/test/java/com/iluwatar/command/CommandTest.java
@@ -0,0 +1,93 @@
+/**
+ * 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.command;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+/**
+ * The Command pattern is a behavioral design pattern in which an object is used to encapsulate all
+ * information needed to perform an action or trigger an event at a later time. This information
+ * includes the method name, the object that owns the method and values for the method parameters.
+ *
+ * Four terms always associated with the command pattern are command, receiver, invoker and
+ * client. A command object (spell) knows about the receiver (target) and invokes a method of
+ * the receiver.Values for parameters of the receiver method are stored in the command. The receiver
+ * then does the work. An invoker object (wizard) knows how to execute a command, and optionally
+ * does bookkeeping about the command execution. The invoker does not know anything about a
+ * concrete command, it knows only about command interface. Both an invoker object and several
+ * command objects are held by a client object (app). The client decides which commands to execute
+ * at which points. To execute a command, it passes the command object to the invoker object.
+ */
+public class CommandTest {
+
+ private static final String GOBLIN = "Goblin";
+
+ /**
+ * This test verifies that when the wizard casts spells on the goblin. The wizard keeps track of
+ * the previous spells cast, so it is easy to undo them. In addition, it also verifies that the
+ * wizard keeps track of the spells undone, so they can be redone.
+ */
+ @Test
+ public void testCommand() {
+
+ Wizard wizard = new Wizard();
+ Goblin goblin = new Goblin();
+
+ wizard.castSpell(new ShrinkSpell(), goblin);
+ verifyGoblin(goblin, GOBLIN, Size.SMALL, Visibility.VISIBLE);
+
+ wizard.castSpell(new InvisibilitySpell(), goblin);
+ verifyGoblin(goblin, GOBLIN, Size.SMALL, Visibility.INVISIBLE);
+
+ wizard.undoLastSpell();
+ verifyGoblin(goblin, GOBLIN, Size.SMALL, Visibility.VISIBLE);
+
+ wizard.undoLastSpell();
+ verifyGoblin(goblin, GOBLIN, Size.NORMAL, Visibility.VISIBLE);
+
+ wizard.redoLastSpell();
+ verifyGoblin(goblin, GOBLIN, Size.SMALL, Visibility.VISIBLE);
+
+ wizard.redoLastSpell();
+ verifyGoblin(goblin, GOBLIN, Size.SMALL, Visibility.INVISIBLE);
+ }
+
+ /**
+ * This method asserts that the passed goblin object has the name as expectedName, size as
+ * expectedSize and visibility as expectedVisibility.
+ *
+ * @param goblin a goblin object whose state is to be verified against other parameters
+ * @param expectedName expectedName of the goblin
+ * @param expectedSize expected size of the goblin
+ * @param expectedVisibilty exepcted visibility of the goblin
+ */
+ private void verifyGoblin(Goblin goblin, String expectedName, Size expectedSize,
+ Visibility expectedVisibilty) {
+ assertEquals("Goblin's name must be same as expectedName", expectedName, goblin.toString());
+ assertEquals("Goblin's size must be same as expectedSize", expectedSize, goblin.getSize());
+ assertEquals("Goblin's visibility must be same as expectedVisibility", expectedVisibilty,
+ goblin.getVisibility());
+ }
+}
diff --git a/composite/index.md b/composite/README.md
similarity index 87%
rename from composite/index.md
rename to composite/README.md
index 4a31a1b33..8b980292d 100644
--- a/composite/index.md
+++ b/composite/README.md
@@ -7,24 +7,27 @@ categories: Structural
tags:
- Java
- Gang Of Four
+ - Difficulty-Intermediate
---
-**Intent:** Compose objects into tree structures to represent part-whole
+## Intent
+Compose objects into tree structures to represent part-whole
hierarchies. Composite lets clients treat individual objects and compositions
of objects uniformly.

-**Applicability:** Use the Composite pattern when
+## Applicability
+Use the Composite pattern when
* you want to represent part-whole hierarchies of objects
* you want clients to be able to ignore the difference between compositions of objects and individual objects. Clients will treat all objects in the composite structure uniformly
-**Real world examples:**
+## Real world examples
* [java.awt.Container](http://docs.oracle.com/javase/8/docs/api/java/awt/Container.html) and [java.awt.Component](http://docs.oracle.com/javase/8/docs/api/java/awt/Component.html)
* [Apache Wicket](https://github.com/apache/wicket) component tree, see [Component](https://github.com/apache/wicket/blob/91e154702ab1ff3481ef6cbb04c6044814b7e130/wicket-core/src/main/java/org/apache/wicket/Component.java) and [MarkupContainer](https://github.com/apache/wicket/blob/b60ec64d0b50a611a9549809c9ab216f0ffa3ae3/wicket-core/src/main/java/org/apache/wicket/MarkupContainer.java)
-**Credits**
+## Credits
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)
diff --git a/composite/pom.xml b/composite/pom.xml
index 2b8298647..ace29d8d1 100644
--- a/composite/pom.xml
+++ b/composite/pom.xml
@@ -1,11 +1,35 @@
+
4.0.0
com.iluwatar
java-design-patterns
- 1.7.0
+ 1.13.0-SNAPSHOT
composite
diff --git a/composite/src/main/java/com/iluwatar/composite/App.java b/composite/src/main/java/com/iluwatar/composite/App.java
index 7bd0e4d01..cfe37876f 100644
--- a/composite/src/main/java/com/iluwatar/composite/App.java
+++ b/composite/src/main/java/com/iluwatar/composite/App.java
@@ -1,33 +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.composite;
/**
- * The Composite pattern is a partitioning design pattern. The Composite pattern
- * describes that a group of objects is to be treated in the same way as a single
- * instance of an object. The intent of a composite is to "compose" objects into
- * tree structures to represent part-whole hierarchies. Implementing the Composite
- * pattern lets clients treat individual objects and compositions uniformly.
+ * The Composite pattern is a partitioning design pattern. The Composite pattern describes that a
+ * group of objects is to be treated in the same way as a single instance of an object. The intent
+ * of a composite is to "compose" objects into tree structures to represent part-whole hierarchies.
+ * Implementing the Composite pattern lets clients treat individual objects and compositions
+ * uniformly.
*
- * In this example we have sentences composed of words composed of letters. All of
- * the objects can be treated through the same interface ({@link LetterComposite}).
+ * In this example we have sentences composed of words composed of letters. All of the objects can
+ * be treated through the same interface ({@link LetterComposite}).
*
*/
public class App {
- /**
- * Program entry point
- * @param args command line args
- */
- public static void main(String[] args) {
- System.out.println("Message from the orcs: ");
+ /**
+ * Program entry point
+ *
+ * @param args command line args
+ */
+ public static void main(String[] args) {
+ System.out.println("Message from the orcs: ");
- LetterComposite orcMessage = new Messenger().messageFromOrcs();
- orcMessage.print();
+ LetterComposite orcMessage = new Messenger().messageFromOrcs();
+ orcMessage.print();
- System.out.println("\n");
+ System.out.println("\n");
- System.out.println("Message from the elves: ");
+ System.out.println("Message from the elves: ");
- LetterComposite elfMessage = new Messenger().messageFromElves();
- elfMessage.print();
- }
+ LetterComposite elfMessage = new Messenger().messageFromElves();
+ elfMessage.print();
+ }
}
diff --git a/composite/src/main/java/com/iluwatar/composite/Letter.java b/composite/src/main/java/com/iluwatar/composite/Letter.java
index 8304ea801..d6a4005d2 100644
--- a/composite/src/main/java/com/iluwatar/composite/Letter.java
+++ b/composite/src/main/java/com/iluwatar/composite/Letter.java
@@ -1,3 +1,25 @@
+/**
+ * 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.composite;
/**
@@ -7,20 +29,19 @@ package com.iluwatar.composite;
*/
public class Letter extends LetterComposite {
- private char c;
+ private char c;
- public Letter(char c) {
- this.c = c;
- }
+ public Letter(char c) {
+ this.c = c;
+ }
- @Override
- protected void printThisBefore() {
- System.out.print(c);
- }
-
- @Override
- protected void printThisAfter() {
- // nop
- }
+ @Override
+ protected void printThisBefore() {
+ System.out.print(c);
+ }
+ @Override
+ protected void printThisAfter() {
+ // nop
+ }
}
diff --git a/composite/src/main/java/com/iluwatar/composite/LetterComposite.java b/composite/src/main/java/com/iluwatar/composite/LetterComposite.java
index e58d51b25..940562969 100644
--- a/composite/src/main/java/com/iluwatar/composite/LetterComposite.java
+++ b/composite/src/main/java/com/iluwatar/composite/LetterComposite.java
@@ -1,3 +1,25 @@
+/**
+ * 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.composite;
import java.util.ArrayList;
@@ -10,25 +32,28 @@ import java.util.List;
*/
public abstract class LetterComposite {
- private List children = new ArrayList();
+ private List children = new ArrayList<>();
- public void add(LetterComposite letter) {
- children.add(letter);
- }
+ public void add(LetterComposite letter) {
+ children.add(letter);
+ }
- public int count() {
- return children.size();
- }
+ public int count() {
+ return children.size();
+ }
- protected abstract void printThisBefore();
+ protected abstract void printThisBefore();
- protected abstract void printThisAfter();
+ protected abstract void printThisAfter();
- public void print() {
- printThisBefore();
- for (LetterComposite letter : children) {
- letter.print();
- }
- printThisAfter();
- }
+ /**
+ * Print
+ */
+ public void print() {
+ printThisBefore();
+ for (LetterComposite letter : children) {
+ letter.print();
+ }
+ printThisAfter();
+ }
}
diff --git a/composite/src/main/java/com/iluwatar/composite/Messenger.java b/composite/src/main/java/com/iluwatar/composite/Messenger.java
index aa0560d4d..3b758d680 100644
--- a/composite/src/main/java/com/iluwatar/composite/Messenger.java
+++ b/composite/src/main/java/com/iluwatar/composite/Messenger.java
@@ -1,3 +1,25 @@
+/**
+ * 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.composite;
import java.util.ArrayList;
@@ -11,48 +33,47 @@ import java.util.List;
*/
public class Messenger {
- LetterComposite messageFromOrcs() {
+ LetterComposite messageFromOrcs() {
- List words = new ArrayList();
+ List words = new ArrayList<>();
- words.add(new Word(Arrays.asList(new Letter('W'), new Letter('h'),
- new Letter('e'), new Letter('r'), new Letter('e'))));
- words.add(new Word(Arrays.asList(new Letter('t'), new Letter('h'),
- new Letter('e'), new Letter('r'), new Letter('e'))));
- words.add(new Word(Arrays.asList(new Letter('i'), new Letter('s'))));
- words.add(new Word(Arrays.asList(new Letter('a'))));
- words.add(new Word(Arrays.asList(new Letter('w'), new Letter('h'),
- new Letter('i'), new Letter('p'))));
- words.add(new Word(Arrays.asList(new Letter('t'), new Letter('h'),
- new Letter('e'), new Letter('r'), new Letter('e'))));
- words.add(new Word(Arrays.asList(new Letter('i'), new Letter('s'))));
- words.add(new Word(Arrays.asList(new Letter('a'))));
- words.add(new Word(Arrays.asList(new Letter('w'), new Letter('a'),
- new Letter('y'))));
+ words.add(new Word(Arrays.asList(new Letter('W'), new Letter('h'), new Letter('e'), new Letter(
+ 'r'), new Letter('e'))));
+ words.add(new Word(Arrays.asList(new Letter('t'), new Letter('h'), new Letter('e'), new Letter(
+ 'r'), new Letter('e'))));
+ words.add(new Word(Arrays.asList(new Letter('i'), new Letter('s'))));
+ words.add(new Word(Arrays.asList(new Letter('a'))));
+ words.add(new Word(Arrays.asList(new Letter('w'), new Letter('h'), new Letter('i'), new Letter(
+ 'p'))));
+ words.add(new Word(Arrays.asList(new Letter('t'), new Letter('h'), new Letter('e'), new Letter(
+ 'r'), new Letter('e'))));
+ words.add(new Word(Arrays.asList(new Letter('i'), new Letter('s'))));
+ words.add(new Word(Arrays.asList(new Letter('a'))));
+ words.add(new Word(Arrays.asList(new Letter('w'), new Letter('a'), new Letter('y'))));
- return new Sentence(words);
+ return new Sentence(words);
- }
+ }
- LetterComposite messageFromElves() {
+ LetterComposite messageFromElves() {
- List words = new ArrayList();
+ List words = new ArrayList<>();
- words.add(new Word(Arrays.asList(new Letter('M'), new Letter('u'),
- new Letter('c'), new Letter('h'))));
- words.add(new Word(Arrays.asList(new Letter('w'), new Letter('i'),
- new Letter('n'), new Letter('d'))));
- words.add(new Word(Arrays.asList(new Letter('p'), new Letter('o'),
- new Letter('u'), new Letter('r'), new Letter('s'))));
- words.add(new Word(Arrays.asList(new Letter('f'), new Letter('r'),
- new Letter('o'), new Letter('m'))));
- words.add(new Word(Arrays.asList(new Letter('y'), new Letter('o'),
- new Letter('u'), new Letter('r'))));
- words.add(new Word(Arrays.asList(new Letter('m'), new Letter('o'),
- new Letter('u'), new Letter('t'), new Letter('h'))));
+ words.add(new Word(Arrays.asList(new Letter('M'), new Letter('u'), new Letter('c'), new Letter(
+ 'h'))));
+ words.add(new Word(Arrays.asList(new Letter('w'), new Letter('i'), new Letter('n'), new Letter(
+ 'd'))));
+ words.add(new Word(Arrays.asList(new Letter('p'), new Letter('o'), new Letter('u'), new Letter(
+ 'r'), new Letter('s'))));
+ words.add(new Word(Arrays.asList(new Letter('f'), new Letter('r'), new Letter('o'), new Letter(
+ 'm'))));
+ words.add(new Word(Arrays.asList(new Letter('y'), new Letter('o'), new Letter('u'), new Letter(
+ 'r'))));
+ words.add(new Word(Arrays.asList(new Letter('m'), new Letter('o'), new Letter('u'), new Letter(
+ 't'), new Letter('h'))));
- return new Sentence(words);
+ return new Sentence(words);
- }
+ }
}
diff --git a/composite/src/main/java/com/iluwatar/composite/Sentence.java b/composite/src/main/java/com/iluwatar/composite/Sentence.java
index 2fc13701b..eea1d4b1d 100644
--- a/composite/src/main/java/com/iluwatar/composite/Sentence.java
+++ b/composite/src/main/java/com/iluwatar/composite/Sentence.java
@@ -1,3 +1,25 @@
+/**
+ * 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.composite;
import java.util.List;
@@ -9,20 +31,22 @@ import java.util.List;
*/
public class Sentence extends LetterComposite {
- public Sentence(List words) {
- for (Word w : words) {
- this.add(w);
- }
- }
+ /**
+ * Constructor
+ */
+ public Sentence(List words) {
+ for (Word w : words) {
+ this.add(w);
+ }
+ }
- @Override
- protected void printThisBefore() {
- // nop
- }
-
- @Override
- protected void printThisAfter() {
- System.out.print(".");
- }
+ @Override
+ protected void printThisBefore() {
+ // nop
+ }
+ @Override
+ protected void printThisAfter() {
+ System.out.print(".");
+ }
}
diff --git a/composite/src/main/java/com/iluwatar/composite/Word.java b/composite/src/main/java/com/iluwatar/composite/Word.java
index e715ed28a..819f166dc 100644
--- a/composite/src/main/java/com/iluwatar/composite/Word.java
+++ b/composite/src/main/java/com/iluwatar/composite/Word.java
@@ -1,3 +1,25 @@
+/**
+ * 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.composite;
import java.util.List;
@@ -9,20 +31,22 @@ import java.util.List;
*/
public class Word extends LetterComposite {
- public Word(List letters) {
- for (Letter l : letters) {
- this.add(l);
- }
- }
+ /**
+ * Constructor
+ */
+ public Word(List letters) {
+ for (Letter l : letters) {
+ this.add(l);
+ }
+ }
- @Override
- protected void printThisBefore() {
- System.out.print(" ");
- }
-
- @Override
- protected void printThisAfter() {
- // nop
- }
+ @Override
+ protected void printThisBefore() {
+ System.out.print(" ");
+ }
+ @Override
+ protected void printThisAfter() {
+ // nop
+ }
}
diff --git a/composite/src/test/java/com/iluwatar/composite/AppTest.java b/composite/src/test/java/com/iluwatar/composite/AppTest.java
index 872ccea78..336438a99 100644
--- a/composite/src/test/java/com/iluwatar/composite/AppTest.java
+++ b/composite/src/test/java/com/iluwatar/composite/AppTest.java
@@ -1,9 +1,29 @@
+/**
+ * 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.composite;
import org.junit.Test;
-import com.iluwatar.composite.App;
-
/**
*
* Application test
@@ -11,9 +31,9 @@ import com.iluwatar.composite.App;
*/
public class AppTest {
- @Test
- public void test() {
- String[] args = {};
- App.main(args);
- }
+ @Test
+ public void test() {
+ String[] args = {};
+ App.main(args);
+ }
}
diff --git a/composite/src/test/java/com/iluwatar/composite/MessengerTest.java b/composite/src/test/java/com/iluwatar/composite/MessengerTest.java
new file mode 100644
index 000000000..5f75ea017
--- /dev/null
+++ b/composite/src/test/java/com/iluwatar/composite/MessengerTest.java
@@ -0,0 +1,112 @@
+/**
+ * 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.composite;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * Date: 12/11/15 - 8:12 PM
+ *
+ * @author Jeroen Meulemeester
+ */
+public class MessengerTest {
+
+ /**
+ * The buffer used to capture every write to {@link System#out}
+ */
+ private ByteArrayOutputStream stdOutBuffer = new ByteArrayOutputStream();
+
+ /**
+ * Keep the original std-out so it can be restored after the test
+ */
+ private final PrintStream realStdOut = System.out;
+
+ /**
+ * Inject the mocked std-out {@link PrintStream} into the {@link System} class before each test
+ */
+ @Before
+ public void setUp() {
+ this.stdOutBuffer = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(stdOutBuffer));
+ }
+
+ /**
+ * Removed the mocked std-out {@link PrintStream} again from the {@link System} class
+ */
+ @After
+ public void tearDown() {
+ System.setOut(realStdOut);
+ }
+
+ /**
+ * Test the message from the orcs
+ */
+ @Test
+ public void testMessageFromOrcs() {
+ final Messenger messenger = new Messenger();
+ testMessage(
+ messenger.messageFromOrcs(),
+ "Where there is a whip there is a way."
+ );
+ }
+
+ /**
+ * Test the message from the elves
+ */
+ @Test
+ public void testMessageFromElves() {
+ final Messenger messenger = new Messenger();
+ testMessage(
+ messenger.messageFromElves(),
+ "Much wind pours from your mouth."
+ );
+ }
+
+ /**
+ * Test if the given composed message matches the expected message
+ *
+ * @param composedMessage The composed message, received from the messenger
+ * @param message The expected message
+ */
+ private void testMessage(final LetterComposite composedMessage, final String message) {
+ // Test is the composed message has the correct number of words
+ final String[] words = message.split(" ");
+ assertNotNull(composedMessage);
+ assertEquals(words.length, composedMessage.count());
+
+ // Print the message to the mocked stdOut ...
+ composedMessage.print();
+
+ // ... and verify if the message matches with the expected one
+ assertEquals(message, new String(this.stdOutBuffer.toByteArray()).trim());
+ }
+
+}
diff --git a/dao/index.md b/dao/README.md
similarity index 69%
rename from dao/index.md
rename to dao/README.md
index cf9f43a68..785a1c362 100644
--- a/dao/index.md
+++ b/dao/README.md
@@ -3,22 +3,24 @@ layout: pattern
title: Data Access Object
folder: dao
permalink: /patterns/dao/
-categories: Architectural
+categories: Persistence Tier
tags:
- Java
- Difficulty-Beginner
---
-**Intent:** Object provides an abstract interface to some type of database or
+## Intent
+Object provides an abstract interface to some type of database or
other persistence mechanism.

-**Applicability:** Use the Data Access Object in any of the following situations
+## Applicability
+Use the Data Access Object in any of the following situations
* when you want to consolidate how the data layer is accessed
* when you want to avoid writing multiple data retrieval/persistence layers
-**Credits:**
+## Credits
* [J2EE Design Patterns](http://www.amazon.com/J2EE-Design-Patterns-William-Crawford/dp/0596004273/ref=sr_1_2)
diff --git a/dao/etc/dao.png b/dao/etc/dao.png
index 9fe34b976..452e72ba1 100644
Binary files a/dao/etc/dao.png and b/dao/etc/dao.png differ
diff --git a/dao/etc/dao.ucls b/dao/etc/dao.ucls
index bf11f18b3..0706837fc 100644
--- a/dao/etc/dao.ucls
+++ b/dao/etc/dao.ucls
@@ -1,45 +1,71 @@
-
-
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dao/pom.xml b/dao/pom.xml
index 69191b94d..f64eff8bc 100644
--- a/dao/pom.xml
+++ b/dao/pom.xml
@@ -1,24 +1,105 @@
+
- 4.0.0
-
- com.iluwatar
- java-design-patterns
- 1.7.0
-
- dao
-
-
-
- junit
- junit
- test
-
-
- log4j
- log4j
-
-
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+ xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ 4.0.0
+
+ com.iluwatar
+ java-design-patterns
+ 1.13.0-SNAPSHOT
+
+ dao
+
+
+
+ junit
+ junit
+ test
+
+
+ log4j
+ log4j
+
+
+ com.h2database
+ h2
+
+
+ de.bechte.junit
+ junit-hierarchicalcontextrunner
+
+
+ org.mockito
+ mockito-core
+
+
+
+
+
+
+
+
+
+ src/main/resources
+
+
+ src/main/resources
+
+ log4j.xml
+
+ ..
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 2.6
+
+
+ log4j.xml
+
+
+
+ true
+
+
+
+
+
+
+
diff --git a/dao/src/main/java/com/iluwatar/dao/App.java b/dao/src/main/java/com/iluwatar/dao/App.java
index 95cf93e5b..8a0c06739 100644
--- a/dao/src/main/java/com/iluwatar/dao/App.java
+++ b/dao/src/main/java/com/iluwatar/dao/App.java
@@ -1,59 +1,135 @@
+/**
+ * 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.dao;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
+import java.util.stream.Stream;
+
+import javax.sql.DataSource;
import org.apache.log4j.Logger;
+import org.h2.jdbcx.JdbcDataSource;
/**
+ * Data Access Object (DAO) is an object that provides an abstract interface to some type of
+ * database or other persistence mechanism. By mapping application calls to the persistence layer,
+ * DAO provide some specific data operations without exposing details of the database. This
+ * isolation supports the Single responsibility principle. It separates what data accesses the
+ * application needs, in terms of domain-specific objects and data types (the public interface of
+ * the DAO), from how these needs can be satisfied with a specific DBMS.
+ *
+ * With the DAO pattern, we can use various method calls to retrieve/add/delete/update data
+ * without directly interacting with the data source. The below example demonstrates basic CRUD
+ * operations: select, add, update, and delete.
*
- * Data Access Object (DAO) is an object that provides an abstract interface to some type of database or other
- * persistence mechanism. By mapping application calls to the persistence layer, DAO provide some specific data
- * operations without exposing details of the database. This isolation supports the Single responsibility principle.
- * It separates what data accesses the application needs, in terms of domain-specific objects and data types
- * (the public interface of the DAO), from how these needs can be satisfied with a specific DBMS.
- *
- * With the DAO pattern, we can use various method calls to retrieve/add/delete/update data without directly
- * interacting with the data. The below example demonstrates basic CRUD operations: select, add, update, and delete.
*
*/
public class App {
+ private static final String DB_URL = "jdbc:h2:~/dao";
+ private static Logger log = Logger.getLogger(App.class);
+
+ /**
+ * Program entry point.
+ *
+ * @param args command line args.
+ * @throws Exception if any error occurs.
+ */
+ public static void main(final String[] args) throws Exception {
+ final CustomerDao inMemoryDao = new InMemoryCustomerDao();
+ performOperationsUsing(inMemoryDao);
+
+ final DataSource dataSource = createDataSource();
+ createSchema(dataSource);
+ final CustomerDao dbDao = new DbCustomerDao(dataSource);
+ performOperationsUsing(dbDao);
+ deleteSchema(dataSource);
+ }
- private static Logger LOGGER = Logger.getLogger(App.class);
+ private static void deleteSchema(DataSource dataSource) throws SQLException {
+ try (Connection connection = dataSource.getConnection();
+ Statement statement = connection.createStatement()) {
+ statement.execute(CustomerSchemaSql.DELETE_SCHEMA_SQL);
+ }
+ }
- /**
- * Program entry point.
- *
- * @param args command line args.
- */
- public static void main(final String[] args) {
- final CustomerDaoImpl customerDao = new CustomerDaoImpl(generateSampleCustomers());
- LOGGER.info("customerDao.getAllCustomers(): " + customerDao.getAllCustomers());
- LOGGER.info("customerDao.getCusterById(2): " + customerDao.getCustomerById(2));
- final Customer customer = new Customer(4, "Dan", "Danson");
- customerDao.addCustomer(customer);
- LOGGER.info("customerDao.getAllCustomers(): " + customerDao.getAllCustomers());
- customer.setFirstName("Daniel");
- customer.setLastName("Danielson");
- customerDao.updateCustomer(customer);
- LOGGER.info("customerDao.getAllCustomers(): " + customerDao.getAllCustomers());
- customerDao.deleteCustomer(customer);
- LOGGER.info("customerDao.getAllCustomers(): " + customerDao.getAllCustomers());
- }
+ private static void createSchema(DataSource dataSource) throws SQLException {
+ try (Connection connection = dataSource.getConnection();
+ Statement statement = connection.createStatement()) {
+ statement.execute(CustomerSchemaSql.CREATE_SCHEMA_SQL);
+ }
+ }
- /**
- * Generate customers.
- *
- * @return list of customers.
- */
- public static List generateSampleCustomers() {
- final Customer customer1 = new Customer(1, "Adam", "Adamson");
- final Customer customer2 = new Customer(2, "Bob", "Bobson");
- final Customer customer3 = new Customer(3, "Carl", "Carlson");
- final List customers = new ArrayList();
- customers.add(customer1);
- customers.add(customer2);
- customers.add(customer3);
- return customers;
- }
+ private static DataSource createDataSource() {
+ JdbcDataSource dataSource = new JdbcDataSource();
+ dataSource.setURL(DB_URL);
+ return dataSource;
+ }
+
+ private static void performOperationsUsing(final CustomerDao customerDao) throws Exception {
+ addCustomers(customerDao);
+ log.info("customerDao.getAllCustomers(): ");
+ try (Stream customerStream = customerDao.getAll()) {
+ customerStream.forEach((customer) -> log.info(customer));
+ }
+ log.info("customerDao.getCustomerById(2): " + customerDao.getById(2));
+ final Customer customer = new Customer(4, "Dan", "Danson");
+ customerDao.add(customer);
+ log.info("customerDao.getAllCustomers(): " + customerDao.getAll());
+ customer.setFirstName("Daniel");
+ customer.setLastName("Danielson");
+ customerDao.update(customer);
+ log.info("customerDao.getAllCustomers(): ");
+ try (Stream customerStream = customerDao.getAll()) {
+ customerStream.forEach((cust) -> log.info(cust));
+ }
+ customerDao.delete(customer);
+ log.info("customerDao.getAllCustomers(): " + customerDao.getAll());
+ }
+
+ private static void addCustomers(CustomerDao customerDao) throws Exception {
+ for (Customer customer : generateSampleCustomers()) {
+ customerDao.add(customer);
+ }
+ }
+
+ /**
+ * Generate customers.
+ *
+ * @return list of customers.
+ */
+ public static List generateSampleCustomers() {
+ final Customer customer1 = new Customer(1, "Adam", "Adamson");
+ final Customer customer2 = new Customer(2, "Bob", "Bobson");
+ final Customer customer3 = new Customer(3, "Carl", "Carlson");
+ final List customers = new ArrayList<>();
+ customers.add(customer1);
+ customers.add(customer2);
+ customers.add(customer3);
+ return customers;
+ }
}
diff --git a/dao/src/main/java/com/iluwatar/dao/Customer.java b/dao/src/main/java/com/iluwatar/dao/Customer.java
index e6d7f7763..d6b512dd6 100644
--- a/dao/src/main/java/com/iluwatar/dao/Customer.java
+++ b/dao/src/main/java/com/iluwatar/dao/Customer.java
@@ -1,8 +1,30 @@
+/**
+ * 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.dao;
/**
- *
- * Customer
+ * A customer POJO that represents the data that will be read from the data source.
*
*/
public class Customer {
@@ -11,6 +33,9 @@ public class Customer {
private String firstName;
private String lastName;
+ /**
+ * Creates an instance of customer.
+ */
public Customer(final int id, final String firstName, final String lastName) {
this.id = id;
this.firstName = firstName;
@@ -48,21 +73,21 @@ public class Customer {
}
@Override
- public boolean equals(final Object o) {
+ public boolean equals(final Object that) {
boolean isEqual = false;
- if (this == o) {
+ if (this == that) {
isEqual = true;
- } else if (o != null && (getClass() == o.getClass())) {
- final Customer customer = (Customer) o;
- if (getId() == customer.getId())
+ } else if (that != null && getClass() == that.getClass()) {
+ final Customer customer = (Customer) that;
+ if (getId() == customer.getId()) {
isEqual = true;
+ }
}
return isEqual;
}
@Override
public int hashCode() {
- int result = getId();
- return result;
+ return getId();
}
}
diff --git a/dao/src/main/java/com/iluwatar/dao/CustomerDao.java b/dao/src/main/java/com/iluwatar/dao/CustomerDao.java
index 79d23ba20..059a9e9f7 100644
--- a/dao/src/main/java/com/iluwatar/dao/CustomerDao.java
+++ b/dao/src/main/java/com/iluwatar/dao/CustomerDao.java
@@ -1,21 +1,81 @@
+/**
+ * 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.dao;
-import java.util.List;
+import java.util.Optional;
+import java.util.stream.Stream;
/**
+ * In an application the Data Access Object (DAO) is a part of Data access layer. It is an object
+ * that provides an interface to some type of persistence mechanism. By mapping application calls
+ * to the persistence layer, DAO provides some specific data operations without exposing details
+ * of the database. This isolation supports the Single responsibility principle. It separates what
+ * data accesses the application needs, in terms of domain-specific objects and data types
+ * (the public interface of the DAO), from how these needs can be satisfied with a specific DBMS,
+ * database schema, etc.
*
- * CustomerDao
- *
+ * Any change in the way data is stored and retrieved will not change the client code as the
+ * client will be using interface and need not worry about exact source.
+ *
+ * @see InMemoryCustomerDao
+ * @see DbCustomerDao
*/
public interface CustomerDao {
- List getAllCustomers();
+ /**
+ * @return all the customers as a stream. The stream may be lazily or eagerly evaluated based
+ * on the implementation. The stream must be closed after use.
+ * @throws Exception if any error occurs.
+ */
+ Stream getAll() throws Exception;
+
+ /**
+ * @param id unique identifier of the customer.
+ * @return an optional with customer if a customer with unique identifier id
+ * exists, empty optional otherwise.
+ * @throws Exception if any error occurs.
+ */
+ Optional getById(int id) throws Exception;
- Customer getCustomerById(int id);
+ /**
+ * @param customer the customer to be added.
+ * @return true if customer is successfully added, false if customer already exists.
+ * @throws Exception if any error occurs.
+ */
+ boolean add(Customer customer) throws Exception;
- void addCustomer(Customer customer);
+ /**
+ * @param customer the customer to be updated.
+ * @return true if customer exists and is successfully updated, false otherwise.
+ * @throws Exception if any error occurs.
+ */
+ boolean update(Customer customer) throws Exception;
- void updateCustomer(Customer customer);
-
- void deleteCustomer(Customer customer);
+ /**
+ * @param customer the customer to be deleted.
+ * @return true if customer exists and is successfully deleted, false otherwise.
+ * @throws Exception if any error occurs.
+ */
+ boolean delete(Customer customer) throws Exception;
}
diff --git a/dao/src/main/java/com/iluwatar/dao/CustomerDaoImpl.java b/dao/src/main/java/com/iluwatar/dao/CustomerDaoImpl.java
deleted file mode 100644
index e590fb1a6..000000000
--- a/dao/src/main/java/com/iluwatar/dao/CustomerDaoImpl.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package com.iluwatar.dao;
-
-import java.util.List;
-
-/**
- *
- * The data access object (DAO) is an object that provides an abstract interface to some type of
- * database or other persistence mechanism. By mapping application calls to the persistence layer,
- * DAO provide some specific data operations without exposing details of the database. This
- * isolation supports the Single responsibility principle. It separates what data accesses the
- * application needs, in terms of domain-specific objects and data types (the public interface of
- * the DAO), from how these needs can be satisfied with a specific DBMS, database schema, etc.
- *
- */
-public class CustomerDaoImpl implements CustomerDao {
-
- // Represents the DB structure for our example so we don't have to managed it ourselves
- // Note: Normally this would be in the form of an actual database and not part of the Dao Impl.
- private List customers;
-
- public CustomerDaoImpl(final List customers) {
- this.customers = customers;
- }
-
- @Override
- public List getAllCustomers() {
- return customers;
- }
-
- @Override
- public Customer getCustomerById(final int id) {
- Customer customer = null;
- for (final Customer cus : getAllCustomers()) {
- if (cus.getId() == id) {
- customer = cus;
- break;
- }
- }
- return customer;
- }
-
- @Override
- public void addCustomer(final Customer customer) {
- if (getCustomerById(customer.getId()) == null) {
- customers.add(customer);
- }
- }
-
-
- @Override
- public void updateCustomer(final Customer customer) {
- if (getAllCustomers().contains(customer)) {
- final int index = getAllCustomers().indexOf(customer);
- getAllCustomers().set(index, customer);
- }
- }
-
- @Override
- public void deleteCustomer(final Customer customer) {
- getAllCustomers().remove(customer);
- }
-}
diff --git a/dao/src/main/java/com/iluwatar/dao/CustomerSchemaSql.java b/dao/src/main/java/com/iluwatar/dao/CustomerSchemaSql.java
new file mode 100644
index 000000000..860826abf
--- /dev/null
+++ b/dao/src/main/java/com/iluwatar/dao/CustomerSchemaSql.java
@@ -0,0 +1,31 @@
+/**
+ * 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.dao;
+
+public interface CustomerSchemaSql {
+
+ String CREATE_SCHEMA_SQL = "CREATE TABLE CUSTOMERS (ID NUMBER, FNAME VARCHAR(100), "
+ + "LNAME VARCHAR(100))";
+
+ String DELETE_SCHEMA_SQL = "DROP TABLE CUSTOMERS";
+}
diff --git a/dao/src/main/java/com/iluwatar/dao/DbCustomerDao.java b/dao/src/main/java/com/iluwatar/dao/DbCustomerDao.java
new file mode 100644
index 000000000..622b5b1f0
--- /dev/null
+++ b/dao/src/main/java/com/iluwatar/dao/DbCustomerDao.java
@@ -0,0 +1,183 @@
+/**
+ * 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.dao;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Optional;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.function.Consumer;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
+import javax.sql.DataSource;
+
+/**
+ * An implementation of {@link CustomerDao} that persists customers in RDBMS.
+ *
+ */
+public class DbCustomerDao implements CustomerDao {
+
+ private final DataSource dataSource;
+
+ /**
+ * Creates an instance of {@link DbCustomerDao} which uses provided dataSource
+ * to store and retrieve customer information.
+ *
+ * @param dataSource a non-null dataSource.
+ */
+ public DbCustomerDao(DataSource dataSource) {
+ this.dataSource = dataSource;
+ }
+
+ /**
+ * @return a lazily populated stream of customers. Note the stream returned must be closed to
+ * free all the acquired resources. The stream keeps an open connection to the database till
+ * it is complete or is closed manually.
+ */
+ @Override
+ public Stream getAll() throws Exception {
+
+ Connection connection;
+ try {
+ connection = getConnection();
+ PreparedStatement statement = connection.prepareStatement("SELECT * FROM CUSTOMERS");
+ ResultSet resultSet = statement.executeQuery();
+ return StreamSupport.stream(new Spliterators.AbstractSpliterator(Long.MAX_VALUE,
+ Spliterator.ORDERED) {
+
+ @Override
+ public boolean tryAdvance(Consumer super Customer> action) {
+ try {
+ if (!resultSet.next()) {
+ return false;
+ }
+ action.accept(createCustomer(resultSet));
+ return true;
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }, false).onClose(() -> mutedClose(connection));
+ } catch (SQLException e) {
+ throw new Exception(e.getMessage(), e);
+ }
+ }
+
+ private Connection getConnection() throws SQLException {
+ return dataSource.getConnection();
+ }
+
+ private void mutedClose(Connection connection) {
+ try {
+ connection.close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private Customer createCustomer(ResultSet resultSet) throws SQLException {
+ return new Customer(resultSet.getInt("ID"),
+ resultSet.getString("FNAME"),
+ resultSet.getString("LNAME"));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Optional getById(int id) throws Exception {
+ try (Connection connection = getConnection();
+ PreparedStatement statement =
+ connection.prepareStatement("SELECT * FROM CUSTOMERS WHERE ID = ?")) {
+
+ statement.setInt(1, id);
+ ResultSet resultSet = statement.executeQuery();
+ if (resultSet.next()) {
+ return Optional.of(createCustomer(resultSet));
+ } else {
+ return Optional.empty();
+ }
+ } catch (SQLException ex) {
+ throw new Exception(ex.getMessage(), ex);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean add(Customer customer) throws Exception {
+ if (getById(customer.getId()).isPresent()) {
+ return false;
+ }
+
+ try (Connection connection = getConnection();
+ PreparedStatement statement =
+ connection.prepareStatement("INSERT INTO CUSTOMERS VALUES (?,?,?)")) {
+ statement.setInt(1, customer.getId());
+ statement.setString(2, customer.getFirstName());
+ statement.setString(3, customer.getLastName());
+ statement.execute();
+ return true;
+ } catch (SQLException ex) {
+ throw new Exception(ex.getMessage(), ex);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean update(Customer customer) throws Exception {
+ try (Connection connection = getConnection();
+ PreparedStatement statement =
+ connection.prepareStatement("UPDATE CUSTOMERS SET FNAME = ?, LNAME = ? WHERE ID = ?")) {
+ statement.setString(1, customer.getFirstName());
+ statement.setString(2, customer.getLastName());
+ statement.setInt(3, customer.getId());
+ return statement.executeUpdate() > 0;
+ } catch (SQLException ex) {
+ throw new Exception(ex.getMessage(), ex);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean delete(Customer customer) throws Exception {
+ try (Connection connection = getConnection();
+ PreparedStatement statement =
+ connection.prepareStatement("DELETE FROM CUSTOMERS WHERE ID = ?")) {
+ statement.setInt(1, customer.getId());
+ return statement.executeUpdate() > 0;
+ } catch (SQLException ex) {
+ throw new Exception(ex.getMessage(), ex);
+ }
+ }
+}
diff --git a/dao/src/main/java/com/iluwatar/dao/InMemoryCustomerDao.java b/dao/src/main/java/com/iluwatar/dao/InMemoryCustomerDao.java
new file mode 100644
index 000000000..15c63d1de
--- /dev/null
+++ b/dao/src/main/java/com/iluwatar/dao/InMemoryCustomerDao.java
@@ -0,0 +1,73 @@
+/**
+ * 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.dao;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Stream;
+
+/**
+ * An in memory implementation of {@link CustomerDao}, which stores the customers in JVM memory
+ * and data is lost when the application exits.
+ *
+ * This implementation is useful as temporary database or for testing.
+ */
+public class InMemoryCustomerDao implements CustomerDao {
+
+ private Map idToCustomer = new HashMap<>();
+
+ /**
+ * An eagerly evaluated stream of customers stored in memory.
+ */
+ @Override
+ public Stream getAll() {
+ return idToCustomer.values().stream();
+ }
+
+ @Override
+ public Optional getById(final int id) {
+ return Optional.ofNullable(idToCustomer.get(id));
+ }
+
+ @Override
+ public boolean add(final Customer customer) {
+ if (getById(customer.getId()).isPresent()) {
+ return false;
+ }
+
+ idToCustomer.put(customer.getId(), customer);
+ return true;
+ }
+
+ @Override
+ public boolean update(final Customer customer) {
+ return idToCustomer.replace(customer.getId(), customer) != null;
+ }
+
+ @Override
+ public boolean delete(final Customer customer) {
+ return idToCustomer.remove(customer.getId()) != null;
+ }
+}
diff --git a/dao/src/main/resources/log4j.xml b/dao/src/main/resources/log4j.xml
new file mode 100644
index 000000000..b591c17e1
--- /dev/null
+++ b/dao/src/main/resources/log4j.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/dao/src/test/java/com/iluwatar/dao/AppTest.java b/dao/src/test/java/com/iluwatar/dao/AppTest.java
new file mode 100644
index 000000000..169fc046e
--- /dev/null
+++ b/dao/src/test/java/com/iluwatar/dao/AppTest.java
@@ -0,0 +1,37 @@
+/**
+ * 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.dao;
+
+import org.junit.Test;
+
+/**
+ * Tests that DAO example runs without errors.
+ */
+public class AppTest {
+ @Test
+ public void test() throws Exception {
+ String[] args = {};
+ App.main(args);
+ }
+}
diff --git a/dao/src/test/java/com/iluwatar/dao/CustomerDaoImplTest.java b/dao/src/test/java/com/iluwatar/dao/CustomerDaoImplTest.java
deleted file mode 100644
index 230314d80..000000000
--- a/dao/src/test/java/com/iluwatar/dao/CustomerDaoImplTest.java
+++ /dev/null
@@ -1,99 +0,0 @@
-package com.iluwatar.dao;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.junit.Before;
-import org.junit.Test;
-
-public class CustomerDaoImplTest {
-
- private CustomerDaoImpl impl;
- private List customers;
- private static final Customer CUSTOMER = new Customer(1, "Freddy", "Kruger");
-
- @Before
- public void setUp() {
- customers = new ArrayList();
- customers.add(CUSTOMER);
- impl = new CustomerDaoImpl(customers);
- }
-
- @Test
- public void deleteExistingCustomer() {
- assertEquals(1, impl.getAllCustomers().size());
- impl.deleteCustomer(CUSTOMER);
- assertTrue(impl.getAllCustomers().isEmpty());
- }
-
- @Test
- public void deleteNonExistingCustomer() {
- final Customer nonExistingCustomer = new Customer(2, "Robert", "Englund");
- impl.deleteCustomer(nonExistingCustomer);
- assertEquals(1, impl.getAllCustomers().size());
- }
-
- @Test
- public void updateExistingCustomer() {
- final String newFirstname = "Bernard";
- final String newLastname = "Montgomery";
- final Customer customer = new Customer(CUSTOMER.getId(), newFirstname, newLastname);
- impl.updateCustomer(customer);
- final Customer cust = impl.getCustomerById(CUSTOMER.getId());
- assertEquals(newFirstname, cust.getFirstName());
- assertEquals(newLastname, cust.getLastName());
- }
-
- @Test
- public void updateNonExistingCustomer() {
- final int nonExistingId = getNonExistingCustomerId();
- final String newFirstname = "Douglas";
- final String newLastname = "MacArthur";
- final Customer customer = new Customer(nonExistingId, newFirstname, newLastname);
- impl.updateCustomer(customer);
- assertNull(impl.getCustomerById(nonExistingId));
- final Customer existingCustomer = impl.getCustomerById(CUSTOMER.getId());
- assertEquals(CUSTOMER.getFirstName(), existingCustomer.getFirstName());
- assertEquals(CUSTOMER.getLastName(), existingCustomer.getLastName());
- }
-
- @Test
- public void addCustomer() {
- final Customer newCustomer = new Customer(3, "George", "Patton");
- impl.addCustomer(newCustomer);
- assertEquals(2, impl.getAllCustomers().size());
- }
-
- @Test
- public void addAlreadyAddedCustomer() {
- final Customer newCustomer = new Customer(3, "George", "Patton");
- impl.addCustomer(newCustomer);
- assertEquals(2, impl.getAllCustomers().size());
- impl.addCustomer(newCustomer);
- assertEquals(2, impl.getAllCustomers().size());
- }
-
- @Test
- public void getExistinCustomerById() {
- assertEquals(CUSTOMER, impl.getCustomerById(CUSTOMER.getId()));
- }
-
- @Test
- public void getNonExistinCustomerById() {
- final int nonExistingId = getNonExistingCustomerId();
- assertNull(impl.getCustomerById(nonExistingId));
- }
-
- /**
- * An arbitrary number which does not correspond to an active Customer id.
- *
- * @return an int of a customer id which doesn't exist
- */
- private int getNonExistingCustomerId() {
- return 999;
- }
-}
diff --git a/dao/src/test/java/com/iluwatar/dao/CustomerTest.java b/dao/src/test/java/com/iluwatar/dao/CustomerTest.java
index 8511a577b..6a02fd6be 100644
--- a/dao/src/test/java/com/iluwatar/dao/CustomerTest.java
+++ b/dao/src/test/java/com/iluwatar/dao/CustomerTest.java
@@ -1,3 +1,26 @@
+/**
+ * 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.dao;
import static org.junit.Assert.assertEquals;
@@ -63,12 +86,12 @@ public class CustomerTest {
@Test
public void testToString() {
final StringBuffer buffer = new StringBuffer();
- buffer.append("Customer{id=");
- buffer.append("" + customer.getId());
- buffer.append(", firstName='");
- buffer.append(customer.getFirstName());
- buffer.append("\', lastName='");
- buffer.append(customer.getLastName() + "\'}");
+ buffer.append("Customer{id=")
+ .append("" + customer.getId())
+ .append(", firstName='")
+ .append(customer.getFirstName())
+ .append("\', lastName='")
+ .append(customer.getLastName() + "\'}");
assertEquals(buffer.toString(), customer.toString());
}
}
diff --git a/dao/src/test/java/com/iluwatar/dao/DbCustomerDaoTest.java b/dao/src/test/java/com/iluwatar/dao/DbCustomerDaoTest.java
new file mode 100644
index 000000000..ac69699df
--- /dev/null
+++ b/dao/src/test/java/com/iluwatar/dao/DbCustomerDaoTest.java
@@ -0,0 +1,269 @@
+/**
+ * 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.dao;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.stream.Stream;
+
+import javax.sql.DataSource;
+
+import org.h2.jdbcx.JdbcDataSource;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+
+import de.bechte.junit.runners.context.HierarchicalContextRunner;
+
+/**
+ * Tests {@link DbCustomerDao}.
+ */
+@RunWith(HierarchicalContextRunner.class)
+public class DbCustomerDaoTest {
+
+ private static final String DB_URL = "jdbc:h2:~/dao";
+ private DbCustomerDao dao;
+ private Customer existingCustomer = new Customer(1, "Freddy", "Krueger");
+
+ /**
+ * Creates customers schema.
+ * @throws SQLException if there is any error while creating schema.
+ */
+ @Before
+ public void createSchema() throws SQLException {
+ try (Connection connection = DriverManager.getConnection(DB_URL);
+ Statement statement = connection.createStatement()) {
+ statement.execute(CustomerSchemaSql.CREATE_SCHEMA_SQL);
+ }
+ }
+
+ /**
+ * Represents the scenario where DB connectivity is present.
+ */
+ public class ConnectionSuccess {
+
+ /**
+ * Setup for connection success scenario.
+ * @throws Exception if any error occurs.
+ */
+ @Before
+ public void setUp() throws Exception {
+ JdbcDataSource dataSource = new JdbcDataSource();
+ dataSource.setURL(DB_URL);
+ dao = new DbCustomerDao(dataSource);
+ boolean result = dao.add(existingCustomer);
+ assertTrue(result);
+ }
+
+ /**
+ * Represents the scenario when DAO operations are being performed on a non existing customer.
+ */
+ public class NonExistingCustomer {
+
+ @Test
+ public void addingShouldResultInSuccess() throws Exception {
+ try (Stream allCustomers = dao.getAll()) {
+ assumeTrue(allCustomers.count() == 1);
+ }
+
+ final Customer nonExistingCustomer = new Customer(2, "Robert", "Englund");
+ boolean result = dao.add(nonExistingCustomer);
+ assertTrue(result);
+
+ assertCustomerCountIs(2);
+ assertEquals(nonExistingCustomer, dao.getById(nonExistingCustomer.getId()).get());
+ }
+
+ @Test
+ public void deletionShouldBeFailureAndNotAffectExistingCustomers() throws Exception {
+ final Customer nonExistingCustomer = new Customer(2, "Robert", "Englund");
+ boolean result = dao.delete(nonExistingCustomer);
+
+ assertFalse(result);
+ assertCustomerCountIs(1);
+ }
+
+ @Test
+ public void updationShouldBeFailureAndNotAffectExistingCustomers() throws Exception {
+ final int nonExistingId = getNonExistingCustomerId();
+ final String newFirstname = "Douglas";
+ final String newLastname = "MacArthur";
+ final Customer customer = new Customer(nonExistingId, newFirstname, newLastname);
+ boolean result = dao.update(customer);
+
+ assertFalse(result);
+ assertFalse(dao.getById(nonExistingId).isPresent());
+ }
+
+ @Test
+ public void retrieveShouldReturnNoCustomer() throws Exception {
+ assertFalse(dao.getById(getNonExistingCustomerId()).isPresent());
+ }
+ }
+
+ /**
+ * Represents a scenario where DAO operations are being performed on an already existing
+ * customer.
+ *
+ */
+ public class ExistingCustomer {
+
+ @Test
+ public void addingShouldResultInFailureAndNotAffectExistingCustomers() throws Exception {
+ Customer existingCustomer = new Customer(1, "Freddy", "Krueger");
+
+ boolean result = dao.add(existingCustomer);
+
+ assertFalse(result);
+ assertCustomerCountIs(1);
+ assertEquals(existingCustomer, dao.getById(existingCustomer.getId()).get());
+ }
+
+ @Test
+ public void deletionShouldBeSuccessAndCustomerShouldBeNonAccessible() throws Exception {
+ boolean result = dao.delete(existingCustomer);
+
+ assertTrue(result);
+ assertCustomerCountIs(0);
+ assertFalse(dao.getById(existingCustomer.getId()).isPresent());
+ }
+
+ @Test
+ public void updationShouldBeSuccessAndAccessingTheSameCustomerShouldReturnUpdatedInformation() throws Exception {
+ final String newFirstname = "Bernard";
+ final String newLastname = "Montgomery";
+ final Customer customer = new Customer(existingCustomer.getId(), newFirstname, newLastname);
+ boolean result = dao.update(customer);
+
+ assertTrue(result);
+
+ final Customer cust = dao.getById(existingCustomer.getId()).get();
+ assertEquals(newFirstname, cust.getFirstName());
+ assertEquals(newLastname, cust.getLastName());
+ }
+ }
+ }
+
+ /**
+ * Represents a scenario where DB connectivity is not present due to network issue, or
+ * DB service unavailable.
+ *
+ */
+ public class ConnectivityIssue {
+
+ private static final String EXCEPTION_CAUSE = "Connection not available";
+ @Rule public ExpectedException exception = ExpectedException.none();
+
+ /**
+ * setup a connection failure scenario.
+ * @throws SQLException if any error occurs.
+ */
+ @Before
+ public void setUp() throws SQLException {
+ dao = new DbCustomerDao(mockedDatasource());
+ exception.expect(Exception.class);
+ exception.expectMessage(EXCEPTION_CAUSE);
+ }
+
+ private DataSource mockedDatasource() throws SQLException {
+ DataSource mockedDataSource = mock(DataSource.class);
+ Connection mockedConnection = mock(Connection.class);
+ SQLException exception = new SQLException(EXCEPTION_CAUSE);
+ doThrow(exception).when(mockedConnection).prepareStatement(Mockito.anyString());
+ doReturn(mockedConnection).when(mockedDataSource).getConnection();
+ return mockedDataSource;
+ }
+
+ @Test
+ public void addingACustomerFailsWithExceptionAsFeedbackToClient() throws Exception {
+ dao.add(new Customer(2, "Bernard", "Montgomery"));
+ }
+
+ @Test
+ public void deletingACustomerFailsWithExceptionAsFeedbackToTheClient() throws Exception {
+ dao.delete(existingCustomer);
+ }
+
+ @Test
+ public void updatingACustomerFailsWithFeedbackToTheClient() throws Exception {
+ final String newFirstname = "Bernard";
+ final String newLastname = "Montgomery";
+
+ dao.update(new Customer(existingCustomer.getId(), newFirstname, newLastname));
+ }
+
+ @Test
+ public void retrievingACustomerByIdFailsWithExceptionAsFeedbackToClient() throws Exception {
+ dao.getById(existingCustomer.getId());
+ }
+
+ @Test
+ public void retrievingAllCustomersFailsWithExceptionAsFeedbackToClient() throws Exception {
+ dao.getAll();
+ }
+
+ }
+
+ /**
+ * Delete customer schema for fresh setup per test.
+ * @throws SQLException if any error occurs.
+ */
+ @After
+ public void deleteSchema() throws SQLException {
+ try (Connection connection = DriverManager.getConnection(DB_URL);
+ Statement statement = connection.createStatement()) {
+ statement.execute(CustomerSchemaSql.DELETE_SCHEMA_SQL);
+ }
+ }
+
+ private void assertCustomerCountIs(int count) throws Exception {
+ try (Stream allCustomers = dao.getAll()) {
+ assertTrue(allCustomers.count() == count);
+ }
+ }
+
+
+ /**
+ * An arbitrary number which does not correspond to an active Customer id.
+ *
+ * @return an int of a customer id which doesn't exist
+ */
+ private int getNonExistingCustomerId() {
+ return 999;
+ }
+}
diff --git a/dao/src/test/java/com/iluwatar/dao/InMemoryCustomerDaoTest.java b/dao/src/test/java/com/iluwatar/dao/InMemoryCustomerDaoTest.java
new file mode 100644
index 000000000..65a087b9b
--- /dev/null
+++ b/dao/src/test/java/com/iluwatar/dao/InMemoryCustomerDaoTest.java
@@ -0,0 +1,164 @@
+/**
+ * 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.dao;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
+
+import java.util.Optional;
+import java.util.stream.Stream;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import de.bechte.junit.runners.context.HierarchicalContextRunner;
+
+/**
+ * Tests {@link InMemoryCustomerDao}.
+ */
+@RunWith(HierarchicalContextRunner.class)
+public class InMemoryCustomerDaoTest {
+
+ private InMemoryCustomerDao dao;
+ private static final Customer CUSTOMER = new Customer(1, "Freddy", "Krueger");
+
+ @Before
+ public void setUp() {
+ dao = new InMemoryCustomerDao();
+ assertTrue(dao.add(CUSTOMER));
+ }
+
+ /**
+ * Represents the scenario when the DAO operations are being performed on a non existent
+ * customer.
+ */
+ public class NonExistingCustomer {
+
+ @Test
+ public void addingShouldResultInSuccess() throws Exception {
+ try (Stream allCustomers = dao.getAll()) {
+ assumeTrue(allCustomers.count() == 1);
+ }
+
+ final Customer nonExistingCustomer = new Customer(2, "Robert", "Englund");
+ boolean result = dao.add(nonExistingCustomer);
+ assertTrue(result);
+
+ assertCustomerCountIs(2);
+ assertEquals(nonExistingCustomer, dao.getById(nonExistingCustomer.getId()).get());
+ }
+
+ @Test
+ public void deletionShouldBeFailureAndNotAffectExistingCustomers() throws Exception {
+ final Customer nonExistingCustomer = new Customer(2, "Robert", "Englund");
+ boolean result = dao.delete(nonExistingCustomer);
+
+ assertFalse(result);
+ assertCustomerCountIs(1);
+ }
+
+ @Test
+ public void updationShouldBeFailureAndNotAffectExistingCustomers() throws Exception {
+ final int nonExistingId = getNonExistingCustomerId();
+ final String newFirstname = "Douglas";
+ final String newLastname = "MacArthur";
+ final Customer customer = new Customer(nonExistingId, newFirstname, newLastname);
+ boolean result = dao.update(customer);
+
+ assertFalse(result);
+ assertFalse(dao.getById(nonExistingId).isPresent());
+ }
+
+ @Test
+ public void retrieveShouldReturnNoCustomer() throws Exception {
+ assertFalse(dao.getById(getNonExistingCustomerId()).isPresent());
+ }
+ }
+
+ /**
+ * Represents the scenario when the DAO operations are being performed on an already existing
+ * customer.
+ */
+ public class ExistingCustomer {
+
+ @Test
+ public void addingShouldResultInFailureAndNotAffectExistingCustomers() throws Exception {
+ boolean result = dao.add(CUSTOMER);
+
+ assertFalse(result);
+ assertCustomerCountIs(1);
+ assertEquals(CUSTOMER, dao.getById(CUSTOMER.getId()).get());
+ }
+
+ @Test
+ public void deletionShouldBeSuccessAndCustomerShouldBeNonAccessible() throws Exception {
+ boolean result = dao.delete(CUSTOMER);
+
+ assertTrue(result);
+ assertCustomerCountIs(0);
+ assertFalse(dao.getById(CUSTOMER.getId()).isPresent());
+ }
+
+ @Test
+ public void updationShouldBeSuccessAndAccessingTheSameCustomerShouldReturnUpdatedInformation() throws Exception {
+ final String newFirstname = "Bernard";
+ final String newLastname = "Montgomery";
+ final Customer customer = new Customer(CUSTOMER.getId(), newFirstname, newLastname);
+ boolean result = dao.update(customer);
+
+ assertTrue(result);
+
+ final Customer cust = dao.getById(CUSTOMER.getId()).get();
+ assertEquals(newFirstname, cust.getFirstName());
+ assertEquals(newLastname, cust.getLastName());
+ }
+
+ @Test
+ public void retriveShouldReturnTheCustomer() {
+ Optional optionalCustomer = dao.getById(CUSTOMER.getId());
+
+ assertTrue(optionalCustomer.isPresent());
+ assertEquals(CUSTOMER, optionalCustomer.get());
+ }
+ }
+
+ /**
+ * An arbitrary number which does not correspond to an active Customer id.
+ *
+ * @return an int of a customer id which doesn't exist
+ */
+ private int getNonExistingCustomerId() {
+ return 999;
+ }
+
+ private void assertCustomerCountIs(int count) throws Exception {
+ try (Stream allCustomers = dao.getAll()) {
+ assertTrue(allCustomers.count() == count);
+ }
+ }
+}
diff --git a/dao/src/test/resources/log4j.xml b/dao/src/test/resources/log4j.xml
deleted file mode 100644
index 136817f50..000000000
--- a/dao/src/test/resources/log4j.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/data-mapper/etc/data-mapper.png b/data-mapper/etc/data-mapper.png
new file mode 100644
index 000000000..bcda8054a
Binary files /dev/null and b/data-mapper/etc/data-mapper.png differ
diff --git a/data-mapper/etc/data-mapper.ucls b/data-mapper/etc/data-mapper.ucls
new file mode 100644
index 000000000..2467983ce
--- /dev/null
+++ b/data-mapper/etc/data-mapper.ucls
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/data-mapper/index.md b/data-mapper/index.md
new file mode 100644
index 000000000..075e8eece
--- /dev/null
+++ b/data-mapper/index.md
@@ -0,0 +1,25 @@
+---
+layout: pattern
+title: Data Mapper
+folder: data-mapper
+permalink: /patterns/data-mapper/
+categories: Persistence Tier
+tags:
+ - Java
+ - Difficulty-Beginner
+---
+
+## Intent
+A layer of mappers that moves data between objects and a database while keeping them independent of each other and the mapper itself
+
+
+
+## Applicability
+Use the Data Mapper in any of the following situations
+
+* when you want to decouple data objects from DB access layer
+* when you want to write multiple data retrieval/persistence implementations
+
+## Credits
+
+* [Data Mapper](http://richard.jp.leguen.ca/tutoring/soen343-f2010/tutorials/implementing-data-mapper/)
diff --git a/data-mapper/pom.xml b/data-mapper/pom.xml
new file mode 100644
index 000000000..7d1b83469
--- /dev/null
+++ b/data-mapper/pom.xml
@@ -0,0 +1,45 @@
+
+
+
+ 4.0.0
+
+ com.iluwatar
+ java-design-patterns
+ 1.13.0-SNAPSHOT
+
+ data-mapper
+
+
+ junit
+ junit
+ test
+
+
+ log4j
+ log4j
+
+
+
diff --git a/data-mapper/src/main/java/com/iluwatar/datamapper/App.java b/data-mapper/src/main/java/com/iluwatar/datamapper/App.java
new file mode 100644
index 000000000..5fcd0d9ea
--- /dev/null
+++ b/data-mapper/src/main/java/com/iluwatar/datamapper/App.java
@@ -0,0 +1,77 @@
+/**
+ * The MIT License Copyright (c) 2016 Amit Dixit
+ *
+ * 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.datamapper;
+
+import java.util.Optional;
+
+import org.apache.log4j.Logger;
+
+/**
+ * The Data Mapper (DM) is a layer of software that separates the in-memory objects from the
+ * database. Its responsibility is to transfer data between the two and also to isolate them from
+ * each other. With Data Mapper the in-memory objects needn't know even that there's a database
+ * present; they need no SQL interface code, and certainly no knowledge of the database schema. (The
+ * database schema is always ignorant of the objects that use it.) Since it's a form of Mapper ,
+ * Data Mapper itself is even unknown to the domain layer.
+ *
+ * The below example demonstrates basic CRUD operations: Create, Read, Update, and Delete.
+ *
+ */
+public final class App {
+
+ private static Logger log = Logger.getLogger(App.class);
+
+ /**
+ * Program entry point.
+ *
+ * @param args command line args.
+ */
+ public static void main(final String... args) {
+
+ /* Create new data mapper for type 'first' */
+ final StudentDataMapper mapper = new StudentDataMapperImpl();
+
+ /* Create new student */
+ Student student = new Student(1, "Adam", 'A');
+
+ /* Add student in respectibe store */
+ mapper.insert(student);
+
+ log.debug("App.main(), student : " + student + ", is inserted");
+
+ /* Find this student */
+ final Optional studentToBeFound = mapper.find(student.getStudentId());
+
+ log.debug("App.main(), student : " + studentToBeFound + ", is searched");
+
+ /* Update existing student object */
+ student = new Student(student.getStudentId(), "AdamUpdated", 'A');
+
+ /* Update student in respectibe db */
+ mapper.update(student);
+
+ log.debug("App.main(), student : " + student + ", is updated");
+ log.debug("App.main(), student : " + student + ", is going to be deleted");
+
+ /* Delete student in db */
+ mapper.delete(student);
+ }
+
+ private App() {}
+}
diff --git a/data-mapper/src/main/java/com/iluwatar/datamapper/DataMapperException.java b/data-mapper/src/main/java/com/iluwatar/datamapper/DataMapperException.java
new file mode 100644
index 000000000..a6995b06d
--- /dev/null
+++ b/data-mapper/src/main/java/com/iluwatar/datamapper/DataMapperException.java
@@ -0,0 +1,42 @@
+/**
+ * The MIT License Copyright (c) 2016 Amit Dixit
+ *
+ * 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.datamapper;
+
+/**
+ * Using Runtime Exception for avoiding dependancy on implementation exceptions. This helps in
+ * decoupling.
+ *
+ * @author amit.dixit
+ *
+ */
+public final class DataMapperException extends RuntimeException {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Constructs a new runtime exception with the specified detail message. The cause is not
+ * initialized, and may subsequently be initialized by a call to {@link #initCause}.
+ *
+ * @param message the detail message. The detail message is saved for later retrieval by the
+ * {@link #getMessage()} method.
+ */
+ public DataMapperException(final String message) {
+ super(message);
+ }
+}
diff --git a/data-mapper/src/main/java/com/iluwatar/datamapper/Student.java b/data-mapper/src/main/java/com/iluwatar/datamapper/Student.java
new file mode 100644
index 000000000..0164533c8
--- /dev/null
+++ b/data-mapper/src/main/java/com/iluwatar/datamapper/Student.java
@@ -0,0 +1,139 @@
+/**
+ * The MIT License Copyright (c) 2016 Amit Dixit
+ *
+ * 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.datamapper;
+
+
+import java.io.Serializable;
+
+public final class Student implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private int studentId;
+ private String name;
+ private char grade;
+
+
+ /**
+ * Use this constructor to create a Student with all details
+ *
+ * @param studentId as unique student id
+ * @param name as student name
+ * @param grade as respective grade of student
+ */
+ public Student(final int studentId, final String name, final char grade) {
+ super();
+
+ this.studentId = studentId;
+ this.name = name;
+ this.grade = grade;
+ }
+
+ /**
+ *
+ * @return the student id
+ */
+ public int getStudentId() {
+ return studentId;
+ }
+
+ /**
+ *
+ * @param studentId as unique student id
+ */
+ public void setStudentId(final int studentId) {
+ this.studentId = studentId;
+ }
+
+ /**
+ *
+ * @return name of student
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ *
+ * @param name as 'name' of student
+ */
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ /**
+ *
+ * @return grade of student
+ */
+ public char getGrade() {
+ return grade;
+ }
+
+ /**
+ *
+ * @param grade as 'grade of student'
+ */
+ public void setGrade(final char grade) {
+ this.grade = grade;
+ }
+
+ /**
+ *
+ */
+ @Override
+ public boolean equals(final Object inputObject) {
+
+ boolean isEqual = false;
+
+ /* Check if both objects are same */
+ if (this == inputObject) {
+
+ isEqual = true;
+ } else if (inputObject != null && getClass() == inputObject.getClass()) {
+
+ final Student inputStudent = (Student) inputObject;
+
+ /* If student id matched */
+ if (this.getStudentId() == inputStudent.getStudentId()) {
+
+ isEqual = true;
+ }
+ }
+
+ return isEqual;
+ }
+
+ /**
+ *
+ */
+ @Override
+ public int hashCode() {
+
+ /* Student id is assumed to be unique */
+ return this.getStudentId();
+ }
+
+ /**
+ *
+ */
+ @Override
+ public String toString() {
+ return "Student [studentId=" + studentId + ", name=" + name + ", grade=" + grade + "]";
+ }
+}
diff --git a/data-mapper/src/main/java/com/iluwatar/datamapper/StudentDataMapper.java b/data-mapper/src/main/java/com/iluwatar/datamapper/StudentDataMapper.java
new file mode 100644
index 000000000..40f0c5c72
--- /dev/null
+++ b/data-mapper/src/main/java/com/iluwatar/datamapper/StudentDataMapper.java
@@ -0,0 +1,32 @@
+/**
+ * The MIT License Copyright (c) 2016 Amit Dixit
+ *
+ * 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.datamapper;
+
+import java.util.Optional;
+
+public interface StudentDataMapper {
+
+ Optional find(int studentId);
+
+ void insert(Student student) throws DataMapperException;
+
+ void update(Student student) throws DataMapperException;
+
+ void delete(Student student) throws DataMapperException;
+}
diff --git a/data-mapper/src/main/java/com/iluwatar/datamapper/StudentDataMapperImpl.java b/data-mapper/src/main/java/com/iluwatar/datamapper/StudentDataMapperImpl.java
new file mode 100644
index 000000000..7ecd9e7f8
--- /dev/null
+++ b/data-mapper/src/main/java/com/iluwatar/datamapper/StudentDataMapperImpl.java
@@ -0,0 +1,102 @@
+/**
+ * The MIT License Copyright (c) 2016 Amit Dixit
+ *
+ * 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.datamapper;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+public final class StudentDataMapperImpl implements StudentDataMapper {
+
+ /* Note: Normally this would be in the form of an actual database */
+ private List students = new ArrayList<>();
+
+ @Override
+ public Optional find(int studentId) {
+
+ /* Compare with existing students */
+ for (final Student student : this.getStudents()) {
+
+ /* Check if student is found */
+ if (student.getStudentId() == studentId) {
+
+ return Optional.of(student);
+ }
+ }
+
+ /* Return empty value */
+ return Optional.empty();
+ }
+
+ @Override
+ public void update(Student studentToBeUpdated) throws DataMapperException {
+
+
+ /* Check with existing students */
+ if (this.getStudents().contains(studentToBeUpdated)) {
+
+ /* Get the index of student in list */
+ final int index = this.getStudents().indexOf(studentToBeUpdated);
+
+ /* Update the student in list */
+ this.getStudents().set(index, studentToBeUpdated);
+
+ } else {
+
+ /* Throw user error after wrapping in a runtime exception */
+ throw new DataMapperException("Student [" + studentToBeUpdated.getName() + "] is not found");
+ }
+ }
+
+ @Override
+ public void insert(Student studentToBeInserted) throws DataMapperException {
+
+ /* Check with existing students */
+ if (!this.getStudents().contains(studentToBeInserted)) {
+
+ /* Add student in list */
+ this.getStudents().add(studentToBeInserted);
+
+ } else {
+
+ /* Throw user error after wrapping in a runtime exception */
+ throw new DataMapperException("Student already [" + studentToBeInserted.getName() + "] exists");
+ }
+ }
+
+ @Override
+ public void delete(Student studentToBeDeleted) throws DataMapperException {
+
+ /* Check with existing students */
+ if (this.getStudents().contains(studentToBeDeleted)) {
+
+ /* Delete the student from list */
+ this.getStudents().remove(studentToBeDeleted);
+
+ } else {
+
+ /* Throw user error after wrapping in a runtime exception */
+ throw new DataMapperException("Student [" + studentToBeDeleted.getName() + "] is not found");
+ }
+ }
+
+ public List getStudents() {
+ return this.students;
+ }
+}
diff --git a/data-mapper/src/main/resources/log4j.xml b/data-mapper/src/main/resources/log4j.xml
new file mode 100644
index 000000000..b591c17e1
--- /dev/null
+++ b/data-mapper/src/main/resources/log4j.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/data-mapper/src/test/java/com/iluwatar/datamapper/AppTest.java b/data-mapper/src/test/java/com/iluwatar/datamapper/AppTest.java
new file mode 100644
index 000000000..f2858100e
--- /dev/null
+++ b/data-mapper/src/test/java/com/iluwatar/datamapper/AppTest.java
@@ -0,0 +1,34 @@
+/**
+ * The MIT License Copyright (c) 2016 Amit Dixit
+ *
+ * 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.datamapper;
+
+import com.iluwatar.datamapper.App;
+import org.junit.Test;
+
+/**
+ * Tests that Data-Mapper example runs without errors.
+ */
+public final class AppTest {
+
+ @Test
+ public void test() {
+ final String[] args = {};
+ App.main(args);
+ }
+}
diff --git a/data-mapper/src/test/java/com/iluwatar/datamapper/DataMapperTest.java b/data-mapper/src/test/java/com/iluwatar/datamapper/DataMapperTest.java
new file mode 100644
index 000000000..17f4d3922
--- /dev/null
+++ b/data-mapper/src/test/java/com/iluwatar/datamapper/DataMapperTest.java
@@ -0,0 +1,73 @@
+/**
+ * The MIT License Copyright (c) 2016 Amit Dixit
+ *
+ * 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.datamapper;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+import com.iluwatar.datamapper.Student;
+import com.iluwatar.datamapper.StudentDataMapper;
+import com.iluwatar.datamapper.StudentDataMapperImpl;
+
+/**
+ * The Data Mapper (DM) is a layer of software that separates the in-memory objects from the
+ * database. Its responsibility is to transfer data between the two and also to isolate them from
+ * each other. With Data Mapper the in-memory objects needn't know even that there's a database
+ * present; they need no SQL interface code, and certainly no knowledge of the database schema. (The
+ * database schema is always ignorant of the objects that use it.) Since it's a form of Mapper ,
+ * Data Mapper itself is even unknown to the domain layer.
+ *
+ */
+public class DataMapperTest {
+
+ /**
+ * This test verify that first data mapper is able to perform all CRUD operations on Student
+ */
+ @Test
+ public void testFirstDataMapper() {
+
+ /* Create new data mapper of first type */
+ final StudentDataMapper mapper = new StudentDataMapperImpl();
+
+ /* Create new student */
+ Student student = new Student(1, "Adam", 'A');
+
+ /* Add student in respectibe db */
+ mapper.insert(student);
+
+ /* Check if student is added in db */
+ assertEquals(student.getStudentId(), mapper.find(student.getStudentId()).get().getStudentId());
+
+ /* Update existing student object */
+ student = new Student(student.getStudentId(), "AdamUpdated", 'A');
+
+ /* Update student in respectibe db */
+ mapper.update(student);
+
+ /* Check if student is updated in db */
+ assertEquals(mapper.find(student.getStudentId()).get().getName(), "AdamUpdated");
+
+ /* Delete student in db */
+ mapper.delete(student);
+
+ /* Result should be false */
+ assertEquals(false, mapper.find(student.getStudentId()).isPresent());
+ }
+}
diff --git a/data-mapper/src/test/java/com/iluwatar/datamapper/StudentTest.java b/data-mapper/src/test/java/com/iluwatar/datamapper/StudentTest.java
new file mode 100644
index 000000000..a3c0e46c1
--- /dev/null
+++ b/data-mapper/src/test/java/com/iluwatar/datamapper/StudentTest.java
@@ -0,0 +1,51 @@
+/**
+ * The MIT License Copyright (c) 2016 Amit Dixit
+ *
+ * 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.datamapper;
+
+import org.junit.Test;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+
+public final class StudentTest {
+
+ @Test
+ /**
+ * This API tests the equality behaviour of Student object
+ * Object Equality should work as per logic defined in equals method
+ *
+ * @throws Exception if any execution error during test
+ */
+ public void testEquality() throws Exception {
+
+ /* Create some students */
+ final Student firstStudent = new Student(1, "Adam", 'A');
+ final Student secondStudent = new Student(2, "Donald", 'B');
+ final Student secondSameStudent = new Student(2, "Donald", 'B');
+ final Student firstSameStudent = firstStudent;
+
+ /* Check equals functionality: should return 'true' */
+ assertTrue(firstStudent.equals(firstSameStudent));
+
+ /* Check equals functionality: should return 'false' */
+ assertFalse(firstStudent.equals(secondStudent));
+
+ /* Check equals functionality: should return 'true' */
+ assertTrue(secondStudent.equals(secondSameStudent));
+ }
+}
diff --git a/decorator/index.md b/decorator/README.md
similarity index 61%
rename from decorator/index.md
rename to decorator/README.md
index 55849fce6..63795114c 100644
--- a/decorator/index.md
+++ b/decorator/README.md
@@ -7,20 +7,28 @@ categories: Structural
tags:
- Java
- Gang Of Four
+ - Difficulty-Beginner
---
-**Intent:** Attach additional responsibilities to an object dynamically.
+## Also known as
+Wrapper
+
+## Intent
+Attach additional responsibilities to an object dynamically.
Decorators provide a flexible alternative to subclassing for extending
functionality.
-
+
-**Applicability:** Use Decorator
+## Applicability
+Use Decorator
* to add responsibilities to individual objects dynamically and transparently, that is, without affecting other objects
* 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
-**Credits**
+## Credits
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)
+* [Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions](http://www.amazon.com/Functional-Programming-Java-Harnessing-Expressions/dp/1937785467/ref=sr_1_1)
+* [J2EE Design Patterns](http://www.amazon.com/J2EE-Design-Patterns-William-Crawford/dp/0596004273/ref=sr_1_2)
diff --git a/decorator/etc/decorator.png b/decorator/etc/decorator.png
index 1e4bfdac2..47a87b20b 100644
Binary files a/decorator/etc/decorator.png and b/decorator/etc/decorator.png differ
diff --git a/decorator/etc/decorator.ucls b/decorator/etc/decorator.ucls
index 7adb8c3a6..a5353d4ec 100644
--- a/decorator/etc/decorator.ucls
+++ b/decorator/etc/decorator.ucls
@@ -1,18 +1,18 @@
-
+
-
+
-
-
+
+
@@ -21,29 +21,46 @@
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
+
+
+
+
+
+
diff --git a/decorator/etc/decorator_1.png b/decorator/etc/decorator_1.png
deleted file mode 100644
index 5a7afe2d1..000000000
Binary files a/decorator/etc/decorator_1.png and /dev/null differ
diff --git a/decorator/pom.xml b/decorator/pom.xml
index 92142f184..7ba2a4ee8 100644
--- a/decorator/pom.xml
+++ b/decorator/pom.xml
@@ -1,11 +1,35 @@
+
4.0.0
com.iluwatar
java-design-patterns
- 1.7.0
+ 1.13.0-SNAPSHOT
decorator
@@ -14,5 +38,10 @@
junit
test
+
+ org.mockito
+ mockito-core
+ test
+
diff --git a/decorator/src/main/java/com/iluwatar/decorator/App.java b/decorator/src/main/java/com/iluwatar/decorator/App.java
index bd697d4a4..bdc574fbc 100644
--- a/decorator/src/main/java/com/iluwatar/decorator/App.java
+++ b/decorator/src/main/java/com/iluwatar/decorator/App.java
@@ -1,38 +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.decorator;
/**
*
- * The Decorator pattern is a more flexible alternative to subclassing. The Decorator
- * class implements the same interface as the target and uses composition to
- * "decorate" calls to the target. Using the Decorator pattern it is possible to
- * change the behavior of the class during runtime.
+ * The Decorator pattern is a more flexible alternative to subclassing. The Decorator class
+ * implements the same interface as the target and uses composition to "decorate" calls to the
+ * target. Using the Decorator pattern it is possible to change the behavior of the class during
+ * runtime.
*
- * In this example we show how the simple {@link Troll} first attacks and then
- * flees the battle. Then we decorate the {@link Troll} with a {@link SmartTroll}
- * and perform the attack again. You can see how the behavior changes after the
- * decoration.
+ * In this example we show how the simple {@link Troll} first attacks and then flees the battle.
+ * Then we decorate the {@link Troll} with a {@link SmartHostile} and perform the attack again. You
+ * can see how the behavior changes after the decoration.
*
*/
public class App {
- /**
- * Program entry point
- * @param args command line args
- */
- public static void main(String[] args) {
+ /**
+ * Program entry point
+ *
+ * @param args command line args
+ */
+ public static void main(String[] args) {
- // simple troll
- System.out.println("A simple looking troll approaches.");
- Hostile troll = new Troll();
- troll.attack();
- troll.fleeBattle();
- System.out.printf("Simple troll power %d.\n", troll.getAttackPower());
+ // simple troll
+ System.out.println("A simple looking troll approaches.");
+ Hostile troll = new Troll();
+ troll.attack();
+ troll.fleeBattle();
+ System.out.printf("Simple troll power %d.\n", troll.getAttackPower());
- // change the behavior of the simple troll by adding a decorator
- System.out.println("\nA smart looking troll surprises you.");
- Hostile smart = new SmartTroll(troll);
- smart.attack();
- smart.fleeBattle();
- System.out.printf("Smart troll power %d.\n", smart.getAttackPower());
- }
+ // change the behavior of the simple troll by adding a decorator
+ System.out.println("\nA smart looking troll surprises you.");
+ Hostile smart = new SmartHostile(troll);
+ smart.attack();
+ smart.fleeBattle();
+ System.out.printf("Smart troll power %d.\n", smart.getAttackPower());
+ }
}
diff --git a/decorator/src/main/java/com/iluwatar/decorator/Hostile.java b/decorator/src/main/java/com/iluwatar/decorator/Hostile.java
index 709072501..d3414c9dd 100644
--- a/decorator/src/main/java/com/iluwatar/decorator/Hostile.java
+++ b/decorator/src/main/java/com/iluwatar/decorator/Hostile.java
@@ -1,3 +1,25 @@
+/**
+ * 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.decorator;
/**
@@ -7,10 +29,10 @@ package com.iluwatar.decorator;
*/
public interface Hostile {
- void attack();
+ void attack();
- int getAttackPower();
+ int getAttackPower();
- void fleeBattle();
+ void fleeBattle();
}
diff --git a/decorator/src/main/java/com/iluwatar/decorator/SmartHostile.java b/decorator/src/main/java/com/iluwatar/decorator/SmartHostile.java
new file mode 100644
index 000000000..3b4b86276
--- /dev/null
+++ b/decorator/src/main/java/com/iluwatar/decorator/SmartHostile.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.decorator;
+
+/**
+ * SmartHostile is a decorator for {@link Hostile} objects. The calls to the {@link Hostile} interface
+ * are intercepted and decorated. Finally the calls are delegated to the decorated {@link Hostile}
+ * object.
+ *
+ */
+public class SmartHostile implements Hostile {
+
+ private Hostile decorated;
+
+ public SmartHostile(Hostile decorated) {
+ this.decorated = decorated;
+ }
+
+ @Override
+ public void attack() {
+ System.out.println("It throws a rock at you!");
+ decorated.attack();
+ }
+
+ @Override
+ public int getAttackPower() {
+ // decorated hostile's power + 20 because it is smart
+ return decorated.getAttackPower() + 20;
+ }
+
+ @Override
+ public void fleeBattle() {
+ System.out.println("It calls for help!");
+ decorated.fleeBattle();
+ }
+}
diff --git a/decorator/src/main/java/com/iluwatar/decorator/SmartTroll.java b/decorator/src/main/java/com/iluwatar/decorator/SmartTroll.java
deleted file mode 100644
index 909f94c95..000000000
--- a/decorator/src/main/java/com/iluwatar/decorator/SmartTroll.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.iluwatar.decorator;
-
-/**
- * SmartTroll is a decorator for {@link Hostile} objects.
- * The calls to the {@link Hostile} interface are intercepted
- * and decorated. Finally the calls are delegated
- * to the decorated {@link Hostile} object.
- *
- */
-public class SmartTroll implements Hostile {
-
- private Hostile decorated;
-
- public SmartTroll(Hostile decorated) {
- this.decorated = decorated;
- }
-
- @Override
- public void attack() {
- System.out.println("The troll throws a rock at you!");
- decorated.attack();
- }
-
- @Override
- public int getAttackPower() {
- // decorated troll power + 20 because it is smart
- return decorated.getAttackPower() + 20;
- }
-
- @Override
- public void fleeBattle() {
- System.out.println("The troll calls for help!");
- decorated.fleeBattle();
- }
-
-}
diff --git a/decorator/src/main/java/com/iluwatar/decorator/Troll.java b/decorator/src/main/java/com/iluwatar/decorator/Troll.java
index 85d873dbe..628adda4b 100644
--- a/decorator/src/main/java/com/iluwatar/decorator/Troll.java
+++ b/decorator/src/main/java/com/iluwatar/decorator/Troll.java
@@ -1,3 +1,25 @@
+/**
+ * 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.decorator;
/**
@@ -7,17 +29,18 @@ package com.iluwatar.decorator;
*/
public class Troll implements Hostile {
- public void attack() {
- System.out.println("The troll swings at you with a club!");
- }
+ @Override
+ public void attack() {
+ System.out.println("The troll swings at you with a club!");
+ }
- @Override
- public int getAttackPower() {
- return 10;
- }
-
- public void fleeBattle() {
- System.out.println("The troll shrieks in horror and runs away!");
- }
+ @Override
+ public int getAttackPower() {
+ return 10;
+ }
+ @Override
+ public void fleeBattle() {
+ System.out.println("The troll shrieks in horror and runs away!");
+ }
}
diff --git a/decorator/src/test/java/com/iluwatar/decorator/AppTest.java b/decorator/src/test/java/com/iluwatar/decorator/AppTest.java
index b74bd3a06..747144c6d 100644
--- a/decorator/src/test/java/com/iluwatar/decorator/AppTest.java
+++ b/decorator/src/test/java/com/iluwatar/decorator/AppTest.java
@@ -1,9 +1,29 @@
+/**
+ * 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.decorator;
import org.junit.Test;
-import com.iluwatar.decorator.App;
-
/**
*
* Application test
@@ -11,9 +31,9 @@ import com.iluwatar.decorator.App;
*/
public class AppTest {
- @Test
- public void test() {
- String[] args = {};
- App.main(args);
- }
+ @Test
+ public void test() {
+ String[] args = {};
+ App.main(args);
+ }
}
diff --git a/decorator/src/test/java/com/iluwatar/decorator/SmartHostileTest.java b/decorator/src/test/java/com/iluwatar/decorator/SmartHostileTest.java
new file mode 100644
index 000000000..6432d4e90
--- /dev/null
+++ b/decorator/src/test/java/com/iluwatar/decorator/SmartHostileTest.java
@@ -0,0 +1,58 @@
+/**
+ * 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.decorator;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.*;
+import static org.mockito.internal.verification.VerificationModeFactory.times;
+
+/**
+ * Date: 12/7/15 - 7:47 PM
+ *
+ * @author Jeroen Meulemeester
+ */
+public class SmartHostileTest {
+
+ @Test
+ public void testSmartHostile() throws Exception {
+ // Create a normal troll first, but make sure we can spy on it later on.
+ final Hostile simpleTroll = spy(new Troll());
+
+ // Now we want to decorate the troll to make it smarter ...
+ final Hostile smartTroll = new SmartHostile(simpleTroll);
+ assertEquals(30, smartTroll.getAttackPower());
+ verify(simpleTroll, times(1)).getAttackPower();
+
+ // Check if the smart troll actions are delegated to the decorated troll
+ smartTroll.attack();
+ verify(simpleTroll, times(1)).attack();
+
+ smartTroll.fleeBattle();
+ verify(simpleTroll, times(1)).fleeBattle();
+ verifyNoMoreInteractions(simpleTroll);
+
+ }
+
+}
diff --git a/decorator/src/test/java/com/iluwatar/decorator/TrollTest.java b/decorator/src/test/java/com/iluwatar/decorator/TrollTest.java
new file mode 100644
index 000000000..84b0f6d20
--- /dev/null
+++ b/decorator/src/test/java/com/iluwatar/decorator/TrollTest.java
@@ -0,0 +1,84 @@
+/**
+ * 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.decorator;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.PrintStream;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.*;
+import static org.mockito.internal.verification.VerificationModeFactory.times;
+
+/**
+ * Date: 12/7/15 - 7:26 PM
+ *
+ * @author Jeroen Meulemeester
+ */
+public class TrollTest {
+
+ /**
+ * The mocked standard out stream, required since the actions don't have any influence on other
+ * objects, except for writing to the std-out using {@link System#out}
+ */
+ private final PrintStream stdOutMock = mock(PrintStream.class);
+
+ /**
+ * Keep the original std-out so it can be restored after the test
+ */
+ private final PrintStream stdOutOrig = System.out;
+
+ /**
+ * Inject the mocked std-out {@link PrintStream} into the {@link System} class before each test
+ */
+ @Before
+ public void setUp() {
+ System.setOut(this.stdOutMock);
+ }
+
+ /**
+ * Removed the mocked std-out {@link PrintStream} again from the {@link System} class
+ */
+ @After
+ public void tearDown() {
+ System.setOut(this.stdOutOrig);
+ }
+
+ @Test
+ public void testTrollActions() throws Exception {
+ final Troll troll = new Troll();
+ assertEquals(10, troll.getAttackPower());
+
+ troll.attack();
+ verify(this.stdOutMock, times(1)).println(eq("The troll swings at you with a club!"));
+
+ troll.fleeBattle();
+ verify(this.stdOutMock, times(1)).println(eq("The troll shrieks in horror and runs away!"));
+
+ verifyNoMoreInteractions(this.stdOutMock);
+ }
+
+}
\ No newline at end of file
diff --git a/delegation/README.md b/delegation/README.md
new file mode 100644
index 000000000..e5c0c6376
--- /dev/null
+++ b/delegation/README.md
@@ -0,0 +1,30 @@
+---
+layout: pattern
+title: Delegation
+folder: delegation
+permalink: /patterns/delegation/
+categories: Behavioral
+tags:
+ - Java
+ - Difficulty-Beginner
+---
+
+## Also known as
+Proxy Pattern
+
+## Intent
+It is a technique where an object expresses certain behavior to the outside but in
+reality delegates responsibility for implementing that behaviour to an associated object.
+
+
+
+## Applicability
+Use the Delegate pattern in order to achieve the following
+
+* Reduce the coupling of methods to their class
+* Components that behave identically, but realize that this situation can change in the future.
+
+## Credits
+
+* [Delegate Pattern: Wikipedia ](https://en.wikipedia.org/wiki/Delegation_pattern)
+* [Proxy Pattern: Wikipedia ](https://en.wikipedia.org/wiki/Proxy_pattern)
diff --git a/delegation/etc/delegation.png b/delegation/etc/delegation.png
new file mode 100644
index 000000000..375ef4d6b
Binary files /dev/null and b/delegation/etc/delegation.png differ
diff --git a/delegation/etc/delegation.ucls b/delegation/etc/delegation.ucls
new file mode 100644
index 000000000..e3ce08873
--- /dev/null
+++ b/delegation/etc/delegation.ucls
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/delegation/pom.xml b/delegation/pom.xml
new file mode 100644
index 000000000..2fca225b8
--- /dev/null
+++ b/delegation/pom.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+ java-design-patterns
+ com.iluwatar
+ 1.13.0-SNAPSHOT
+
+ 4.0.0
+
+ delegation
+
+
+
+ junit
+ junit
+ test
+
+
+ com.github.stefanbirkner
+ system-rules
+ test
+
+
+
\ No newline at end of file
diff --git a/delegation/src/main/java/com/iluwatar/delegation/simple/App.java b/delegation/src/main/java/com/iluwatar/delegation/simple/App.java
new file mode 100644
index 000000000..1940e7ae2
--- /dev/null
+++ b/delegation/src/main/java/com/iluwatar/delegation/simple/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.delegation.simple;
+
+import com.iluwatar.delegation.simple.printers.CanonPrinter;
+import com.iluwatar.delegation.simple.printers.EpsonPrinter;
+import com.iluwatar.delegation.simple.printers.HpPrinter;
+
+/**
+ * The delegate pattern provides a mechanism to abstract away the implementation and control of the desired action.
+ * The class being called in this case {@link PrinterController} is not responsible for the actual desired action,
+ * but is actually delegated to a helper class either {@link CanonPrinter}, {@link EpsonPrinter} or {@link HpPrinter}.
+ * The consumer does not have or require knowledge of the actual class carrying out the action, only the
+ * container on which they are calling.
+ *
+ * In this example the delegates are {@link EpsonPrinter}, {@link HpPrinter} and {@link CanonPrinter} they all implement
+ * {@link Printer}. The {@link PrinterController} class also implements {@link Printer}. However neither provide the
+ * functionality of {@link Printer} by printing to the screen, they actually call upon the instance of {@link Printer}
+ * that they were instantiated with. Therefore delegating the behaviour to another class.
+ */
+public class App {
+
+ public static final String MESSAGE_TO_PRINT = "hello world";
+
+ /**
+ * Program entry point
+ *
+ * @param args command line args
+ */
+ public static void main(String[] args) {
+ PrinterController hpPrinterController = new PrinterController(new HpPrinter());
+ PrinterController canonPrinterController = new PrinterController(new CanonPrinter());
+ PrinterController epsonPrinterController = new PrinterController(new EpsonPrinter());
+
+ hpPrinterController.print(MESSAGE_TO_PRINT);
+ canonPrinterController.print(MESSAGE_TO_PRINT);
+ epsonPrinterController.print(MESSAGE_TO_PRINT);
+ }
+
+}
diff --git a/delegation/src/main/java/com/iluwatar/delegation/simple/Printer.java b/delegation/src/main/java/com/iluwatar/delegation/simple/Printer.java
new file mode 100644
index 000000000..a25f0fba3
--- /dev/null
+++ b/delegation/src/main/java/com/iluwatar/delegation/simple/Printer.java
@@ -0,0 +1,45 @@
+/**
+ * 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.delegation.simple;
+
+import com.iluwatar.delegation.simple.printers.CanonPrinter;
+import com.iluwatar.delegation.simple.printers.EpsonPrinter;
+import com.iluwatar.delegation.simple.printers.HpPrinter;
+
+/**
+ * Interface that both the Controller and the Delegate will implement.
+ *
+ * @see CanonPrinter
+ * @see EpsonPrinter
+ * @see HpPrinter
+ */
+public interface Printer {
+
+ /**
+ * Method that takes a String to print to the screen. This will be implemented on both the
+ * controller and the delegate allowing the controller to call the same method on the delegate class.
+ *
+ * @param message to be printed to the screen
+ */
+ void print(final String message);
+}
diff --git a/delegation/src/main/java/com/iluwatar/delegation/simple/PrinterController.java b/delegation/src/main/java/com/iluwatar/delegation/simple/PrinterController.java
new file mode 100644
index 000000000..8a4f20dd2
--- /dev/null
+++ b/delegation/src/main/java/com/iluwatar/delegation/simple/PrinterController.java
@@ -0,0 +1,45 @@
+/**
+ * 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.delegation.simple;
+
+public class PrinterController implements Printer {
+
+ private final Printer printer;
+
+ public PrinterController(Printer printer) {
+ this.printer = printer;
+ }
+
+ /**
+ * This method is implemented from {@link Printer} however instead on providing an
+ * implementation, it instead calls upon the class passed through the constructor. This is the delegate,
+ * hence the pattern. Therefore meaning that the caller does not care of the implementing class only the owning
+ * controller.
+ *
+ * @param message to be printed to the screen
+ */
+ @Override
+ public void print(String message) {
+ printer.print(message);
+ }
+}
diff --git a/delegation/src/main/java/com/iluwatar/delegation/simple/printers/CanonPrinter.java b/delegation/src/main/java/com/iluwatar/delegation/simple/printers/CanonPrinter.java
new file mode 100644
index 000000000..5e3966d85
--- /dev/null
+++ b/delegation/src/main/java/com/iluwatar/delegation/simple/printers/CanonPrinter.java
@@ -0,0 +1,43 @@
+/**
+ * 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.delegation.simple.printers;
+
+import com.iluwatar.delegation.simple.Printer;
+
+/**
+ * Specialised Implementation of {@link Printer} for a Canon Printer, in
+ * this case the message to be printed is appended to "Canon Printer : "
+ *
+ * @see Printer
+ */
+public class CanonPrinter implements Printer {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void print(String message) {
+ System.out.print("Canon Printer : " + message);
+ }
+
+}
diff --git a/delegation/src/main/java/com/iluwatar/delegation/simple/printers/EpsonPrinter.java b/delegation/src/main/java/com/iluwatar/delegation/simple/printers/EpsonPrinter.java
new file mode 100644
index 000000000..d37fbf613
--- /dev/null
+++ b/delegation/src/main/java/com/iluwatar/delegation/simple/printers/EpsonPrinter.java
@@ -0,0 +1,43 @@
+/**
+ * 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.delegation.simple.printers;
+
+import com.iluwatar.delegation.simple.Printer;
+
+/**
+ * Specialised Implementation of {@link Printer} for a Epson Printer, in
+ * this case the message to be printed is appended to "Epson Printer : "
+ *
+ * @see Printer
+ */
+public class EpsonPrinter implements Printer {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void print(String message) {
+ System.out.print("Epson Printer : " + message);
+ }
+
+}
diff --git a/delegation/src/main/java/com/iluwatar/delegation/simple/printers/HpPrinter.java b/delegation/src/main/java/com/iluwatar/delegation/simple/printers/HpPrinter.java
new file mode 100644
index 000000000..f81debf62
--- /dev/null
+++ b/delegation/src/main/java/com/iluwatar/delegation/simple/printers/HpPrinter.java
@@ -0,0 +1,43 @@
+/**
+ * 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.delegation.simple.printers;
+
+import com.iluwatar.delegation.simple.Printer;
+
+/**
+ * Specialised Implementation of {@link Printer} for a HP Printer, in
+ * this case the message to be printed is appended to "HP Printer : "
+ *
+ * @see Printer
+ */
+public class HpPrinter implements Printer {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void print(String message) {
+ System.out.print("HP Printer : " + message);
+ }
+
+}
diff --git a/delegation/src/test/java/com/iluwatar/delegation/simple/AppTest.java b/delegation/src/test/java/com/iluwatar/delegation/simple/AppTest.java
new file mode 100644
index 000000000..63e469a59
--- /dev/null
+++ b/delegation/src/test/java/com/iluwatar/delegation/simple/AppTest.java
@@ -0,0 +1,35 @@
+/**
+ * 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.delegation.simple;
+
+import org.junit.Test;
+
+public class AppTest {
+
+ @Test
+ public void test() {
+ String[] args = {};
+ App.main(args);
+ }
+
+}
diff --git a/delegation/src/test/java/com/iluwatar/delegation/simple/DelegateTest.java b/delegation/src/test/java/com/iluwatar/delegation/simple/DelegateTest.java
new file mode 100644
index 000000000..6a19c9a1a
--- /dev/null
+++ b/delegation/src/test/java/com/iluwatar/delegation/simple/DelegateTest.java
@@ -0,0 +1,65 @@
+/**
+ * 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.delegation.simple;
+
+import com.iluwatar.delegation.simple.printers.CanonPrinter;
+import com.iluwatar.delegation.simple.printers.EpsonPrinter;
+import com.iluwatar.delegation.simple.printers.HpPrinter;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.contrib.java.lang.system.SystemOutRule;
+
+import static org.junit.Assert.assertEquals;
+
+public class DelegateTest {
+
+ private static final String MESSAGE = "Test Message Printed";
+
+ @Rule
+ public final SystemOutRule systemOutRule = new SystemOutRule().enableLog();
+
+ @Test
+ public void testCanonPrinter() throws Exception {
+ PrinterController printerController = new PrinterController(new CanonPrinter());
+ printerController.print(MESSAGE);
+
+ assertEquals("Canon Printer : Test Message Printed", systemOutRule.getLog());
+ }
+
+ @Test
+ public void testHpPrinter() throws Exception {
+ PrinterController printerController = new PrinterController(new HpPrinter());
+ printerController.print(MESSAGE);
+
+ assertEquals("HP Printer : Test Message Printed", systemOutRule.getLog());
+ }
+
+ @Test
+ public void testEpsonPrinter() throws Exception {
+ PrinterController printerController = new PrinterController(new EpsonPrinter());
+ printerController.print(MESSAGE);
+
+ assertEquals("Epson Printer : Test Message Printed", systemOutRule.getLog());
+ }
+
+}
diff --git a/dependency-injection/index.md b/dependency-injection/README.md
similarity index 80%
rename from dependency-injection/index.md
rename to dependency-injection/README.md
index f6ead97a7..735f589b1 100644
--- a/dependency-injection/index.md
+++ b/dependency-injection/README.md
@@ -4,10 +4,13 @@ title: Dependency Injection
folder: dependency-injection
permalink: /patterns/dependency-injection/
categories: Behavioral
-tags: Java
+tags:
+ - Java
+ - Difficulty-Beginner
---
-**Intent:** Dependency Injection is a software design pattern in which one or
+## Intent
+Dependency Injection is a software design pattern in which one or
more dependencies (or services) are injected, or passed by reference, into a
dependent object (or client) and are made part of the client's state. The
pattern separates the creation of a client's dependencies from its own
@@ -16,7 +19,8 @@ inversion of control and single responsibility principles.

-**Applicability:** Use the Dependency Injection pattern when
+## Applicability
+Use the Dependency Injection pattern when
* when you need to remove knowledge of concrete implementation from object
* to enable unit testing of classes in isolation using mock objects or stubs
diff --git a/dependency-injection/pom.xml b/dependency-injection/pom.xml
index 9a28933f8..3472da240 100644
--- a/dependency-injection/pom.xml
+++ b/dependency-injection/pom.xml
@@ -1,11 +1,35 @@
+
4.0.0
com.iluwatar
java-design-patterns
- 1.7.0
+ 1.13.0-SNAPSHOT
dependency-injection
@@ -13,6 +37,11 @@
junit
junit
test
+
+
+ org.mockito
+ mockito-core
+ test
com.google.inject
diff --git a/dependency-injection/src/main/java/com/iluwatar/dependency/injection/AdvancedWizard.java b/dependency-injection/src/main/java/com/iluwatar/dependency/injection/AdvancedWizard.java
index 8202cc58e..4eeaccdea 100644
--- a/dependency-injection/src/main/java/com/iluwatar/dependency/injection/AdvancedWizard.java
+++ b/dependency-injection/src/main/java/com/iluwatar/dependency/injection/AdvancedWizard.java
@@ -1,22 +1,43 @@
+/**
+ * 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.dependency.injection;
/**
*
- * AdvancedWizard implements inversion of control.
- * It depends on abstraction that can be injected through
- * its constructor.
+ * AdvancedWizard implements inversion of control. It depends on abstraction that can be injected
+ * through its constructor.
*
*/
public class AdvancedWizard implements Wizard {
-
- private Tobacco tobacco;
- public AdvancedWizard(Tobacco tobacco) {
- this.tobacco = tobacco;
- }
+ private Tobacco tobacco;
- @Override
- public void smoke() {
- tobacco.smoke(this);
- }
+ public AdvancedWizard(Tobacco tobacco) {
+ this.tobacco = tobacco;
+ }
+
+ @Override
+ public void smoke() {
+ tobacco.smoke(this);
+ }
}
diff --git a/dependency-injection/src/main/java/com/iluwatar/dependency/injection/App.java b/dependency-injection/src/main/java/com/iluwatar/dependency/injection/App.java
index a882863b7..faf2a6a43 100644
--- a/dependency-injection/src/main/java/com/iluwatar/dependency/injection/App.java
+++ b/dependency-injection/src/main/java/com/iluwatar/dependency/injection/App.java
@@ -1,3 +1,25 @@
+/**
+ * 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.dependency.injection;
import com.google.inject.Guice;
@@ -5,40 +27,41 @@ import com.google.inject.Injector;
/**
*
- * Dependency Injection pattern deals with how objects handle their dependencies. The pattern
+ * Dependency Injection pattern deals with how objects handle their dependencies. The pattern
* implements so called inversion of control principle. Inversion of control has two specific rules:
- * - High-level modules should not depend on low-level modules. Both should depend on abstractions.
- * - Abstractions should not depend on details. Details should depend on abstractions.
- *
- * In this example we show you three different wizards. The first one ({@link SimpleWizard}) is a naive
- * implementation violating the inversion of control principle. It depends directly on a concrete
- * implementation which cannot be changed.
- *
- * The second wizard ({@link AdvancedWizard}) is more flexible. It does not depend on any concrete implementation
- * but abstraction. It utilizes Dependency Injection pattern allowing its {@link Tobacco} dependency to be
- * injected through its constructor. This way, handling the dependency is no longer the wizard's
- * responsibility. It is resolved outside the wizard class.
- *
- * The third example takes the pattern a step further. It uses Guice framework for Dependency Injection.
- * {@link TobaccoModule} binds a concrete implementation to abstraction. Injector is then used to create
- * {@link GuiceWizard} object with correct dependencies.
+ * - High-level modules should not depend on low-level modules. Both should depend on abstractions.
+ * - Abstractions should not depend on details. Details should depend on abstractions.
+ *
+ * In this example we show you three different wizards. The first one ({@link SimpleWizard}) is a
+ * naive implementation violating the inversion of control principle. It depends directly on a
+ * concrete implementation which cannot be changed.
+ *
+ * The second wizard ({@link AdvancedWizard}) is more flexible. It does not depend on any concrete
+ * implementation but abstraction. It utilizes Dependency Injection pattern allowing its
+ * {@link Tobacco} dependency to be injected through its constructor. This way, handling the
+ * dependency is no longer the wizard's responsibility. It is resolved outside the wizard class.
+ *
+ * The third example takes the pattern a step further. It uses Guice framework for Dependency
+ * Injection. {@link TobaccoModule} binds a concrete implementation to abstraction. Injector is then
+ * used to create {@link GuiceWizard} object with correct dependencies.
*
*/
public class App {
-
- /**
- * Program entry point
- * @param args command line args
- */
- public static void main( String[] args ) {
- SimpleWizard simpleWizard = new SimpleWizard();
- simpleWizard.smoke();
-
- AdvancedWizard advancedWizard = new AdvancedWizard(new SecondBreakfastTobacco());
- advancedWizard.smoke();
-
- Injector injector = Guice.createInjector(new TobaccoModule());
- GuiceWizard guiceWizard = injector.getInstance(GuiceWizard.class);
- guiceWizard.smoke();
- }
+
+ /**
+ * Program entry point
+ *
+ * @param args command line args
+ */
+ public static void main(String[] args) {
+ SimpleWizard simpleWizard = new SimpleWizard();
+ simpleWizard.smoke();
+
+ AdvancedWizard advancedWizard = new AdvancedWizard(new SecondBreakfastTobacco());
+ advancedWizard.smoke();
+
+ Injector injector = Guice.createInjector(new TobaccoModule());
+ GuiceWizard guiceWizard = injector.getInstance(GuiceWizard.class);
+ guiceWizard.smoke();
+ }
}
diff --git a/dependency-injection/src/main/java/com/iluwatar/dependency/injection/GuiceWizard.java b/dependency-injection/src/main/java/com/iluwatar/dependency/injection/GuiceWizard.java
index 9393377f1..6e3baee5a 100644
--- a/dependency-injection/src/main/java/com/iluwatar/dependency/injection/GuiceWizard.java
+++ b/dependency-injection/src/main/java/com/iluwatar/dependency/injection/GuiceWizard.java
@@ -1,25 +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.dependency.injection;
import javax.inject.Inject;
/**
*
- * GuiceWizard implements inversion of control.
- * Its dependencies are injected through its constructor
- * by Guice framework.
+ * GuiceWizard implements inversion of control. Its dependencies are injected through its
+ * constructor by Guice framework.
*
*/
public class GuiceWizard implements Wizard {
-
- private Tobacco tobacco;
-
- @Inject
- public GuiceWizard(Tobacco tobacco) {
- this.tobacco = tobacco;
- }
- @Override
- public void smoke() {
- tobacco.smoke(this);
- }
+ private Tobacco tobacco;
+
+ @Inject
+ public GuiceWizard(Tobacco tobacco) {
+ this.tobacco = tobacco;
+ }
+
+ @Override
+ public void smoke() {
+ tobacco.smoke(this);
+ }
}
diff --git a/dependency-injection/src/main/java/com/iluwatar/dependency/injection/OldTobyTobacco.java b/dependency-injection/src/main/java/com/iluwatar/dependency/injection/OldTobyTobacco.java
index 9197066ee..523be1d37 100644
--- a/dependency-injection/src/main/java/com/iluwatar/dependency/injection/OldTobyTobacco.java
+++ b/dependency-injection/src/main/java/com/iluwatar/dependency/injection/OldTobyTobacco.java
@@ -1,3 +1,25 @@
+/**
+ * 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.dependency.injection;
/**
diff --git a/dependency-injection/src/main/java/com/iluwatar/dependency/injection/RivendellTobacco.java b/dependency-injection/src/main/java/com/iluwatar/dependency/injection/RivendellTobacco.java
index 9eb137a05..18691a161 100644
--- a/dependency-injection/src/main/java/com/iluwatar/dependency/injection/RivendellTobacco.java
+++ b/dependency-injection/src/main/java/com/iluwatar/dependency/injection/RivendellTobacco.java
@@ -1,3 +1,25 @@
+/**
+ * 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.dependency.injection;
/**
diff --git a/dependency-injection/src/main/java/com/iluwatar/dependency/injection/SecondBreakfastTobacco.java b/dependency-injection/src/main/java/com/iluwatar/dependency/injection/SecondBreakfastTobacco.java
index 269f531d3..57565daf0 100644
--- a/dependency-injection/src/main/java/com/iluwatar/dependency/injection/SecondBreakfastTobacco.java
+++ b/dependency-injection/src/main/java/com/iluwatar/dependency/injection/SecondBreakfastTobacco.java
@@ -1,3 +1,25 @@
+/**
+ * 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.dependency.injection;
/**
diff --git a/dependency-injection/src/main/java/com/iluwatar/dependency/injection/SimpleWizard.java b/dependency-injection/src/main/java/com/iluwatar/dependency/injection/SimpleWizard.java
index 5bc2c8377..6928fe7fe 100644
--- a/dependency-injection/src/main/java/com/iluwatar/dependency/injection/SimpleWizard.java
+++ b/dependency-injection/src/main/java/com/iluwatar/dependency/injection/SimpleWizard.java
@@ -1,16 +1,38 @@
+/**
+ * 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.dependency.injection;
/**
*
- * Naive Wizard implementation violating the inversion of control principle.
- * It should depend on abstraction instead.
+ * Naive Wizard implementation violating the inversion of control principle. It should depend on
+ * abstraction instead.
*
*/
public class SimpleWizard implements Wizard {
-
- private OldTobyTobacco tobacco = new OldTobyTobacco();
-
- public void smoke() {
- tobacco.smoke(this);
- }
+
+ private OldTobyTobacco tobacco = new OldTobyTobacco();
+
+ public void smoke() {
+ tobacco.smoke(this);
+ }
}
diff --git a/dependency-injection/src/main/java/com/iluwatar/dependency/injection/Tobacco.java b/dependency-injection/src/main/java/com/iluwatar/dependency/injection/Tobacco.java
index 7ee97404d..74a564ab5 100644
--- a/dependency-injection/src/main/java/com/iluwatar/dependency/injection/Tobacco.java
+++ b/dependency-injection/src/main/java/com/iluwatar/dependency/injection/Tobacco.java
@@ -1,3 +1,25 @@
+/**
+ * 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.dependency.injection;
/**
@@ -6,8 +28,9 @@ package com.iluwatar.dependency.injection;
*
*/
public abstract class Tobacco {
-
- public void smoke(Wizard wizard) {
- System.out.println(String.format("%s smoking %s", wizard.getClass().getSimpleName(), this.getClass().getSimpleName()));
- }
+
+ public void smoke(Wizard wizard) {
+ System.out.println(String.format("%s smoking %s", wizard.getClass().getSimpleName(), this
+ .getClass().getSimpleName()));
+ }
}
diff --git a/dependency-injection/src/main/java/com/iluwatar/dependency/injection/TobaccoModule.java b/dependency-injection/src/main/java/com/iluwatar/dependency/injection/TobaccoModule.java
index d2dd1072e..b8d4df676 100644
--- a/dependency-injection/src/main/java/com/iluwatar/dependency/injection/TobaccoModule.java
+++ b/dependency-injection/src/main/java/com/iluwatar/dependency/injection/TobaccoModule.java
@@ -1,3 +1,25 @@
+/**
+ * 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.dependency.injection;
import com.google.inject.AbstractModule;
@@ -9,8 +31,8 @@ import com.google.inject.AbstractModule;
*/
public class TobaccoModule extends AbstractModule {
- @Override
- protected void configure() {
- bind(Tobacco.class).to(RivendellTobacco.class);
- }
+ @Override
+ protected void configure() {
+ bind(Tobacco.class).to(RivendellTobacco.class);
+ }
}
diff --git a/dependency-injection/src/main/java/com/iluwatar/dependency/injection/Wizard.java b/dependency-injection/src/main/java/com/iluwatar/dependency/injection/Wizard.java
index 8ac9f9fcb..a5d4d68e0 100644
--- a/dependency-injection/src/main/java/com/iluwatar/dependency/injection/Wizard.java
+++ b/dependency-injection/src/main/java/com/iluwatar/dependency/injection/Wizard.java
@@ -1,3 +1,25 @@
+/**
+ * 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.dependency.injection;
/**
@@ -6,7 +28,7 @@ package com.iluwatar.dependency.injection;
*
*/
public interface Wizard {
-
- void smoke();
+
+ void smoke();
}
diff --git a/dependency-injection/src/test/java/com/iluwatar/dependency/injection/AdvancedWizardTest.java b/dependency-injection/src/test/java/com/iluwatar/dependency/injection/AdvancedWizardTest.java
new file mode 100644
index 000000000..d1f5e574c
--- /dev/null
+++ b/dependency-injection/src/test/java/com/iluwatar/dependency/injection/AdvancedWizardTest.java
@@ -0,0 +1,62 @@
+/**
+ * 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.dependency.injection;
+
+import org.junit.Test;
+
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+
+/**
+ * Date: 12/10/15 - 8:40 PM
+ *
+ * @author Jeroen Meulemeester
+ */
+public class AdvancedWizardTest extends StdOutTest {
+
+ /**
+ * Test if the {@link AdvancedWizard} smokes whatever instance of {@link Tobacco} is passed to him
+ * through the constructor parameter
+ */
+ @Test
+ public void testSmokeEveryThing() throws Exception {
+
+ final Tobacco[] tobaccos = {
+ new OldTobyTobacco(), new RivendellTobacco(), new SecondBreakfastTobacco()
+ };
+
+ for (final Tobacco tobacco : tobaccos) {
+ final AdvancedWizard advancedWizard = new AdvancedWizard(tobacco);
+ advancedWizard.smoke();
+
+ // Verify if the wizard is smoking the correct tobacco ...
+ verify(getStdOutMock(), times(1)).println("AdvancedWizard smoking " + tobacco.getClass().getSimpleName());
+
+ // ... and nothing else is happening.
+ verifyNoMoreInteractions(getStdOutMock());
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/dependency-injection/src/test/java/com/iluwatar/dependency/injection/AppTest.java b/dependency-injection/src/test/java/com/iluwatar/dependency/injection/AppTest.java
index 5315fe1db..2003933ac 100644
--- a/dependency-injection/src/test/java/com/iluwatar/dependency/injection/AppTest.java
+++ b/dependency-injection/src/test/java/com/iluwatar/dependency/injection/AppTest.java
@@ -1,9 +1,29 @@
+/**
+ * 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.dependency.injection;
import org.junit.Test;
-import com.iluwatar.dependency.injection.App;
-
/**
*
* Application test
@@ -11,9 +31,9 @@ import com.iluwatar.dependency.injection.App;
*/
public class AppTest {
- @Test
- public void test() {
- String[] args = {};
- App.main(args);
- }
+ @Test
+ public void test() {
+ String[] args = {};
+ App.main(args);
+ }
}
diff --git a/dependency-injection/src/test/java/com/iluwatar/dependency/injection/GuiceWizardTest.java b/dependency-injection/src/test/java/com/iluwatar/dependency/injection/GuiceWizardTest.java
new file mode 100644
index 000000000..1d3d679df
--- /dev/null
+++ b/dependency-injection/src/test/java/com/iluwatar/dependency/injection/GuiceWizardTest.java
@@ -0,0 +1,100 @@
+/**
+ * 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.dependency.injection;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+
+import org.junit.Test;
+
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+
+/**
+ * Date: 12/10/15 - 8:57 PM
+ *
+ * @author Jeroen Meulemeester
+ */
+public class GuiceWizardTest extends StdOutTest {
+
+ /**
+ * Test if the {@link GuiceWizard} smokes whatever instance of {@link Tobacco} is passed to him
+ * through the constructor parameter
+ */
+ @Test
+ public void testSmokeEveryThingThroughConstructor() throws Exception {
+
+ final Tobacco[] tobaccos = {
+ new OldTobyTobacco(), new RivendellTobacco(), new SecondBreakfastTobacco()
+ };
+
+ for (final Tobacco tobacco : tobaccos) {
+ final GuiceWizard guiceWizard = new GuiceWizard(tobacco);
+ guiceWizard.smoke();
+
+ // Verify if the wizard is smoking the correct tobacco ...
+ verify(getStdOutMock(), times(1)).println("GuiceWizard smoking " + tobacco.getClass().getSimpleName());
+
+ // ... and nothing else is happening.
+ verifyNoMoreInteractions(getStdOutMock());
+ }
+
+ }
+
+ /**
+ * Test if the {@link GuiceWizard} smokes whatever instance of {@link Tobacco} is passed to him
+ * through the Guice google inject framework
+ */
+ @Test
+ public void testSmokeEveryThingThroughInjectionFramework() throws Exception {
+
+ @SuppressWarnings("unchecked")
+ final Class extends Tobacco>[] tobaccos = new Class[]{
+ OldTobyTobacco.class, RivendellTobacco.class, SecondBreakfastTobacco.class
+ };
+
+ for (final Class extends Tobacco> tobaccoClass : tobaccos) {
+ // Configure the tobacco in the injection framework ...
+ final Injector injector = Guice.createInjector(new AbstractModule() {
+ @Override
+ protected void configure() {
+ bind(Tobacco.class).to(tobaccoClass);
+ }
+ });
+
+ // ... and create a new wizard with it
+ final GuiceWizard guiceWizard = injector.getInstance(GuiceWizard.class);
+ guiceWizard.smoke();
+
+ // Verify if the wizard is smoking the correct tobacco ...
+ verify(getStdOutMock(), times(1)).println("GuiceWizard smoking " + tobaccoClass.getSimpleName());
+
+ // ... and nothing else is happening.
+ verifyNoMoreInteractions(getStdOutMock());
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/dependency-injection/src/test/java/com/iluwatar/dependency/injection/SimpleWizardTest.java b/dependency-injection/src/test/java/com/iluwatar/dependency/injection/SimpleWizardTest.java
new file mode 100644
index 000000000..e5a856e8d
--- /dev/null
+++ b/dependency-injection/src/test/java/com/iluwatar/dependency/injection/SimpleWizardTest.java
@@ -0,0 +1,48 @@
+/**
+ * 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.dependency.injection;
+
+import org.junit.Test;
+
+import static org.mockito.Mockito.*;
+
+/**
+ * Date: 12/10/15 - 8:26 PM
+ *
+ * @author Jeroen Meulemeester
+ */
+public class SimpleWizardTest extends StdOutTest {
+
+ /**
+ * Test if the {@link SimpleWizard} does the only thing it can do: Smoke it's {@link
+ * OldTobyTobacco}
+ */
+ @Test
+ public void testSmoke() {
+ final SimpleWizard simpleWizard = new SimpleWizard();
+ simpleWizard.smoke();
+ verify(getStdOutMock(), times(1)).println("SimpleWizard smoking OldTobyTobacco");
+ verifyNoMoreInteractions(getStdOutMock());
+ }
+
+}
\ No newline at end of file
diff --git a/dependency-injection/src/test/java/com/iluwatar/dependency/injection/StdOutTest.java b/dependency-injection/src/test/java/com/iluwatar/dependency/injection/StdOutTest.java
new file mode 100644
index 000000000..57272c511
--- /dev/null
+++ b/dependency-injection/src/test/java/com/iluwatar/dependency/injection/StdOutTest.java
@@ -0,0 +1,75 @@
+/**
+ * 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.dependency.injection;
+
+import org.junit.After;
+import org.junit.Before;
+
+import java.io.PrintStream;
+
+import static org.mockito.Mockito.mock;
+
+/**
+ * Date: 12/10/15 - 8:37 PM
+ *
+ * @author Jeroen Meulemeester
+ */
+public abstract class StdOutTest {
+
+ /**
+ * The mocked standard out {@link PrintStream}, required since the actions of the wizard don't
+ * have any influence on any other accessible objects, except for writing to std-out using {@link
+ * System#out}
+ */
+ private final PrintStream stdOutMock = mock(PrintStream.class);
+
+ /**
+ * Keep the original std-out so it can be restored after the test
+ */
+ private final PrintStream stdOutOrig = System.out;
+
+ /**
+ * Inject the mocked std-out {@link PrintStream} into the {@link System} class before each test
+ */
+ @Before
+ public void setUp() {
+ System.setOut(this.stdOutMock);
+ }
+
+ /**
+ * Removed the mocked std-out {@link PrintStream} again from the {@link System} class
+ */
+ @After
+ public void tearDown() {
+ System.setOut(this.stdOutOrig);
+ }
+
+ /**
+ * Get the mocked stdOut {@link PrintStream}
+ *
+ * @return The stdOut print stream mock, renewed before each test
+ */
+ final PrintStream getStdOutMock() {
+ return this.stdOutMock;
+ }
+}
diff --git a/double-checked-locking/index.md b/double-checked-locking/README.md
similarity index 82%
rename from double-checked-locking/index.md
rename to double-checked-locking/README.md
index b1b0108ec..da1fdd1a2 100644
--- a/double-checked-locking/index.md
+++ b/double-checked-locking/README.md
@@ -4,17 +4,22 @@ title: Double Checked Locking
folder: double-checked-locking
permalink: /patterns/double-checked-locking/
categories: Concurrency
-tags: Java
+tags:
+ - Java
+ - Difficulty-Beginner
+ - Idiom
---
-**Intent:** Reduce the overhead of acquiring a lock by first testing the
+## Intent
+Reduce the overhead of acquiring a lock by first testing the
locking criterion (the "lock hint") without actually acquiring the lock. Only
if the locking criterion check indicates that locking is required does the
actual locking logic proceed.

-**Applicability:** Use the Double Checked Locking pattern when
+## Applicability
+Use the Double Checked Locking pattern when
* there is a concurrent access in object creation, e.g. singleton, where you want to create single instance of the same class and checking if it's null or not maybe not be enough when there are two or more threads that checks if instance is null or not.
* there is a concurrent access on a method where method's behaviour changes according to the some constraints and these constraint change within this method.
diff --git a/double-checked-locking/pom.xml b/double-checked-locking/pom.xml
index 6f1fe93eb..239bcf870 100644
--- a/double-checked-locking/pom.xml
+++ b/double-checked-locking/pom.xml
@@ -1,9 +1,33 @@
+
4.0.0
com.iluwatar
java-design-patterns
- 1.7.0
+ 1.13.0-SNAPSHOT
double-checked-locking
@@ -12,5 +36,10 @@
junit
test
+
+ org.mockito
+ mockito-core
+ test
+
diff --git a/double-checked-locking/src/main/java/com/iluwatar/doublechecked/locking/App.java b/double-checked-locking/src/main/java/com/iluwatar/doublechecked/locking/App.java
index b8d6a41a0..98309e181 100644
--- a/double-checked-locking/src/main/java/com/iluwatar/doublechecked/locking/App.java
+++ b/double-checked-locking/src/main/java/com/iluwatar/doublechecked/locking/App.java
@@ -1,3 +1,25 @@
+/**
+ * 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.doublechecked.locking;
import java.util.concurrent.ExecutorService;
@@ -6,38 +28,37 @@ import java.util.concurrent.TimeUnit;
/**
*
- * Double Checked Locking is a concurrency design pattern used to reduce the overhead
- * of acquiring a lock by first testing the locking criterion (the "lock hint") without
- * actually acquiring the lock. Only if the locking criterion check indicates that
- * locking is required does the actual locking logic proceed.
+ * Double Checked Locking is a concurrency design pattern used to reduce the overhead of acquiring a
+ * lock by first testing the locking criterion (the "lock hint") without actually acquiring the
+ * lock. Only if the locking criterion check indicates that locking is required does the actual
+ * locking logic proceed.
*
- * In {@link Inventory} we store the items with a given size. However, we do not store
- * more items than the inventory size. To address concurrent access problems we
- * use double checked locking to add item to inventory. In this method, the
- * thread which gets the lock first adds the item.
+ * In {@link Inventory} we store the items with a given size. However, we do not store more items
+ * than the inventory size. To address concurrent access problems we use double checked locking to
+ * add item to inventory. In this method, the thread which gets the lock first adds the item.
*
*/
public class App {
- /**
- * Program entry point
- * @param args command line args
- */
- public static void main(String[] args) {
- final Inventory inventory = new Inventory(1000);
- ExecutorService executorService = Executors.newFixedThreadPool(3);
- for (int i = 0; i < 3; i++) {
- executorService.execute(() -> {
- while (inventory.addItem(new Item()))
- ;
- });
- }
+ /**
+ * Program entry point
+ *
+ * @param args command line args
+ */
+ public static void main(String[] args) {
+ final Inventory inventory = new Inventory(1000);
+ ExecutorService executorService = Executors.newFixedThreadPool(3);
+ for (int i = 0; i < 3; i++) {
+ executorService.execute(() -> {
+ while (inventory.addItem(new Item())) {};
+ });
+ }
- executorService.shutdown();
- try {
- executorService.awaitTermination(5, TimeUnit.SECONDS);
- } catch (InterruptedException e) {
- System.out.println("Error waiting for ExecutorService shutdown");
- }
- }
+ executorService.shutdown();
+ try {
+ executorService.awaitTermination(5, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ System.out.println("Error waiting for ExecutorService shutdown");
+ }
+ }
}
diff --git a/double-checked-locking/src/main/java/com/iluwatar/doublechecked/locking/Inventory.java b/double-checked-locking/src/main/java/com/iluwatar/doublechecked/locking/Inventory.java
index a58926d9d..176203a44 100644
--- a/double-checked-locking/src/main/java/com/iluwatar/doublechecked/locking/Inventory.java
+++ b/double-checked-locking/src/main/java/com/iluwatar/doublechecked/locking/Inventory.java
@@ -1,6 +1,29 @@
+/**
+ * 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.doublechecked.locking;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@@ -12,32 +35,46 @@ import java.util.concurrent.locks.ReentrantLock;
*/
public class Inventory {
- private final int inventorySize;
- private final List- items;
- private final Lock lock;
+ private final int inventorySize;
+ private final List
- items;
+ private final Lock lock;
- public Inventory(int inventorySize) {
- this.inventorySize = inventorySize;
- this.items = new ArrayList<>(inventorySize);
- this.lock = new ReentrantLock();
- }
+ /**
+ * Constructor
+ */
+ public Inventory(int inventorySize) {
+ this.inventorySize = inventorySize;
+ this.items = new ArrayList<>(inventorySize);
+ this.lock = new ReentrantLock();
+ }
- public boolean addItem(Item item) {
- if (items.size() < inventorySize) {
- lock.lock();
- try {
- if (items.size() < inventorySize) {
- items.add(item);
- System.out.println(Thread.currentThread()
- + ": items.size()=" + items.size()
- + ", inventorySize=" + inventorySize);
- return true;
- }
- } finally {
- lock.unlock();
- }
- }
- return false;
- }
+ /**
+ * Add item
+ */
+ public boolean addItem(Item item) {
+ if (items.size() < inventorySize) {
+ lock.lock();
+ try {
+ if (items.size() < inventorySize) {
+ items.add(item);
+ System.out.println(Thread.currentThread() + ": items.size()=" + items.size()
+ + ", inventorySize=" + inventorySize);
+ return true;
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Get all the items in the inventory
+ *
+ * @return All the items of the inventory, as an unmodifiable list
+ */
+ public final List
- getItems() {
+ return Collections.unmodifiableList(items);
+ }
}
diff --git a/double-checked-locking/src/main/java/com/iluwatar/doublechecked/locking/Item.java b/double-checked-locking/src/main/java/com/iluwatar/doublechecked/locking/Item.java
index 8fc7f3888..c805022ab 100644
--- a/double-checked-locking/src/main/java/com/iluwatar/doublechecked/locking/Item.java
+++ b/double-checked-locking/src/main/java/com/iluwatar/doublechecked/locking/Item.java
@@ -1,3 +1,25 @@
+/**
+ * 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.doublechecked.locking;
/**
@@ -6,7 +28,4 @@ package com.iluwatar.doublechecked.locking;
*
*/
public class Item {
-
- private String name;
- private int level;
}
diff --git a/double-checked-locking/src/test/java/com/iluwatar/doublechecked/locking/AppTest.java b/double-checked-locking/src/test/java/com/iluwatar/doublechecked/locking/AppTest.java
index 14fd47488..748c66c6a 100644
--- a/double-checked-locking/src/test/java/com/iluwatar/doublechecked/locking/AppTest.java
+++ b/double-checked-locking/src/test/java/com/iluwatar/doublechecked/locking/AppTest.java
@@ -1,9 +1,29 @@
+/**
+ * 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.doublechecked.locking;
import org.junit.Test;
-import com.iluwatar.doublechecked.locking.App;
-
/**
*
* Application test
@@ -11,9 +31,9 @@ import com.iluwatar.doublechecked.locking.App;
*/
public class AppTest {
- @Test
- public void test() {
- String[] args = {};
- App.main(args);
- }
+ @Test
+ public void test() {
+ String[] args = {};
+ App.main(args);
+ }
}
diff --git a/double-checked-locking/src/test/java/com/iluwatar/doublechecked/locking/InventoryTest.java b/double-checked-locking/src/test/java/com/iluwatar/doublechecked/locking/InventoryTest.java
new file mode 100644
index 000000000..485c9573e
--- /dev/null
+++ b/double-checked-locking/src/test/java/com/iluwatar/doublechecked/locking/InventoryTest.java
@@ -0,0 +1,132 @@
+/**
+ * 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.doublechecked.locking;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+
+import java.io.PrintStream;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import static junit.framework.Assert.assertTrue;
+import static junit.framework.TestCase.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+
+/**
+ * Date: 12/10/15 - 9:34 PM
+ *
+ * @author Jeroen Meulemeester
+ */
+public class InventoryTest {
+
+ /**
+ * The mocked standard out {@link PrintStream}, used to verify a steady increasing size of the
+ * {@link Inventory} while adding items from multiple threads concurrently
+ */
+ private final PrintStream stdOutMock = mock(PrintStream.class);
+
+ /**
+ * Keep the original std-out so it can be restored after the test
+ */
+ private final PrintStream stdOutOrig = System.out;
+
+ /**
+ * Inject the mocked std-out {@link PrintStream} into the {@link System} class before each test
+ */
+ @Before
+ public void setUp() {
+ System.setOut(this.stdOutMock);
+ }
+
+ /**
+ * Removed the mocked std-out {@link PrintStream} again from the {@link System} class
+ */
+ @After
+ public void tearDown() {
+ System.setOut(this.stdOutOrig);
+ }
+
+ /**
+ * The number of threads used to stress test the locking of the {@link Inventory#addItem(Item)}
+ * method
+ */
+ private static final int THREAD_COUNT = 8;
+
+ /**
+ * The maximum number of {@link Item}s allowed in the {@link Inventory}
+ */
+ private static final int INVENTORY_SIZE = 1000;
+
+ /**
+ * Concurrently add multiple items to the inventory, and check if the items were added in order by
+ * checking the stdOut for continuous growth of the inventory. When 'items.size()=xx' shows up out
+ * of order, it means that the locking is not ok, increasing the risk of going over the inventory
+ * item limit.
+ */
+ @Test(timeout = 10000)
+ public void testAddItem() throws Exception {
+ // Create a new inventory with a limit of 1000 items and put some load on the add method
+ final Inventory inventory = new Inventory(INVENTORY_SIZE);
+ final ExecutorService executorService = Executors.newFixedThreadPool(THREAD_COUNT);
+ for (int i = 0; i < THREAD_COUNT; i++) {
+ executorService.execute(() -> {
+ while (inventory.addItem(new Item())) {};
+ });
+ }
+
+ // Wait until all threads have finished
+ executorService.shutdown();
+ executorService.awaitTermination(5, TimeUnit.SECONDS);
+
+ // Check the number of items in the inventory. It should not have exceeded the allowed maximum
+ final List
- items = inventory.getItems();
+ assertNotNull(items);
+ assertEquals(INVENTORY_SIZE, items.size());
+
+ // Capture all stdOut messages ...
+ final ArgumentCaptor
stdOutCaptor = ArgumentCaptor.forClass(String.class);
+ verify(this.stdOutMock, times(INVENTORY_SIZE)).println(stdOutCaptor.capture());
+
+ // ... verify if we got all 1000
+ final List values = stdOutCaptor.getAllValues();
+ assertEquals(INVENTORY_SIZE, values.size());
+
+ // ... and check if the inventory size is increasing continuously
+ for (int i = 0; i < values.size(); i++) {
+ assertNotNull(values.get(i));
+ assertTrue(values.get(i).contains("items.size()=" + (i + 1)));
+ }
+
+ verifyNoMoreInteractions(this.stdOutMock);
+ }
+
+}
\ No newline at end of file
diff --git a/double-dispatch/index.md b/double-dispatch/README.md
similarity index 69%
rename from double-dispatch/index.md
rename to double-dispatch/README.md
index 6847b7a41..ae87208a2 100644
--- a/double-dispatch/index.md
+++ b/double-dispatch/README.md
@@ -4,18 +4,23 @@ title: Double Dispatch
folder: double-dispatch
permalink: /patterns/double-dispatch/
categories: Other
-tags: Java
+tags:
+ - Java
+ - Difficulty-Intermediate
+ - Idiom
---
-**Intent:** Double Dispatch pattern is a way to create maintainable dynamic
+## Intent
+Double Dispatch pattern is a way to create maintainable dynamic
behavior based on receiver and parameter types.

-**Applicability:** Use the Double Dispatch pattern when
+## Applicability
+Use the Double Dispatch pattern when
* the dynamic behavior is not defined only based on receiving object's type but also on the receiving method's parameter type.
-**Real world examples:**
+## Real world examples
* [ObjectOutputStream](https://docs.oracle.com/javase/8/docs/api/java/io/ObjectOutputStream.html)
diff --git a/double-dispatch/pom.xml b/double-dispatch/pom.xml
index 057d75e8e..4f31b2e7e 100644
--- a/double-dispatch/pom.xml
+++ b/double-dispatch/pom.xml
@@ -1,11 +1,35 @@
+
4.0.0
com.iluwatar
java-design-patterns
- 1.7.0
+ 1.13.0-SNAPSHOT
double-dispatch
@@ -14,5 +38,10 @@
junit
test
+
+ org.mockito
+ mockito-core
+ test
+
diff --git a/double-dispatch/src/main/java/com/iluwatar/doubledispatch/App.java b/double-dispatch/src/main/java/com/iluwatar/doubledispatch/App.java
index f32c93cb1..40a0485a5 100644
--- a/double-dispatch/src/main/java/com/iluwatar/doubledispatch/App.java
+++ b/double-dispatch/src/main/java/com/iluwatar/doubledispatch/App.java
@@ -1,3 +1,25 @@
+/**
+ * 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.doubledispatch;
import java.util.ArrayList;
@@ -5,46 +27,50 @@ import java.util.List;
/**
*
- * When a message with a parameter is sent to an object, the resultant behaviour is defined by the
- * implementation of that method in the receiver. Sometimes the behaviour must also be determined
- * by the type of the parameter.
+ * When a message with a parameter is sent to an object, the resultant behaviour is defined by the implementation of
+ * that method in the receiver. Sometimes the behaviour must also be determined by the type of the parameter.
*
- * One way to implement this would be to create multiple instanceof-checks for the methods parameter.
- * However, this creates a maintenance issue. When new types are added we would also need to change
- * the method's implementation and add a new instanceof-check. This violates the single responsibility
- * principle - a class should have only one reason to change.
+ * One way to implement this would be to create multiple instanceof-checks for the methods parameter. However, this
+ * creates a maintenance issue. When new types are added we would also need to change the method's implementation and
+ * add a new instanceof-check. This violates the single responsibility principle - a class should have only one reason
+ * to change.
*
- * Instead of the instanceof-checks a better way is to make another virtual call on the parameter
- * object. This way new functionality can be easily added without the need to modify existing
- * implementation (open-closed principle).
+ * Instead of the instanceof-checks a better way is to make another virtual call on the parameter object. This way new
+ * functionality can be easily added without the need to modify existing implementation (open-closed principle).
*
- * In this example we have hierarchy of objects ({@link GameObject}) that can collide to each other. Each
- * object has its own coordinates which are checked against the other objects' coordinates. If
- * there is an overlap, then the objects collide utilizing the Double Dispatch pattern.
+ * In this example we have hierarchy of objects ({@link GameObject}) that can collide to each other. Each object has its
+ * own coordinates which are checked against the other objects' coordinates. If there is an overlap, then the objects
+ * collide utilizing the Double Dispatch pattern.
*
*/
public class App {
-
- /**
- * Program entry point
- * @param args command line args
- */
- public static void main( String[] args ) {
- // initialize game objects and print their status
- List objects = new ArrayList<>();
- objects.add(new FlamingAsteroid(0, 0, 5, 5));
- objects.add(new SpaceStationMir(1, 1, 2, 2));
- objects.add(new Meteoroid(10, 10, 15, 15));
- objects.add(new SpaceStationIss(12, 12, 14, 14));
- objects.stream().forEach(o -> System.out.println(o));
- System.out.println("");
-
- // collision check
- objects.stream().forEach(o1 -> objects.stream().forEach(o2 -> { if (o1 != o2 && o1.intersectsWith(o2)) o1.collision(o2); } ));
- System.out.println("");
-
- // output eventual object statuses
- objects.stream().forEach(o -> System.out.println(o));
- System.out.println("");
- }
+
+ /**
+ * Program entry point
+ *
+ * @param args
+ * command line args
+ */
+ public static void main(String[] args) {
+ // initialize game objects and print their status
+ List objects = new ArrayList<>();
+ objects.add(new FlamingAsteroid(0, 0, 5, 5));
+ objects.add(new SpaceStationMir(1, 1, 2, 2));
+ objects.add(new Meteoroid(10, 10, 15, 15));
+ objects.add(new SpaceStationIss(12, 12, 14, 14));
+ objects.stream().forEach(o -> System.out.println(o));
+ System.out.println("");
+
+ // collision check
+ objects.stream().forEach(o1 -> objects.stream().forEach(o2 -> {
+ if (o1 != o2 && o1.intersectsWith(o2)) {
+ o1.collision(o2);
+ }
+ }));
+ System.out.println("");
+
+ // output eventual object statuses
+ objects.stream().forEach(o -> System.out.println(o));
+ System.out.println("");
+ }
}
diff --git a/double-dispatch/src/main/java/com/iluwatar/doubledispatch/FlamingAsteroid.java b/double-dispatch/src/main/java/com/iluwatar/doubledispatch/FlamingAsteroid.java
index 73b633e5b..6cff89f58 100644
--- a/double-dispatch/src/main/java/com/iluwatar/doubledispatch/FlamingAsteroid.java
+++ b/double-dispatch/src/main/java/com/iluwatar/doubledispatch/FlamingAsteroid.java
@@ -1,3 +1,25 @@
+/**
+ * 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.doubledispatch;
/**
@@ -7,13 +29,13 @@ package com.iluwatar.doubledispatch;
*/
public class FlamingAsteroid extends Meteoroid {
- public FlamingAsteroid(int left, int top, int right, int bottom) {
- super(left, top, right, bottom);
- setOnFire(true);
- }
+ public FlamingAsteroid(int left, int top, int right, int bottom) {
+ super(left, top, right, bottom);
+ setOnFire(true);
+ }
- @Override
- public void collision(GameObject gameObject) {
- gameObject.collisionResolve(this);
- }
+ @Override
+ public void collision(GameObject gameObject) {
+ gameObject.collisionResolve(this);
+ }
}
diff --git a/double-dispatch/src/main/java/com/iluwatar/doubledispatch/GameObject.java b/double-dispatch/src/main/java/com/iluwatar/doubledispatch/GameObject.java
index afe05e9b2..fea0cdfd1 100644
--- a/double-dispatch/src/main/java/com/iluwatar/doubledispatch/GameObject.java
+++ b/double-dispatch/src/main/java/com/iluwatar/doubledispatch/GameObject.java
@@ -1,49 +1,70 @@
+/**
+ * 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.doubledispatch;
/**
*
- * Game objects have coordinates and some
- * other status information.
+ * Game objects have coordinates and some other status information.
*
*/
public abstract class GameObject extends Rectangle {
-
- private boolean damaged;
- private boolean onFire;
-
- public GameObject(int left, int top, int right, int bottom) {
- super(left, top, right, bottom);
- }
-
- @Override
- public String toString() {
- return String.format("%s at %s damaged=%b onFire=%b", this.getClass().getSimpleName(),
- super.toString(), isDamaged(), isOnFire());
- }
-
- public boolean isOnFire() {
- return onFire;
- }
-
- public void setOnFire(boolean onFire) {
- this.onFire = onFire;
- }
-
- public boolean isDamaged() {
- return damaged;
- }
-
- public void setDamaged(boolean damaged) {
- this.damaged = damaged;
- }
-
- public abstract void collision(GameObject gameObject);
-
- public abstract void collisionResolve(FlamingAsteroid asteroid);
- public abstract void collisionResolve(Meteoroid meteoroid);
+ private boolean damaged;
+ private boolean onFire;
- public abstract void collisionResolve(SpaceStationMir mir);
+ public GameObject(int left, int top, int right, int bottom) {
+ super(left, top, right, bottom);
+ }
- public abstract void collisionResolve(SpaceStationIss iss);
+ @Override
+ public String toString() {
+ return String.format("%s at %s damaged=%b onFire=%b", this.getClass().getSimpleName(),
+ super.toString(), isDamaged(), isOnFire());
+ }
+
+ public boolean isOnFire() {
+ return onFire;
+ }
+
+ public void setOnFire(boolean onFire) {
+ this.onFire = onFire;
+ }
+
+ public boolean isDamaged() {
+ return damaged;
+ }
+
+ public void setDamaged(boolean damaged) {
+ this.damaged = damaged;
+ }
+
+ public abstract void collision(GameObject gameObject);
+
+ public abstract void collisionResolve(FlamingAsteroid asteroid);
+
+ public abstract void collisionResolve(Meteoroid meteoroid);
+
+ public abstract void collisionResolve(SpaceStationMir mir);
+
+ public abstract void collisionResolve(SpaceStationIss iss);
}
diff --git a/double-dispatch/src/main/java/com/iluwatar/doubledispatch/Meteoroid.java b/double-dispatch/src/main/java/com/iluwatar/doubledispatch/Meteoroid.java
index fb59c49b4..cc68a85ec 100644
--- a/double-dispatch/src/main/java/com/iluwatar/doubledispatch/Meteoroid.java
+++ b/double-dispatch/src/main/java/com/iluwatar/doubledispatch/Meteoroid.java
@@ -1,3 +1,25 @@
+/**
+ * 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.doubledispatch;
/**
@@ -7,32 +29,36 @@ package com.iluwatar.doubledispatch;
*/
public class Meteoroid extends GameObject {
- public Meteoroid(int left, int top, int right, int bottom) {
- super(left, top, right, bottom);
- }
+ public Meteoroid(int left, int top, int right, int bottom) {
+ super(left, top, right, bottom);
+ }
- @Override
- public void collision(GameObject gameObject) {
- gameObject.collisionResolve(this);
- }
+ @Override
+ public void collision(GameObject gameObject) {
+ gameObject.collisionResolve(this);
+ }
- @Override
- public void collisionResolve(FlamingAsteroid asteroid) {
- System.out.println(String.format("%s hits %s.", asteroid.getClass().getSimpleName(), this.getClass().getSimpleName()));
- }
+ @Override
+ public void collisionResolve(FlamingAsteroid asteroid) {
+ System.out.println(String.format("%s hits %s.", asteroid.getClass().getSimpleName(), this
+ .getClass().getSimpleName()));
+ }
- @Override
- public void collisionResolve(Meteoroid meteoroid) {
- System.out.println(String.format("%s hits %s.", meteoroid.getClass().getSimpleName(), this.getClass().getSimpleName()));
- }
+ @Override
+ public void collisionResolve(Meteoroid meteoroid) {
+ System.out.println(String.format("%s hits %s.", meteoroid.getClass().getSimpleName(), this
+ .getClass().getSimpleName()));
+ }
- @Override
- public void collisionResolve(SpaceStationMir mir) {
- System.out.println(String.format("%s hits %s.", mir.getClass().getSimpleName(), this.getClass().getSimpleName()));
- }
+ @Override
+ public void collisionResolve(SpaceStationMir mir) {
+ System.out.println(String.format("%s hits %s.", mir.getClass().getSimpleName(), this.getClass()
+ .getSimpleName()));
+ }
- @Override
- public void collisionResolve(SpaceStationIss iss) {
- System.out.println(String.format("%s hits %s.", iss.getClass().getSimpleName(), this.getClass().getSimpleName()));
- }
+ @Override
+ public void collisionResolve(SpaceStationIss iss) {
+ System.out.println(String.format("%s hits %s.", iss.getClass().getSimpleName(), this.getClass()
+ .getSimpleName()));
+ }
}
diff --git a/double-dispatch/src/main/java/com/iluwatar/doubledispatch/Rectangle.java b/double-dispatch/src/main/java/com/iluwatar/doubledispatch/Rectangle.java
index 12aca0056..496bb8769 100644
--- a/double-dispatch/src/main/java/com/iluwatar/doubledispatch/Rectangle.java
+++ b/double-dispatch/src/main/java/com/iluwatar/doubledispatch/Rectangle.java
@@ -1,44 +1,72 @@
+/**
+ * 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.doubledispatch;
/**
*
- * Rectangle has coordinates and can be checked for overlap against
- * other Rectangles.
+ * Rectangle has coordinates and can be checked for overlap against other Rectangles.
*
*/
public class Rectangle {
- private int left;
- private int top;
- private int right;
- private int bottom;
+ private int left;
+ private int top;
+ private int right;
+ private int bottom;
- public Rectangle(int left, int top, int right, int bottom) {
- this.left = left;
- this.top = top;
- this.right = right;
- this.bottom = bottom;
- }
-
- public int getLeft() {
- return left;
- }
- public int getTop() {
- return top;
- }
- public int getRight() {
- return right;
- }
- public int getBottom() {
- return bottom;
- }
-
- boolean intersectsWith(Rectangle r) {
- return !(r.getLeft() > getRight() || r.getRight() < getLeft() || r.getTop() > getBottom() || r.getBottom() < getTop());
- }
-
- @Override
- public String toString() {
- return String.format("[%d,%d,%d,%d]", getLeft(), getTop(), getRight(), getBottom());
- }
+ /**
+ * Constructor
+ */
+ public Rectangle(int left, int top, int right, int bottom) {
+ this.left = left;
+ this.top = top;
+ this.right = right;
+ this.bottom = bottom;
+ }
+
+ public int getLeft() {
+ return left;
+ }
+
+ public int getTop() {
+ return top;
+ }
+
+ public int getRight() {
+ return right;
+ }
+
+ public int getBottom() {
+ return bottom;
+ }
+
+ boolean intersectsWith(Rectangle r) {
+ return !(r.getLeft() > getRight() || r.getRight() < getLeft() || r.getTop() > getBottom() || r
+ .getBottom() < getTop());
+ }
+
+ @Override
+ public String toString() {
+ return String.format("[%d,%d,%d,%d]", getLeft(), getTop(), getRight(), getBottom());
+ }
}
diff --git a/double-dispatch/src/main/java/com/iluwatar/doubledispatch/SpaceStationIss.java b/double-dispatch/src/main/java/com/iluwatar/doubledispatch/SpaceStationIss.java
index 50eae3df8..1150fc60b 100644
--- a/double-dispatch/src/main/java/com/iluwatar/doubledispatch/SpaceStationIss.java
+++ b/double-dispatch/src/main/java/com/iluwatar/doubledispatch/SpaceStationIss.java
@@ -1,3 +1,25 @@
+/**
+ * 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.doubledispatch;
/**
@@ -7,12 +29,12 @@ package com.iluwatar.doubledispatch;
*/
public class SpaceStationIss extends SpaceStationMir {
- public SpaceStationIss(int left, int top, int right, int bottom) {
- super(left, top, right, bottom);
- }
+ public SpaceStationIss(int left, int top, int right, int bottom) {
+ super(left, top, right, bottom);
+ }
- @Override
- public void collision(GameObject gameObject) {
- gameObject.collisionResolve(this);
- }
+ @Override
+ public void collision(GameObject gameObject) {
+ gameObject.collisionResolve(this);
+ }
}
diff --git a/double-dispatch/src/main/java/com/iluwatar/doubledispatch/SpaceStationMir.java b/double-dispatch/src/main/java/com/iluwatar/doubledispatch/SpaceStationMir.java
index 059b41271..e7a55d0ee 100644
--- a/double-dispatch/src/main/java/com/iluwatar/doubledispatch/SpaceStationMir.java
+++ b/double-dispatch/src/main/java/com/iluwatar/doubledispatch/SpaceStationMir.java
@@ -1,3 +1,25 @@
+/**
+ * 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.doubledispatch;
/**
@@ -7,45 +29,42 @@ package com.iluwatar.doubledispatch;
*/
public class SpaceStationMir extends GameObject {
- public SpaceStationMir(int left, int top, int right, int bottom) {
- super(left, top, right, bottom);
- }
+ public SpaceStationMir(int left, int top, int right, int bottom) {
+ super(left, top, right, bottom);
+ }
- @Override
- public void collision(GameObject gameObject) {
- gameObject.collisionResolve(this);
- }
+ @Override
+ public void collision(GameObject gameObject) {
+ gameObject.collisionResolve(this);
+ }
- @Override
- public void collisionResolve(FlamingAsteroid asteroid) {
- System.out.println(String.format("%s hits %s. %s is damaged! %s is set on fire!",
- asteroid.getClass().getSimpleName(), this.getClass().getSimpleName(),
- this.getClass().getSimpleName(), this.getClass().getSimpleName()));
- setDamaged(true);
- setOnFire(true);
- }
+ @Override
+ public void collisionResolve(FlamingAsteroid asteroid) {
+ System.out.println(String.format("%s hits %s. %s is damaged! %s is set on fire!", asteroid
+ .getClass().getSimpleName(), this.getClass().getSimpleName(), this.getClass()
+ .getSimpleName(), this.getClass().getSimpleName()));
+ setDamaged(true);
+ setOnFire(true);
+ }
- @Override
- public void collisionResolve(Meteoroid meteoroid) {
- System.out.println(String.format("%s hits %s. %s is damaged!",
- meteoroid.getClass().getSimpleName(), this.getClass().getSimpleName(),
- this.getClass().getSimpleName()));
- setDamaged(true);
- }
+ @Override
+ public void collisionResolve(Meteoroid meteoroid) {
+ System.out.println(String.format("%s hits %s. %s is damaged!", meteoroid.getClass()
+ .getSimpleName(), this.getClass().getSimpleName(), this.getClass().getSimpleName()));
+ setDamaged(true);
+ }
- @Override
- public void collisionResolve(SpaceStationMir mir) {
- System.out.println(String.format("%s hits %s. %s is damaged!",
- mir.getClass().getSimpleName(), this.getClass().getSimpleName(),
- this.getClass().getSimpleName()));
- setDamaged(true);
- }
+ @Override
+ public void collisionResolve(SpaceStationMir mir) {
+ System.out.println(String.format("%s hits %s. %s is damaged!", mir.getClass().getSimpleName(),
+ this.getClass().getSimpleName(), this.getClass().getSimpleName()));
+ setDamaged(true);
+ }
- @Override
- public void collisionResolve(SpaceStationIss iss) {
- System.out.println(String.format("%s hits %s. %s is damaged!",
- iss.getClass().getSimpleName(), this.getClass().getSimpleName(),
- this.getClass().getSimpleName()));
- setDamaged(true);
- }
+ @Override
+ public void collisionResolve(SpaceStationIss iss) {
+ System.out.println(String.format("%s hits %s. %s is damaged!", iss.getClass().getSimpleName(),
+ this.getClass().getSimpleName(), this.getClass().getSimpleName()));
+ setDamaged(true);
+ }
}
diff --git a/double-dispatch/src/test/java/com/iluwatar/doubledispatch/AppTest.java b/double-dispatch/src/test/java/com/iluwatar/doubledispatch/AppTest.java
index be93ee559..c1a6aa690 100644
--- a/double-dispatch/src/test/java/com/iluwatar/doubledispatch/AppTest.java
+++ b/double-dispatch/src/test/java/com/iluwatar/doubledispatch/AppTest.java
@@ -1,19 +1,39 @@
+/**
+ * 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.doubledispatch;
import org.junit.Test;
-import com.iluwatar.doubledispatch.App;
-
/**
*
* Application test
*
*/
public class AppTest {
-
- @Test
- public void test() {
- String[] args = {};
- App.main(args);
- }
+
+ @Test
+ public void test() {
+ String[] args = {};
+ App.main(args);
+ }
}
diff --git a/double-dispatch/src/test/java/com/iluwatar/doubledispatch/CollisionTest.java b/double-dispatch/src/test/java/com/iluwatar/doubledispatch/CollisionTest.java
new file mode 100644
index 000000000..dbc8fc55e
--- /dev/null
+++ b/double-dispatch/src/test/java/com/iluwatar/doubledispatch/CollisionTest.java
@@ -0,0 +1,158 @@
+/**
+ * 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.doubledispatch;
+
+import org.junit.After;
+import org.junit.Before;
+
+import java.io.PrintStream;
+import java.util.Objects;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+
+/**
+ * Date: 12/10/15 - 8:37 PM
+ *
+ * @author Jeroen Meulemeester
+ */
+public abstract class CollisionTest {
+
+ /**
+ * The mocked standard out {@link PrintStream}, required if some of the actions on the tested
+ * object don't have a direct influence on any other accessible objects, except for writing to
+ * std-out using {@link System#out}
+ */
+ private final PrintStream stdOutMock = mock(PrintStream.class);
+
+ /**
+ * Keep the original std-out so it can be restored after the test
+ */
+ private final PrintStream stdOutOrig = System.out;
+
+ /**
+ * Inject the mocked std-out {@link PrintStream} into the {@link System} class before each test
+ */
+ @Before
+ public void setUp() {
+ System.setOut(this.stdOutMock);
+ }
+
+ /**
+ * Removed the mocked std-out {@link PrintStream} again from the {@link System} class
+ */
+ @After
+ public void tearDown() {
+ System.setOut(this.stdOutOrig);
+ }
+
+ /**
+ * Get the mocked stdOut {@link PrintStream}
+ *
+ * @return The stdOut print stream mock, renewed before each test
+ */
+ final PrintStream getStdOutMock() {
+ return this.stdOutMock;
+ }
+
+ /**
+ * Get the tested object
+ *
+ * @return The tested object, should never return 'null'
+ */
+ abstract O getTestedObject();
+
+ /**
+ * Collide the tested item with the other given item and verify if the damage and fire state is as
+ * expected
+ *
+ * @param other The other object we have to collide with
+ * @param otherDamaged Indicates if the other object should be damaged after the collision
+ * @param otherOnFire Indicates if the other object should be burning after the collision
+ * @param thisDamaged Indicates if the test object should be damaged after the collision
+ * @param thisOnFire Indicates if the other object should be burning after the collision
+ * @param description The expected description of the collision
+ */
+ void testCollision(final GameObject other, final boolean otherDamaged, final boolean otherOnFire,
+ final boolean thisDamaged, final boolean thisOnFire, final String description) {
+
+ Objects.requireNonNull(other);
+ Objects.requireNonNull(getTestedObject());
+
+ final O tested = getTestedObject();
+
+ tested.collision(other);
+
+ verify(getStdOutMock(), times(1)).println(description);
+ verifyNoMoreInteractions(getStdOutMock());
+
+ testOnFire(other, tested, otherOnFire);
+ testDamaged(other, tested, otherDamaged);
+
+ testOnFire(tested, other, thisOnFire);
+ testDamaged(tested, other, thisDamaged);
+
+ }
+
+ /**
+ * Test if the fire state of the target matches the expected state after colliding with the given
+ * object
+ *
+ * @param target The target object
+ * @param other The other object
+ * @param expectTargetOnFire The expected state of fire on the target object
+ */
+ private void testOnFire(final GameObject target, final GameObject other, final boolean expectTargetOnFire) {
+ final String targetName = target.getClass().getSimpleName();
+ final String otherName = other.getClass().getSimpleName();
+
+ final String errorMessage = expectTargetOnFire
+ ? "Expected [" + targetName + "] to be on fire after colliding with [" + otherName + "] but it was not!"
+ : "Expected [" + targetName + "] not to be on fire after colliding with [" + otherName + "] but it was!";
+
+ assertEquals(errorMessage, expectTargetOnFire, target.isOnFire());
+ }
+
+ /**
+ * Test if the damage state of the target matches the expected state after colliding with the
+ * given object
+ *
+ * @param target The target object
+ * @param other The other object
+ * @param expectedDamage The expected state of damage on the target object
+ */
+ private void testDamaged(final GameObject target, final GameObject other, final boolean expectedDamage) {
+ final String targetName = target.getClass().getSimpleName();
+ final String otherName = other.getClass().getSimpleName();
+
+ final String errorMessage = expectedDamage
+ ? "Expected [" + targetName + "] to be damaged after colliding with [" + otherName + "] but it was not!"
+ : "Expected [" + targetName + "] not to be damaged after colliding with [" + otherName + "] but it was!";
+
+ assertEquals(errorMessage, expectedDamage, target.isDamaged());
+ }
+
+}
diff --git a/double-dispatch/src/test/java/com/iluwatar/doubledispatch/FlamingAsteroidTest.java b/double-dispatch/src/test/java/com/iluwatar/doubledispatch/FlamingAsteroidTest.java
new file mode 100644
index 000000000..31a16f093
--- /dev/null
+++ b/double-dispatch/src/test/java/com/iluwatar/doubledispatch/FlamingAsteroidTest.java
@@ -0,0 +1,110 @@
+/**
+ * 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.doubledispatch;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Date: 12/10/15 - 11:31 PM
+ *
+ * @author Jeroen Meulemeester
+ */
+public class FlamingAsteroidTest extends CollisionTest {
+
+ @Override
+ final FlamingAsteroid getTestedObject() {
+ return new FlamingAsteroid(1, 2, 3, 4);
+ }
+
+ /**
+ * Test the constructor parameters
+ */
+ @Test
+ public void testConstructor() {
+ final FlamingAsteroid asteroid = new FlamingAsteroid(1, 2, 3, 4);
+ assertEquals(1, asteroid.getLeft());
+ assertEquals(2, asteroid.getTop());
+ assertEquals(3, asteroid.getRight());
+ assertEquals(4, asteroid.getBottom());
+ assertTrue(asteroid.isOnFire());
+ assertFalse(asteroid.isDamaged());
+ assertEquals("FlamingAsteroid at [1,2,3,4] damaged=false onFire=true", asteroid.toString());
+ }
+
+ /**
+ * Test what happens we collide with an asteroid
+ */
+ @Test
+ public void testCollideFlamingAsteroid() {
+ testCollision(
+ new FlamingAsteroid(1, 2, 3, 4),
+ false, true,
+ false, true,
+ "FlamingAsteroid hits FlamingAsteroid."
+ );
+ }
+
+ /**
+ * Test what happens we collide with an meteoroid
+ */
+ @Test
+ public void testCollideMeteoroid() {
+ testCollision(
+ new Meteoroid(1, 1, 3, 4),
+ false, false,
+ false, true,
+ "FlamingAsteroid hits Meteoroid."
+ );
+ }
+
+ /**
+ * Test what happens we collide with ISS
+ */
+ @Test
+ public void testCollideSpaceStationIss() {
+ testCollision(
+ new SpaceStationIss(1, 1, 3, 4),
+ true, true,
+ false, true,
+ "FlamingAsteroid hits SpaceStationIss. SpaceStationIss is damaged! SpaceStationIss is set on fire!"
+ );
+ }
+
+ /**
+ * Test what happens we collide with MIR
+ */
+ @Test
+ public void testCollideSpaceStationMir() {
+ testCollision(
+ new SpaceStationMir(1, 1, 3, 4),
+ true, true,
+ false, true,
+ "FlamingAsteroid hits SpaceStationMir. SpaceStationMir is damaged! SpaceStationMir is set on fire!"
+ );
+ }
+
+}
\ No newline at end of file
diff --git a/double-dispatch/src/test/java/com/iluwatar/doubledispatch/MeteoroidTest.java b/double-dispatch/src/test/java/com/iluwatar/doubledispatch/MeteoroidTest.java
new file mode 100644
index 000000000..147fe430a
--- /dev/null
+++ b/double-dispatch/src/test/java/com/iluwatar/doubledispatch/MeteoroidTest.java
@@ -0,0 +1,109 @@
+/**
+ * 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.doubledispatch;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+/**
+ * Date: 12/10/15 - 11:31 PM
+ *
+ * @author Jeroen Meulemeester
+ */
+public class MeteoroidTest extends CollisionTest {
+
+ @Override
+ final Meteoroid getTestedObject() {
+ return new Meteoroid(1, 2, 3, 4);
+ }
+
+ /**
+ * Test the constructor parameters
+ */
+ @Test
+ public void testConstructor() {
+ final Meteoroid meteoroid = new Meteoroid(1, 2, 3, 4);
+ assertEquals(1, meteoroid.getLeft());
+ assertEquals(2, meteoroid.getTop());
+ assertEquals(3, meteoroid.getRight());
+ assertEquals(4, meteoroid.getBottom());
+ assertFalse(meteoroid.isOnFire());
+ assertFalse(meteoroid.isDamaged());
+ assertEquals("Meteoroid at [1,2,3,4] damaged=false onFire=false", meteoroid.toString());
+ }
+
+ /**
+ * Test what happens we collide with an asteroid
+ */
+ @Test
+ public void testCollideFlamingAsteroid() {
+ testCollision(
+ new FlamingAsteroid(1, 1, 3, 4),
+ false, true,
+ false, false,
+ "Meteoroid hits FlamingAsteroid."
+ );
+ }
+
+ /**
+ * Test what happens we collide with an meteoroid
+ */
+ @Test
+ public void testCollideMeteoroid() {
+ testCollision(
+ new Meteoroid(1, 1, 3, 4),
+ false, false,
+ false, false,
+ "Meteoroid hits Meteoroid."
+ );
+ }
+
+ /**
+ * Test what happens we collide with ISS
+ */
+ @Test
+ public void testCollideSpaceStationIss() {
+ testCollision(
+ new SpaceStationIss(1, 1, 3, 4),
+ true, false,
+ false, false,
+ "Meteoroid hits SpaceStationIss. SpaceStationIss is damaged!"
+ );
+ }
+
+ /**
+ * Test what happens we collide with MIR
+ */
+ @Test
+ public void testCollideSpaceStationMir() {
+ testCollision(
+ new SpaceStationMir(1, 1, 3, 4),
+ true, false,
+ false, false,
+ "Meteoroid hits SpaceStationMir. SpaceStationMir is damaged!"
+ );
+ }
+
+}
\ No newline at end of file
diff --git a/double-dispatch/src/test/java/com/iluwatar/doubledispatch/RectangleTest.java b/double-dispatch/src/test/java/com/iluwatar/doubledispatch/RectangleTest.java
index bb8aa954e..b7c0dbd2e 100644
--- a/double-dispatch/src/test/java/com/iluwatar/doubledispatch/RectangleTest.java
+++ b/double-dispatch/src/test/java/com/iluwatar/doubledispatch/RectangleTest.java
@@ -1,22 +1,69 @@
+/**
+ * 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.doubledispatch;
-import org.junit.Assert;
import org.junit.Test;
-import com.iluwatar.doubledispatch.Rectangle;
+import static junit.framework.TestCase.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
/**
- *
* Unit test for Rectangle
- *
*/
public class RectangleTest {
- @Test
- public void test() {
- Assert.assertTrue(new Rectangle(0,0,1,1).intersectsWith(new Rectangle(0,0,1,1)));
- Assert.assertTrue(new Rectangle(0,0,1,1).intersectsWith(new Rectangle(-1,-5,7,8)));
- Assert.assertFalse(new Rectangle(0,0,1,1).intersectsWith(new Rectangle(2,2,3,3)));
- Assert.assertFalse(new Rectangle(0,0,1,1).intersectsWith(new Rectangle(-2,-2,-1,-1)));
- }
+ /**
+ * Test if the values passed through the constructor matches the values fetched from the getters
+ */
+ @Test
+ public void testConstructor() {
+ final Rectangle rectangle = new Rectangle(1, 2, 3, 4);
+ assertEquals(1, rectangle.getLeft());
+ assertEquals(2, rectangle.getTop());
+ assertEquals(3, rectangle.getRight());
+ assertEquals(4, rectangle.getBottom());
+ }
+
+ /**
+ * Test if the values passed through the constructor matches the values in the {@link
+ * #toString()}
+ */
+ @Test
+ public void testToString() throws Exception {
+ final Rectangle rectangle = new Rectangle(1, 2, 3, 4);
+ assertEquals("[1,2,3,4]", rectangle.toString());
+ }
+
+ /**
+ * Test if the {@link Rectangle} class can detect if it intersects with another rectangle.
+ */
+ @Test
+ public void testIntersection() {
+ assertTrue(new Rectangle(0, 0, 1, 1).intersectsWith(new Rectangle(0, 0, 1, 1)));
+ assertTrue(new Rectangle(0, 0, 1, 1).intersectsWith(new Rectangle(-1, -5, 7, 8)));
+ assertFalse(new Rectangle(0, 0, 1, 1).intersectsWith(new Rectangle(2, 2, 3, 3)));
+ assertFalse(new Rectangle(0, 0, 1, 1).intersectsWith(new Rectangle(-2, -2, -1, -1)));
+ }
+
}
diff --git a/double-dispatch/src/test/java/com/iluwatar/doubledispatch/SpaceStationIssTest.java b/double-dispatch/src/test/java/com/iluwatar/doubledispatch/SpaceStationIssTest.java
new file mode 100644
index 000000000..d06f84b22
--- /dev/null
+++ b/double-dispatch/src/test/java/com/iluwatar/doubledispatch/SpaceStationIssTest.java
@@ -0,0 +1,109 @@
+/**
+ * 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.doubledispatch;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+/**
+ * Date: 12/10/15 - 11:31 PM
+ *
+ * @author Jeroen Meulemeester
+ */
+public class SpaceStationIssTest extends CollisionTest {
+
+ @Override
+ final SpaceStationIss getTestedObject() {
+ return new SpaceStationIss(1, 2, 3, 4);
+ }
+
+ /**
+ * Test the constructor parameters
+ */
+ @Test
+ public void testConstructor() {
+ final SpaceStationIss iss = new SpaceStationIss(1, 2, 3, 4);
+ assertEquals(1, iss.getLeft());
+ assertEquals(2, iss.getTop());
+ assertEquals(3, iss.getRight());
+ assertEquals(4, iss.getBottom());
+ assertFalse(iss.isOnFire());
+ assertFalse(iss.isDamaged());
+ assertEquals("SpaceStationIss at [1,2,3,4] damaged=false onFire=false", iss.toString());
+ }
+
+ /**
+ * Test what happens we collide with an asteroid
+ */
+ @Test
+ public void testCollideFlamingAsteroid() {
+ testCollision(
+ new FlamingAsteroid(1, 1, 3, 4),
+ false, true,
+ false, false,
+ "SpaceStationIss hits FlamingAsteroid."
+ );
+ }
+
+ /**
+ * Test what happens we collide with an meteoroid
+ */
+ @Test
+ public void testCollideMeteoroid() {
+ testCollision(
+ new Meteoroid(1, 1, 3, 4),
+ false, false,
+ false, false,
+ "SpaceStationIss hits Meteoroid."
+ );
+ }
+
+ /**
+ * Test what happens we collide with ISS
+ */
+ @Test
+ public void testCollideSpaceStationIss() {
+ testCollision(
+ new SpaceStationIss(1, 1, 3, 4),
+ true, false,
+ false, false,
+ "SpaceStationIss hits SpaceStationIss. SpaceStationIss is damaged!"
+ );
+ }
+
+ /**
+ * Test what happens we collide with MIR
+ */
+ @Test
+ public void testCollideSpaceStationMir() {
+ testCollision(
+ new SpaceStationMir(1, 1, 3, 4),
+ true, false,
+ false, false,
+ "SpaceStationIss hits SpaceStationMir. SpaceStationMir is damaged!"
+ );
+ }
+
+}
\ No newline at end of file
diff --git a/double-dispatch/src/test/java/com/iluwatar/doubledispatch/SpaceStationMirTest.java b/double-dispatch/src/test/java/com/iluwatar/doubledispatch/SpaceStationMirTest.java
new file mode 100644
index 000000000..c107aed8b
--- /dev/null
+++ b/double-dispatch/src/test/java/com/iluwatar/doubledispatch/SpaceStationMirTest.java
@@ -0,0 +1,109 @@
+/**
+ * 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.doubledispatch;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+/**
+ * Date: 12/10/15 - 11:31 PM
+ *
+ * @author Jeroen Meulemeester
+ */
+public class SpaceStationMirTest extends CollisionTest {
+
+ @Override
+ final SpaceStationMir getTestedObject() {
+ return new SpaceStationMir(1, 2, 3, 4);
+ }
+
+ /**
+ * Test the constructor parameters
+ */
+ @Test
+ public void testConstructor() {
+ final SpaceStationMir mir = new SpaceStationMir(1, 2, 3, 4);
+ assertEquals(1, mir.getLeft());
+ assertEquals(2, mir.getTop());
+ assertEquals(3, mir.getRight());
+ assertEquals(4, mir.getBottom());
+ assertFalse(mir.isOnFire());
+ assertFalse(mir.isDamaged());
+ assertEquals("SpaceStationMir at [1,2,3,4] damaged=false onFire=false", mir.toString());
+ }
+
+ /**
+ * Test what happens we collide with an asteroid
+ */
+ @Test
+ public void testCollideFlamingAsteroid() {
+ testCollision(
+ new FlamingAsteroid(1, 1, 3, 4),
+ false, true,
+ false, false,
+ "SpaceStationMir hits FlamingAsteroid."
+ );
+ }
+
+ /**
+ * Test what happens we collide with an meteoroid
+ */
+ @Test
+ public void testCollideMeteoroid() {
+ testCollision(
+ new Meteoroid(1, 1, 3, 4),
+ false, false,
+ false, false,
+ "SpaceStationMir hits Meteoroid."
+ );
+ }
+
+ /**
+ * Test what happens we collide with ISS
+ */
+ @Test
+ public void testCollideSpaceStationIss() {
+ testCollision(
+ new SpaceStationIss(1, 1, 3, 4),
+ true, false,
+ false, false,
+ "SpaceStationMir hits SpaceStationIss. SpaceStationIss is damaged!"
+ );
+ }
+
+ /**
+ * Test what happens we collide with MIR
+ */
+ @Test
+ public void testCollideSpaceStationMir() {
+ testCollision(
+ new SpaceStationMir(1, 1, 3, 4),
+ true, false,
+ false, false,
+ "SpaceStationMir hits SpaceStationMir. SpaceStationMir is damaged!"
+ );
+ }
+
+}
\ No newline at end of file
diff --git a/event-aggregator/index.md b/event-aggregator/README.md
similarity index 84%
rename from event-aggregator/index.md
rename to event-aggregator/README.md
index 1c89c7188..ac07869e7 100644
--- a/event-aggregator/index.md
+++ b/event-aggregator/README.md
@@ -4,10 +4,14 @@ title: Event Aggregator
folder: event-aggregator
permalink: /patterns/event-aggregator/
categories: Structural
-tags: Java
+tags:
+ - Java
+ - Difficulty-Beginner
+ - Reactive
---
-**Intent:** A system with lots of objects can lead to complexities when a
+## Intent
+A system with lots of objects can lead to complexities when a
client wants to subscribe to events. The client has to find and register for
each object individually, if each object has multiple events then each event
requires a separate subscription. An Event Aggregator acts as a single source
@@ -16,7 +20,8 @@ allowing clients to register with just the aggregator.

-**Applicability:** Use the Event Aggregator pattern when
+## Applicability
+Use the Event Aggregator pattern when
* Event Aggregator is a good choice when you have lots of objects that are
potential event sources. Rather than have the observer deal with registering
@@ -24,6 +29,6 @@ allowing clients to register with just the aggregator.
Aggregator. As well as simplifying registration, a Event Aggregator also
simplifies the memory management issues in using observers.
-**Credits:**
+## Credits
* [Martin Fowler - Event Aggregator](http://martinfowler.com/eaaDev/EventAggregator.html)
diff --git a/event-aggregator/pom.xml b/event-aggregator/pom.xml
index 4e7f1b55b..b7de6e01b 100644
--- a/event-aggregator/pom.xml
+++ b/event-aggregator/pom.xml
@@ -1,10 +1,34 @@
+