res = this.find(txt);
+ res.addAll(orFinder.find(txt));
+ return res;
+ };
+ }
+
+ /**
+ * combinator or.
+ * @param andFinder finder to combine
+ * @return new finder including previous finders
+ */
+ default Finder and(Finder andFinder) {
+ return
+ txt -> this
+ .find(txt)
+ .stream()
+ .flatMap(line -> andFinder.find(line).stream())
+ .collect(Collectors.toList());
+ }
+
+}
diff --git a/combinator/src/main/java/com/iluwatar/combinator/Finders.java b/combinator/src/main/java/com/iluwatar/combinator/Finders.java
new file mode 100644
index 000000000000..f91c07f4c4ad
--- /dev/null
+++ b/combinator/src/main/java/com/iluwatar/combinator/Finders.java
@@ -0,0 +1,103 @@
+/*
+ * The MIT License
+ * Copyright © 2014-2019 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.combinator;
+
+import java.util.ArrayList;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * Complex finders consisting of simple finder.
+ */
+public class Finders {
+ private Finders() {
+ }
+
+
+ /**
+ * Finder to find a complex query.
+ * @param query to find
+ * @param orQuery alternative to find
+ * @param notQuery exclude from search
+ * @return new finder
+ */
+ public static Finder advancedFinder(String query, String orQuery, String notQuery) {
+ return
+ Finder.contains(query)
+ .or(Finder.contains(orQuery))
+ .not(Finder.contains(notQuery));
+ }
+
+ /**
+ * Filtered finder looking a query with excluded queries as well.
+ * @param query to find
+ * @param excludeQueries to exclude
+ * @return new finder
+ */
+ public static Finder filteredFinder(String query, String... excludeQueries) {
+ var finder = Finder.contains(query);
+
+ for (String q : excludeQueries) {
+ finder = finder.not(Finder.contains(q));
+ }
+ return finder;
+
+ }
+
+ /**
+ * Specialized query. Every next query is looked in previous result.
+ * @param queries array with queries
+ * @return new finder
+ */
+ public static Finder specializedFinder(String... queries) {
+ var finder = identMult();
+
+ for (String query : queries) {
+ finder = finder.and(Finder.contains(query));
+ }
+ return finder;
+ }
+
+ /**
+ * Expanded query. Looking for alternatives.
+ * @param queries array with queries.
+ * @return new finder
+ */
+ public static Finder expandedFinder(String... queries) {
+ var finder = identSum();
+
+ for (String query : queries) {
+ finder = finder.or(Finder.contains(query));
+ }
+ return finder;
+ }
+
+ private static Finder identMult() {
+ return txt -> Stream.of(txt.split("\n")).collect(Collectors.toList());
+ }
+
+ private static Finder identSum() {
+ return txt -> new ArrayList<>();
+ }
+}
diff --git a/combinator/src/test/java/com/iluwatar/combinator/CombinatorAppTest.java b/combinator/src/test/java/com/iluwatar/combinator/CombinatorAppTest.java
new file mode 100644
index 000000000000..f42b46c1407f
--- /dev/null
+++ b/combinator/src/test/java/com/iluwatar/combinator/CombinatorAppTest.java
@@ -0,0 +1,36 @@
+/*
+ * The MIT License
+ * Copyright © 2014-2019 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.combinator;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class CombinatorAppTest {
+
+ @Test
+ public void main() {
+ CombinatorApp.main(new String[]{});
+ }
+}
\ No newline at end of file
diff --git a/prototype/src/test/java/com/iluwatar/prototype/HeroFactoryImplTest.java b/combinator/src/test/java/com/iluwatar/combinator/FinderTest.java
similarity index 50%
rename from prototype/src/test/java/com/iluwatar/prototype/HeroFactoryImplTest.java
rename to combinator/src/test/java/com/iluwatar/combinator/FinderTest.java
index 0d33b67c3796..67314903da50 100644
--- a/prototype/src/test/java/com/iluwatar/prototype/HeroFactoryImplTest.java
+++ b/combinator/src/test/java/com/iluwatar/combinator/FinderTest.java
@@ -21,42 +21,24 @@
* THE SOFTWARE.
*/
-package com.iluwatar.prototype;
+package com.iluwatar.combinator;
-import org.junit.jupiter.api.Test;
+import org.junit.Assert;
+import org.junit.Test;
-import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
+import java.util.List;
-/**
- * Date: 12/28/15 - 8:34 PM
- *
- * @author Jeroen Meulemeester
- */
-public class HeroFactoryImplTest {
+import static org.junit.Assert.*;
+
+public class FinderTest {
@Test
- public void testFactory() throws Exception {
- final Mage mage = mock(Mage.class);
- final Warlord warlord = mock(Warlord.class);
- final Beast beast = mock(Beast.class);
-
- when(mage.copy()).thenThrow(CloneNotSupportedException.class);
- when(warlord.copy()).thenThrow(CloneNotSupportedException.class);
- when(beast.copy()).thenThrow(CloneNotSupportedException.class);
-
- final HeroFactoryImpl factory = new HeroFactoryImpl(mage, warlord, beast);
- assertNull(factory.createMage());
- assertNull(factory.createWarlord());
- assertNull(factory.createBeast());
-
- verify(mage).copy();
- verify(warlord).copy();
- verify(beast).copy();
- verifyNoMoreInteractions(mage, warlord, beast);
+ public void contains() {
+ var example = "the first one \nthe second one \n";
+
+ var result = Finder.contains("second").find(example);
+ Assert.assertEquals(result.size(),1);
+ Assert.assertEquals(result.get(0),"the second one ");
}
}
\ No newline at end of file
diff --git a/combinator/src/test/java/com/iluwatar/combinator/FindersTest.java b/combinator/src/test/java/com/iluwatar/combinator/FindersTest.java
new file mode 100644
index 000000000000..5753ec92a222
--- /dev/null
+++ b/combinator/src/test/java/com/iluwatar/combinator/FindersTest.java
@@ -0,0 +1,83 @@
+/*
+ * The MIT License
+ * Copyright © 2014-2019 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.combinator;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.List;
+
+import static com.iluwatar.combinator.Finders.*;
+import static org.junit.Assert.*;
+
+public class FindersTest {
+
+ @Test
+ public void advancedFinderTest() {
+ var res = advancedFinder("it was","kingdom","sea").find(text());
+ Assert.assertEquals(res.size(),1);
+ Assert.assertEquals(res.get(0),"It was many and many a year ago,");
+ }
+
+ @Test
+ public void filteredFinderTest() {
+ var res = filteredFinder(" was ", "many", "child").find(text());
+ Assert.assertEquals(res.size(),1);
+ Assert.assertEquals(res.get(0),"But we loved with a love that was more than love-");
+ }
+
+ @Test
+ public void specializedFinderTest() {
+ var res = specializedFinder("love","heaven").find(text());
+ Assert.assertEquals(res.size(),1);
+ Assert.assertEquals(res.get(0),"With a love that the winged seraphs of heaven");
+ }
+
+ @Test
+ public void expandedFinderTest() {
+ var res = expandedFinder("It was","kingdom").find(text());
+ Assert.assertEquals(res.size(),3);
+ Assert.assertEquals(res.get(0),"It was many and many a year ago,");
+ Assert.assertEquals(res.get(1),"In a kingdom by the sea,");
+ Assert.assertEquals(res.get(2),"In this kingdom by the sea;");
+ }
+
+
+ private String text(){
+ return
+ "It was many and many a year ago,\n"
+ + "In a kingdom by the sea,\n"
+ + "That a maiden there lived whom you may know\n"
+ + "By the name of ANNABEL LEE;\n"
+ + "And this maiden she lived with no other thought\n"
+ + "Than to love and be loved by me.\n"
+ + "I was a child and she was a child,\n"
+ + "In this kingdom by the sea;\n"
+ + "But we loved with a love that was more than love-\n"
+ + "I and my Annabel Lee;\n"
+ + "With a love that the winged seraphs of heaven\n"
+ + "Coveted her and me.";
+ }
+
+}
\ No newline at end of file
diff --git a/decorator/src/main/java/com/iluwatar/decorator/App.java b/decorator/src/main/java/com/iluwatar/decorator/App.java
index 348e5623d4c3..9d28bd10876f 100644
--- a/decorator/src/main/java/com/iluwatar/decorator/App.java
+++ b/decorator/src/main/java/com/iluwatar/decorator/App.java
@@ -28,7 +28,7 @@
/**
* The Decorator pattern is a more flexible alternative to subclassing. The Decorator class
- * implements the same interface as the target and uses aggregation to "decorate" calls to the
+ * 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.
*
diff --git a/pom.xml b/pom.xml
index 39582fd93718..63cef06f5a35 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,29 +1,21 @@
-
-
+
4.0.0
com.iluwatar
@@ -176,18 +168,20 @@
master-worker-pattern
spatial-partition
priority-queue
- commander
- typeobjectpattern
+ commander
+ typeobjectpattern
bytecode
leader-election
data-locality
subclass-sandbox
circuit-breaker
role-object
- saga
+ saga
double-buffer
sharding
game-loop
+ combinator
+ update-method
@@ -381,6 +375,28 @@
spring-boot-maven-plugin
${spring-boot.version}
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+
+
+ package
+
+ single
+
+
+
+ jar-with-dependencies
+
+
+ ${project.artifactId}
+ false
+
+
+
+
@@ -408,9 +424,9 @@
-
+
org.commonjava.maven.plugins
directory-maven-plugin
@@ -432,7 +448,6 @@
-
com.mycila
license-maven-plugin
@@ -483,10 +498,8 @@
-
-
@@ -497,4 +510,4 @@
-
+
\ No newline at end of file
diff --git a/prototype/README.md b/prototype/README.md
index 483a5e469274..4cb8c0365c83 100644
--- a/prototype/README.md
+++ b/prototype/README.md
@@ -40,8 +40,12 @@ class Sheep implements Cloneable {
public void setName(String name) { this.name = name; }
public String getName() { return name; }
@Override
- public Sheep clone() throws CloneNotSupportedException {
- return new Sheep(name);
+ public Sheep clone() {
+ try {
+ return (Sheep)super.clone();
+ } catch(CloneNotSuportedException) {
+ throw new InternalError();
+ }
}
}
```
diff --git a/prototype/src/main/java/com/iluwatar/prototype/Beast.java b/prototype/src/main/java/com/iluwatar/prototype/Beast.java
index e3b25b850d19..c6797fd29a0b 100644
--- a/prototype/src/main/java/com/iluwatar/prototype/Beast.java
+++ b/prototype/src/main/java/com/iluwatar/prototype/Beast.java
@@ -26,9 +26,24 @@
/**
* Beast.
*/
-public abstract class Beast extends Prototype {
+public abstract class Beast implements Prototype {
+
+ public Beast() { }
+
+ public Beast(Beast source) { }
+
+ @Override
+ public abstract Beast copy();
@Override
- public abstract Beast copy() throws CloneNotSupportedException;
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ return getClass() == obj.getClass();
+ }
}
diff --git a/prototype/src/main/java/com/iluwatar/prototype/ElfBeast.java b/prototype/src/main/java/com/iluwatar/prototype/ElfBeast.java
index 50761964a4ac..e88f11699c83 100644
--- a/prototype/src/main/java/com/iluwatar/prototype/ElfBeast.java
+++ b/prototype/src/main/java/com/iluwatar/prototype/ElfBeast.java
@@ -35,11 +35,12 @@ public ElfBeast(String helpType) {
}
public ElfBeast(ElfBeast elfBeast) {
+ super(elfBeast);
this.helpType = elfBeast.helpType;
}
@Override
- public Beast copy() {
+ public ElfBeast copy() {
return new ElfBeast(this);
}
@@ -48,4 +49,26 @@ public String toString() {
return "Elven eagle helps in " + helpType;
}
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!super.equals(obj)) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ ElfBeast other = (ElfBeast) obj;
+ if (helpType == null) {
+ if (other.helpType != null) {
+ return false;
+ }
+ } else if (!helpType.equals(other.helpType)) {
+ return false;
+ }
+ return true;
+ }
+
}
diff --git a/prototype/src/main/java/com/iluwatar/prototype/ElfMage.java b/prototype/src/main/java/com/iluwatar/prototype/ElfMage.java
index 014c39bac2e5..d569a18c2482 100644
--- a/prototype/src/main/java/com/iluwatar/prototype/ElfMage.java
+++ b/prototype/src/main/java/com/iluwatar/prototype/ElfMage.java
@@ -28,7 +28,6 @@
*/
public class ElfMage extends Mage {
-
private String helpType;
public ElfMage(String helpType) {
@@ -36,6 +35,7 @@ public ElfMage(String helpType) {
}
public ElfMage(ElfMage elfMage) {
+ super(elfMage);
this.helpType = elfMage.helpType;
}
@@ -49,4 +49,25 @@ public String toString() {
return "Elven mage helps in " + helpType;
}
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!super.equals(obj)) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ ElfMage other = (ElfMage) obj;
+ if (helpType == null) {
+ if (other.helpType != null) {
+ return false;
+ }
+ } else if (!helpType.equals(other.helpType)) {
+ return false;
+ }
+ return true;
+ }
}
diff --git a/prototype/src/main/java/com/iluwatar/prototype/ElfWarlord.java b/prototype/src/main/java/com/iluwatar/prototype/ElfWarlord.java
index 43cdac7e5747..3484198d5316 100644
--- a/prototype/src/main/java/com/iluwatar/prototype/ElfWarlord.java
+++ b/prototype/src/main/java/com/iluwatar/prototype/ElfWarlord.java
@@ -35,6 +35,7 @@ public ElfWarlord(String helpType) {
}
public ElfWarlord(ElfWarlord elfWarlord) {
+ super(elfWarlord);
this.helpType = elfWarlord.helpType;
}
@@ -48,4 +49,25 @@ public String toString() {
return "Elven warlord helps in " + helpType;
}
-}
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!super.equals(obj)) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ ElfWarlord other = (ElfWarlord) obj;
+ if (helpType == null) {
+ if (other.helpType != null) {
+ return false;
+ }
+ } else if (!helpType.equals(other.helpType)) {
+ return false;
+ }
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/prototype/src/main/java/com/iluwatar/prototype/HeroFactoryImpl.java b/prototype/src/main/java/com/iluwatar/prototype/HeroFactoryImpl.java
index b9348a3b22b8..eb84b2982c57 100644
--- a/prototype/src/main/java/com/iluwatar/prototype/HeroFactoryImpl.java
+++ b/prototype/src/main/java/com/iluwatar/prototype/HeroFactoryImpl.java
@@ -45,33 +45,21 @@ public HeroFactoryImpl(Mage mage, Warlord warlord, Beast beast) {
* Create mage.
*/
public Mage createMage() {
- try {
- return mage.copy();
- } catch (CloneNotSupportedException e) {
- return null;
- }
+ return mage.copy();
}
/**
* Create warlord.
*/
public Warlord createWarlord() {
- try {
- return warlord.copy();
- } catch (CloneNotSupportedException e) {
- return null;
- }
+ return warlord.copy();
}
/**
* Create beast.
*/
public Beast createBeast() {
- try {
- return beast.copy();
- } catch (CloneNotSupportedException e) {
- return null;
- }
+ return beast.copy();
}
}
diff --git a/prototype/src/main/java/com/iluwatar/prototype/Mage.java b/prototype/src/main/java/com/iluwatar/prototype/Mage.java
index 27c3bae7a191..f8a597805feb 100644
--- a/prototype/src/main/java/com/iluwatar/prototype/Mage.java
+++ b/prototype/src/main/java/com/iluwatar/prototype/Mage.java
@@ -26,9 +26,24 @@
/**
* Mage.
*/
-public abstract class Mage extends Prototype {
+public abstract class Mage implements Prototype {
+
+ public Mage() { }
+
+ public Mage(Mage source) { }
+
+ @Override
+ public abstract Mage copy();
@Override
- public abstract Mage copy() throws CloneNotSupportedException;
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ return getClass() == obj.getClass();
+ }
}
diff --git a/prototype/src/main/java/com/iluwatar/prototype/OrcBeast.java b/prototype/src/main/java/com/iluwatar/prototype/OrcBeast.java
index c800b3ac51e6..020063616f19 100644
--- a/prototype/src/main/java/com/iluwatar/prototype/OrcBeast.java
+++ b/prototype/src/main/java/com/iluwatar/prototype/OrcBeast.java
@@ -35,11 +35,12 @@ public OrcBeast(String weapon) {
}
public OrcBeast(OrcBeast orcBeast) {
+ super(orcBeast);
this.weapon = orcBeast.weapon;
}
@Override
- public Beast copy() {
+ public OrcBeast copy() {
return new OrcBeast(this);
}
@@ -48,5 +49,27 @@ public String toString() {
return "Orcish wolf attacks with " + weapon;
}
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!super.equals(obj)) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ OrcBeast other = (OrcBeast) obj;
+ if (weapon == null) {
+ if (other.weapon != null) {
+ return false;
+ }
+ } else if (!weapon.equals(other.weapon)) {
+ return false;
+ }
+ return true;
+ }
+
}
diff --git a/prototype/src/main/java/com/iluwatar/prototype/OrcMage.java b/prototype/src/main/java/com/iluwatar/prototype/OrcMage.java
index c71b59d06c54..e14145434f43 100644
--- a/prototype/src/main/java/com/iluwatar/prototype/OrcMage.java
+++ b/prototype/src/main/java/com/iluwatar/prototype/OrcMage.java
@@ -35,6 +35,7 @@ public OrcMage(String weapon) {
}
public OrcMage(OrcMage orcMage) {
+ super(orcMage);
this.weapon = orcMage.weapon;
}
@@ -48,4 +49,25 @@ public String toString() {
return "Orcish mage attacks with " + weapon;
}
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!super.equals(obj)) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ OrcMage other = (OrcMage) obj;
+ if (weapon == null) {
+ if (other.weapon != null) {
+ return false;
+ }
+ } else if (!weapon.equals(other.weapon)) {
+ return false;
+ }
+ return true;
+ }
}
diff --git a/prototype/src/main/java/com/iluwatar/prototype/OrcWarlord.java b/prototype/src/main/java/com/iluwatar/prototype/OrcWarlord.java
index 096fd49dc9c0..cc5e17d8e9c3 100644
--- a/prototype/src/main/java/com/iluwatar/prototype/OrcWarlord.java
+++ b/prototype/src/main/java/com/iluwatar/prototype/OrcWarlord.java
@@ -35,6 +35,7 @@ public OrcWarlord(String weapon) {
}
public OrcWarlord(OrcWarlord orcWarlord) {
+ super(orcWarlord);
this.weapon = orcWarlord.weapon;
}
@@ -48,4 +49,25 @@ public String toString() {
return "Orcish warlord attacks with " + weapon;
}
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!super.equals(obj)) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ OrcWarlord other = (OrcWarlord) obj;
+ if (weapon == null) {
+ if (other.weapon != null) {
+ return false;
+ }
+ } else if (!weapon.equals(other.weapon)) {
+ return false;
+ }
+ return true;
+ }
}
diff --git a/prototype/src/main/java/com/iluwatar/prototype/Prototype.java b/prototype/src/main/java/com/iluwatar/prototype/Prototype.java
index c74c82f4ad6b..d4c518ec2f16 100644
--- a/prototype/src/main/java/com/iluwatar/prototype/Prototype.java
+++ b/prototype/src/main/java/com/iluwatar/prototype/Prototype.java
@@ -26,8 +26,8 @@
/**
* Prototype.
*/
-public abstract class Prototype implements Cloneable {
+public interface Prototype {
- public abstract Object copy() throws CloneNotSupportedException;
+ Object copy();
}
diff --git a/prototype/src/main/java/com/iluwatar/prototype/Warlord.java b/prototype/src/main/java/com/iluwatar/prototype/Warlord.java
index c270ab80bd0d..30a3cd75cd92 100644
--- a/prototype/src/main/java/com/iluwatar/prototype/Warlord.java
+++ b/prototype/src/main/java/com/iluwatar/prototype/Warlord.java
@@ -26,9 +26,24 @@
/**
* Warlord.
*/
-public abstract class Warlord extends Prototype {
+public abstract class Warlord implements Prototype {
+
+ public Warlord() { }
+
+ public Warlord(Warlord source) { }
+
+ @Override
+ public abstract Warlord copy();
@Override
- public abstract Warlord copy() throws CloneNotSupportedException;
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ return getClass() == obj.getClass();
+ }
}
diff --git a/prototype/src/test/java/com/iluwatar/prototype/PrototypeTest.java b/prototype/src/test/java/com/iluwatar/prototype/PrototypeTest.java
index e4dd0658a0d8..579746ecc6c1 100644
--- a/prototype/src/test/java/com/iluwatar/prototype/PrototypeTest.java
+++ b/prototype/src/test/java/com/iluwatar/prototype/PrototypeTest.java
@@ -57,6 +57,7 @@ public void testPrototype(P testedPrototype, String expectedToString) throws Exc
assertNotNull(clone);
assertNotSame(clone, testedPrototype);
assertSame(testedPrototype.getClass(), clone.getClass());
+ assertEquals(clone, testedPrototype);
}
}
diff --git a/template-method/README.md b/template-method/README.md
index 5a1402259f4b..22c2ac2c3e65 100644
--- a/template-method/README.md
+++ b/template-method/README.md
@@ -15,11 +15,12 @@ Define the skeleton of an algorithm in an operation, deferring some
steps to subclasses. Template method lets subclasses redefine certain steps of
an algorithm without changing the algorithm's structure.
+To make sure that subclasses don’t override the template method, the template method should be declared `final`.
+

## Applicability
The Template Method pattern should be used
-
* to implement the invariant parts of an algorithm once and leave it up to subclasses to implement the behavior that can vary
* when common behavior among subclasses should be factored and localized in a common class to avoid code duplication. This is good example of "refactoring to generalize" as described by Opdyke and Johnson. You first identify the differences in the existing code and then separate the differences into new operations. Finally, you replace the differing code with a template method that calls one of these new operations
* to control subclasses extensions. You can define a template method that calls "hook" operations at specific points, thereby permitting extensions only at those points
@@ -27,6 +28,10 @@ The Template Method pattern should be used
## Tutorial
* [Template-method Pattern Tutorial](https://www.journaldev.com/1763/template-method-design-pattern-in-java)
-## Credits
+## Real world examples
+* [javax.servlet.GenericServlet.init](https://jakarta.ee/specifications/servlet/4.0/apidocs/javax/servlet/GenericServlet.html#init--):
+Method `GenericServlet.init(ServletConfig config)` calls the parameterless method `GenericServlet.init()` which is intended to be overridden in subclasses.
+Method `GenericServlet.init(ServletConfig config)` is the template method in this example.
+## Credits
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)
diff --git a/twin/src/main/java/com/iluwatar/twin/App.java b/twin/src/main/java/com/iluwatar/twin/App.java
index 5789d163a5ec..ccd91f6e0b7b 100644
--- a/twin/src/main/java/com/iluwatar/twin/App.java
+++ b/twin/src/main/java/com/iluwatar/twin/App.java
@@ -25,10 +25,10 @@
/**
* Twin pattern is a design pattern which provides a standard solution to simulate multiple
- * inheritance in java.
+ * inheritance in Java.
*
* In this example, the essence of the Twin pattern is the {@link BallItem} class and {@link
- * BallThread} class represent the twin objects to coordinate with each other(via the twin
+ * BallThread} class represent the twin objects to coordinate with each other (via the twin
* reference) like a single class inheriting from {@link GameItem} and {@link Thread}.
*/
diff --git a/update-method/README.md b/update-method/README.md
new file mode 100644
index 000000000000..50cba44f34c5
--- /dev/null
+++ b/update-method/README.md
@@ -0,0 +1,35 @@
+---
+layout: pattern
+title: Update Method
+folder: update-method
+permalink: /patterns/update-method/
+categories: Other
+tags:
+ - Java
+ - Difficulty-Beginner
+---
+
+## Intent
+Update method pattern simulates a collection of independent objects by telling each to process one frame of behavior at a time.
+
+## Applicability
+If the Game Loop pattern is the best thing since sliced bread, then the Update Method pattern is its butter. A wide swath of games featuring live entities that the player interacts with use this pattern in some form or other. If the game has space marines, dragons, Martians, ghosts, or athletes, there’s a good chance it uses this pattern.
+
+However, if the game is more abstract and the moving pieces are less like living actors and more like pieces on a chessboard, this pattern is often a poor fit. In a game like chess, you don’t need to simulate all of the pieces concurrently, and you probably don’t need to tell the pawns to update themselves every frame.
+
+Update methods work well when:
+
+- Your game has a number of objects or systems that need to run simultaneously.
+
+- Each object’s behavior is mostly independent of the others.
+
+- The objects need to be simulated over time.
+
+## Explanation
+The game world maintains a collection of objects. Each object implements an update method that simulates one frame of the object’s behavior. Each frame, the game updates every object in the collection.
+
+To learn more about how the game loop runs and when the update methods are invoked, please refer to Game Loop Pattern.
+
+## Credits
+
+* [Game Programming Patterns - Update Method](http://gameprogrammingpatterns.com/update-method.html)
\ No newline at end of file
diff --git a/update-method/pom.xml b/update-method/pom.xml
new file mode 100644
index 000000000000..ede79f8f6c06
--- /dev/null
+++ b/update-method/pom.xml
@@ -0,0 +1,44 @@
+
+
+
+
+
+ java-design-patterns
+ com.iluwatar
+ 1.23.0-SNAPSHOT
+
+ 4.0.0
+
+ update-method
+
+
+ junit
+ junit
+
+
+
+
+
\ No newline at end of file
diff --git a/update-method/src/main/java/com/iluwatar/updatemethod/App.java b/update-method/src/main/java/com/iluwatar/updatemethod/App.java
new file mode 100644
index 000000000000..45069a3dee21
--- /dev/null
+++ b/update-method/src/main/java/com/iluwatar/updatemethod/App.java
@@ -0,0 +1,61 @@
+/*
+ * The MIT License
+ * Copyright © 2014-2019 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.updatemethod;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This pattern simulate a collection of independent objects by telling each to
+ * process one frame of behavior at a time. The game world maintains a collection
+ * of objects. Each object implements an update method that simulates one frame of
+ * the object’s behavior. Each frame, the game updates every object in the collection.
+ */
+public class App {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
+
+ private static final int GAME_RUNNING_TIME = 2000;
+
+ /**
+ * Program entry point.
+ * @param args runtime arguments
+ */
+ public static void main(String[] args) {
+ try {
+ var world = new World();
+ var skeleton1 = new Skeleton(1, 10);
+ var skeleton2 = new Skeleton(2, 70);
+ var statue = new Statue(3, 20);
+ world.addEntity(skeleton1);
+ world.addEntity(skeleton2);
+ world.addEntity(statue);
+ world.run();
+ Thread.sleep(GAME_RUNNING_TIME);
+ world.stop();
+ } catch (InterruptedException e) {
+ LOGGER.error(e.getMessage());
+ }
+ }
+}
diff --git a/update-method/src/main/java/com/iluwatar/updatemethod/Entity.java b/update-method/src/main/java/com/iluwatar/updatemethod/Entity.java
new file mode 100644
index 000000000000..0f10d77758cd
--- /dev/null
+++ b/update-method/src/main/java/com/iluwatar/updatemethod/Entity.java
@@ -0,0 +1,54 @@
+/*
+ * The MIT License
+ * Copyright © 2014-2019 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.updatemethod;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Abstract class for all the entity types.
+ */
+public abstract class Entity {
+
+ protected final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+ protected int id;
+
+ protected int position;
+
+ public Entity(int id) {
+ this.id = id;
+ this.position = 0;
+ }
+
+ public abstract void update();
+
+ public int getPosition() {
+ return position;
+ }
+
+ public void setPosition(int position) {
+ this.position = position;
+ }
+}
diff --git a/update-method/src/main/java/com/iluwatar/updatemethod/Skeleton.java b/update-method/src/main/java/com/iluwatar/updatemethod/Skeleton.java
new file mode 100644
index 000000000000..e365d6aecfcb
--- /dev/null
+++ b/update-method/src/main/java/com/iluwatar/updatemethod/Skeleton.java
@@ -0,0 +1,78 @@
+/*
+ * The MIT License
+ * Copyright © 2014-2019 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.updatemethod;
+
+/**
+ * Skeletons are always patrolling on the game map. Initially all the skeletons
+ * patrolling to the right, and after them reach the bounding, it will start
+ * patrolling to the left. For each frame, one skeleton will move 1 position
+ * step.
+ */
+public class Skeleton extends Entity {
+
+ private static final int PATROLLING_LEFT_BOUNDING = 0;
+
+ private static final int PATROLLING_RIGHT_BOUNDING = 100;
+
+ protected boolean patrollingLeft;
+
+ /**
+ * Constructor of Skeleton.
+ *
+ * @param id id of skeleton
+ */
+ public Skeleton(int id) {
+ super(id);
+ patrollingLeft = false;
+ }
+
+ /**
+ * Constructor of Skeleton.
+ *
+ * @param id id of skeleton
+ * @param postition position of skeleton
+ */
+ public Skeleton(int id, int postition) {
+ super(id);
+ this.position = position;
+ patrollingLeft = false;
+ }
+
+ @Override
+ public void update() {
+ if (patrollingLeft) {
+ position -= 1;
+ if (position == PATROLLING_LEFT_BOUNDING) {
+ patrollingLeft = false;
+ }
+ } else {
+ position += 1;
+ if (position == PATROLLING_RIGHT_BOUNDING) {
+ patrollingLeft = true;
+ }
+ }
+ logger.info("Skeleton " + id + " is on position " + position + ".");
+ }
+}
+
diff --git a/update-method/src/main/java/com/iluwatar/updatemethod/Statue.java b/update-method/src/main/java/com/iluwatar/updatemethod/Statue.java
new file mode 100644
index 000000000000..f1f3e2a87a6f
--- /dev/null
+++ b/update-method/src/main/java/com/iluwatar/updatemethod/Statue.java
@@ -0,0 +1,69 @@
+/*
+ * The MIT License
+ * Copyright © 2014-2019 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.updatemethod;
+
+/**
+ * Statues shoot lightning at regular intervals.
+ */
+public class Statue extends Entity {
+
+ protected int frames;
+
+ protected int delay;
+
+ /**
+ * Constructor of Statue.
+ *
+ * @param id id of statue
+ */
+ public Statue(int id) {
+ super(id);
+ this.frames = 0;
+ this.delay = 0;
+ }
+
+ /**
+ * Constructor of Statue.
+ *
+ * @param id id of statue
+ * @param delay the number of frames between two lightning
+ */
+ public Statue(int id, int delay) {
+ super(id);
+ this.frames = 0;
+ this.delay = delay;
+ }
+
+ @Override
+ public void update() {
+ if (++ frames == delay) {
+ shootLightning();
+ frames = 0;
+ }
+ }
+
+ private void shootLightning() {
+ logger.info("Statue " + id + " shoots lightning!");
+ }
+}
diff --git a/update-method/src/main/java/com/iluwatar/updatemethod/World.java b/update-method/src/main/java/com/iluwatar/updatemethod/World.java
new file mode 100644
index 000000000000..8cabead56f00
--- /dev/null
+++ b/update-method/src/main/java/com/iluwatar/updatemethod/World.java
@@ -0,0 +1,114 @@
+/*
+ * The MIT License
+ * Copyright © 2014-2019 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.updatemethod;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The game world class. Maintain all the objects existed in the game frames.
+ */
+public class World {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(World.class);
+
+ protected List entities;
+
+ protected volatile boolean isRunning;
+
+ public World() {
+ entities = new ArrayList<>();
+ isRunning = false;
+ }
+
+ /**
+ * Main game loop. This loop will always run until the game is over. For
+ * each loop it will process user input, update internal status, and render
+ * the next frames. For more detail please refer to the game-loop pattern.
+ */
+ private void gameLoop() {
+ while (isRunning) {
+ processInput();
+ update();
+ render();
+ }
+ }
+
+ /**
+ * Handle any user input that has happened since the last call. In order to
+ * simulate the situation in real-life game, here we add a random time lag.
+ * The time lag ranges from 50 ms to 250 ms.
+ */
+ private void processInput() {
+ try {
+ int lag = new Random().nextInt(200) + 50;
+ Thread.sleep(lag);
+ } catch (InterruptedException e) {
+ LOGGER.error(e.getMessage());
+ }
+ }
+
+ /**
+ * Update internal status. The update method pattern invoke udpate method for
+ * each entity in the game.
+ */
+ private void update() {
+ for (var entity : entities) {
+ entity.update();
+ }
+ }
+
+ /**
+ * Render the next frame. Here we do nothing since it is not related to the
+ * pattern.
+ */
+ private void render() {}
+
+ /**
+ * Run game loop.
+ */
+ public void run() {
+ LOGGER.info("Start game.");
+ isRunning = true;
+ var thread = new Thread(this::gameLoop);
+ thread.start();
+ }
+
+ /**
+ * Stop game loop.
+ */
+ public void stop() {
+ LOGGER.info("Stop game.");
+ isRunning = false;
+ }
+
+ public void addEntity(Entity entity) {
+ entities.add(entity);
+ }
+
+}
diff --git a/update-method/src/test/java/com/iluwatar/updatemethod/AppTest.java b/update-method/src/test/java/com/iluwatar/updatemethod/AppTest.java
new file mode 100644
index 000000000000..75c30470d1b7
--- /dev/null
+++ b/update-method/src/test/java/com/iluwatar/updatemethod/AppTest.java
@@ -0,0 +1,35 @@
+/*
+ * The MIT License
+ * Copyright © 2014-2019 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.updatemethod;
+
+import org.junit.Test;
+
+public class AppTest {
+
+ @Test
+ public void testMain() {
+ String[] args = {};
+ App.main(args);
+ }
+}
diff --git a/update-method/src/test/java/com/iluwatar/updatemethod/SkeletonTest.java b/update-method/src/test/java/com/iluwatar/updatemethod/SkeletonTest.java
new file mode 100644
index 000000000000..73ab9eb1dc13
--- /dev/null
+++ b/update-method/src/test/java/com/iluwatar/updatemethod/SkeletonTest.java
@@ -0,0 +1,78 @@
+/*
+ * The MIT License
+ * Copyright © 2014-2019 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.updatemethod;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class SkeletonTest {
+
+ private Skeleton skeleton;
+
+ @Before
+ public void setup() {
+ skeleton = new Skeleton(1);
+ }
+
+ @After
+ public void tearDown() {
+ skeleton = null;
+ }
+
+ @Test
+ public void testUpdateForPatrollingLeft() {
+ skeleton.patrollingLeft = true;
+ skeleton.setPosition(50);
+ skeleton.update();
+ Assert.assertEquals(49, skeleton.getPosition());
+ }
+
+ @Test
+ public void testUpdateForPatrollingRight() {
+ skeleton.patrollingLeft = false;
+ skeleton.setPosition(50);
+ skeleton.update();
+ Assert.assertEquals(51, skeleton.getPosition());
+ }
+
+ @Test
+ public void testUpdateForReverseDirectionFromLeftToRight() {
+ skeleton.patrollingLeft = true;
+ skeleton.setPosition(1);
+ skeleton.update();
+ Assert.assertEquals(0, skeleton.getPosition());
+ Assert.assertEquals(false, skeleton.patrollingLeft);
+ }
+
+ @Test
+ public void testUpdateForReverseDirectionFromRightToLeft() {
+ skeleton.patrollingLeft = false;
+ skeleton.setPosition(99);
+ skeleton.update();
+ Assert.assertEquals(100, skeleton.getPosition());
+ Assert.assertEquals(true, skeleton.patrollingLeft);
+ }
+}
diff --git a/update-method/src/test/java/com/iluwatar/updatemethod/StatueTest.java b/update-method/src/test/java/com/iluwatar/updatemethod/StatueTest.java
new file mode 100644
index 000000000000..2d523237cfc3
--- /dev/null
+++ b/update-method/src/test/java/com/iluwatar/updatemethod/StatueTest.java
@@ -0,0 +1,58 @@
+/*
+ * The MIT License
+ * Copyright © 2014-2019 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.updatemethod;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class StatueTest {
+
+ private Statue statue;
+
+ @Before
+ public void setup() {
+ statue = new Statue(1, 20);
+ }
+
+ @After
+ public void tearDown() {
+ statue = null;
+ }
+
+ @Test
+ public void testUpdateForPendingShoot() {
+ statue.frames = 10;
+ statue.update();
+ Assert.assertEquals(11, statue.frames);
+ }
+
+ @Test
+ public void testUpdateForShooting() {
+ statue.frames = 19;
+ statue.update();
+ Assert.assertEquals(0, statue.frames);
+ }
+}
diff --git a/update-method/src/test/java/com/iluwatar/updatemethod/WorldTest.java b/update-method/src/test/java/com/iluwatar/updatemethod/WorldTest.java
new file mode 100644
index 000000000000..2a9dad316ba5
--- /dev/null
+++ b/update-method/src/test/java/com/iluwatar/updatemethod/WorldTest.java
@@ -0,0 +1,63 @@
+/*
+ * The MIT License
+ * Copyright © 2014-2019 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.updatemethod;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class WorldTest {
+
+ private World world;
+
+ @Before
+ public void setup() {
+ world = new World();
+ }
+
+ @After
+ public void tearDown() {
+ world = null;
+ }
+
+ @Test
+ public void testRun() {
+ world.run();
+ Assert.assertEquals(true, world.isRunning);
+ }
+
+ @Test
+ public void testStop() {
+ world.stop();
+ Assert.assertEquals(false, world.isRunning);
+ }
+
+ @Test
+ public void testAddEntity() {
+ var entity = new Skeleton(1);
+ world.addEntity(entity);
+ Assert.assertEquals(entity, world.entities.get(0));
+ }
+}