From 845da1fa16b0be48e2cf1859e4d46367b1780d33 Mon Sep 17 00:00:00 2001 From: Zhang WH Date: Sun, 26 Apr 2020 20:06:09 +0800 Subject: [PATCH 001/211] add java 11 support (o) (#1222) --- .../java/com/iluwatar/objectmother/King.java | 2 +- .../objectmother/RoyaltyObjectMother.java | 8 +++--- .../test/RoyaltyObjectMotherTest.java | 28 +++++++++---------- .../java/com/iluwatar/object/pool/App.java | 12 ++++---- .../com/iluwatar/object/pool/ObjectPool.java | 2 +- .../object/pool/OliphauntPoolTest.java | 18 ++++++------ .../main/java/com/iluwatar/observer/App.java | 4 +-- .../java/com/iluwatar/observer/Weather.java | 4 +-- .../iluwatar/observer/generic/GWeather.java | 2 +- .../iluwatar/observer/generic/Observable.java | 2 +- .../observer/WeatherObserverTest.java | 2 +- .../com/iluwatar/observer/WeatherTest.java | 14 +++++----- .../observer/generic/GWeatherTest.java | 14 +++++----- .../observer/generic/ObserverTest.java | 2 +- 14 files changed, 57 insertions(+), 57 deletions(-) diff --git a/object-mother/src/main/java/com/iluwatar/objectmother/King.java b/object-mother/src/main/java/com/iluwatar/objectmother/King.java index 314d152fd..2bd6a39cd 100644 --- a/object-mother/src/main/java/com/iluwatar/objectmother/King.java +++ b/object-mother/src/main/java/com/iluwatar/objectmother/King.java @@ -60,7 +60,7 @@ public class King implements Royalty { * @param queen Queen which should be flirted. */ public void flirt(Queen queen) { - boolean flirtStatus = queen.getFlirted(this); + var flirtStatus = queen.getFlirted(this); if (!flirtStatus) { this.makeUnhappy(); } else { diff --git a/object-mother/src/main/java/com/iluwatar/objectmother/RoyaltyObjectMother.java b/object-mother/src/main/java/com/iluwatar/objectmother/RoyaltyObjectMother.java index 5650e5f48..ff4c8bf39 100644 --- a/object-mother/src/main/java/com/iluwatar/objectmother/RoyaltyObjectMother.java +++ b/object-mother/src/main/java/com/iluwatar/objectmother/RoyaltyObjectMother.java @@ -43,7 +43,7 @@ public final class RoyaltyObjectMother { * @return A drunk {@link com.iluwatar.objectmother.King}. */ public static King createDrunkKing() { - King king = new King(); + var king = new King(); king.makeDrunk(); return king; } @@ -54,7 +54,7 @@ public final class RoyaltyObjectMother { * @return A happy {@link com.iluwatar.objectmother.King}. */ public static King createHappyKing() { - King king = new King(); + var king = new King(); king.makeHappy(); return king; } @@ -65,7 +65,7 @@ public final class RoyaltyObjectMother { * @return A drunk and happy {@link com.iluwatar.objectmother.King}. */ public static King createHappyDrunkKing() { - King king = new King(); + var king = new King(); king.makeHappy(); king.makeDrunk(); return king; @@ -77,7 +77,7 @@ public final class RoyaltyObjectMother { * @return A flirty {@link com.iluwatar.objectmother.Queen}. */ public static Queen createFlirtyQueen() { - Queen queen = new Queen(); + var queen = new Queen(); queen.setFlirtiness(true); return queen; } diff --git a/object-mother/src/test/java/com/iluwatar/objectmother/test/RoyaltyObjectMotherTest.java b/object-mother/src/test/java/com/iluwatar/objectmother/test/RoyaltyObjectMotherTest.java index b9b211d96..525b8e24e 100644 --- a/object-mother/src/test/java/com/iluwatar/objectmother/test/RoyaltyObjectMotherTest.java +++ b/object-mother/src/test/java/com/iluwatar/objectmother/test/RoyaltyObjectMotherTest.java @@ -40,50 +40,50 @@ public class RoyaltyObjectMotherTest { @Test public void unsuccessfulKingFlirt() { - King soberUnhappyKing = RoyaltyObjectMother.createSoberUnhappyKing(); - Queen flirtyQueen = RoyaltyObjectMother.createFlirtyQueen(); + var soberUnhappyKing = RoyaltyObjectMother.createSoberUnhappyKing(); + var flirtyQueen = RoyaltyObjectMother.createFlirtyQueen(); soberUnhappyKing.flirt(flirtyQueen); assertFalse(soberUnhappyKing.isHappy()); } @Test public void queenIsBlockingFlirtCauseDrunkKing() { - King drunkUnhappyKing = RoyaltyObjectMother.createDrunkKing(); - Queen notFlirtyQueen = RoyaltyObjectMother.createNotFlirtyQueen(); + var drunkUnhappyKing = RoyaltyObjectMother.createDrunkKing(); + var notFlirtyQueen = RoyaltyObjectMother.createNotFlirtyQueen(); drunkUnhappyKing.flirt(notFlirtyQueen); assertFalse(drunkUnhappyKing.isHappy()); } @Test public void queenIsBlockingFlirt() { - King soberHappyKing = RoyaltyObjectMother.createHappyKing(); - Queen notFlirtyQueen = RoyaltyObjectMother.createNotFlirtyQueen(); + var soberHappyKing = RoyaltyObjectMother.createHappyKing(); + var notFlirtyQueen = RoyaltyObjectMother.createNotFlirtyQueen(); soberHappyKing.flirt(notFlirtyQueen); assertFalse(soberHappyKing.isHappy()); } @Test public void successfullKingFlirt() { - King soberHappyKing = RoyaltyObjectMother.createHappyKing(); - Queen flirtyQueen = RoyaltyObjectMother.createFlirtyQueen(); + var soberHappyKing = RoyaltyObjectMother.createHappyKing(); + var flirtyQueen = RoyaltyObjectMother.createFlirtyQueen(); soberHappyKing.flirt(flirtyQueen); assertTrue(soberHappyKing.isHappy()); } @Test public void testQueenType() { - Royalty flirtyQueen = RoyaltyObjectMother.createFlirtyQueen(); - Royalty notFlirtyQueen = RoyaltyObjectMother.createNotFlirtyQueen(); + var flirtyQueen = RoyaltyObjectMother.createFlirtyQueen(); + var notFlirtyQueen = RoyaltyObjectMother.createNotFlirtyQueen(); assertEquals(flirtyQueen.getClass(), Queen.class); assertEquals(notFlirtyQueen.getClass(), Queen.class); } @Test public void testKingType() { - Royalty drunkKing = RoyaltyObjectMother.createDrunkKing(); - Royalty happyDrunkKing = RoyaltyObjectMother.createHappyDrunkKing(); - Royalty happyKing = RoyaltyObjectMother.createHappyKing(); - Royalty soberUnhappyKing = RoyaltyObjectMother.createSoberUnhappyKing(); + var drunkKing = RoyaltyObjectMother.createDrunkKing(); + var happyDrunkKing = RoyaltyObjectMother.createHappyDrunkKing(); + var happyKing = RoyaltyObjectMother.createHappyKing(); + var soberUnhappyKing = RoyaltyObjectMother.createSoberUnhappyKing(); assertEquals(drunkKing.getClass(), King.class); assertEquals(happyDrunkKing.getClass(), King.class); assertEquals(happyKing.getClass(), King.class); diff --git a/object-pool/src/main/java/com/iluwatar/object/pool/App.java b/object-pool/src/main/java/com/iluwatar/object/pool/App.java index 3c1774fac..cbfc7dea5 100644 --- a/object-pool/src/main/java/com/iluwatar/object/pool/App.java +++ b/object-pool/src/main/java/com/iluwatar/object/pool/App.java @@ -54,14 +54,14 @@ public class App { * @param args command line args */ public static void main(String[] args) { - OliphauntPool pool = new OliphauntPool(); + var pool = new OliphauntPool(); LOGGER.info(pool.toString()); - Oliphaunt oliphaunt1 = pool.checkOut(); + var oliphaunt1 = pool.checkOut(); LOGGER.info("Checked out {}", oliphaunt1); LOGGER.info(pool.toString()); - Oliphaunt oliphaunt2 = pool.checkOut(); + var oliphaunt2 = pool.checkOut(); LOGGER.info("Checked out {}", oliphaunt2); - Oliphaunt oliphaunt3 = pool.checkOut(); + var oliphaunt3 = pool.checkOut(); LOGGER.info("Checked out {}", oliphaunt3); LOGGER.info(pool.toString()); LOGGER.info("Checking in {}", oliphaunt1); @@ -69,9 +69,9 @@ public class App { LOGGER.info("Checking in {}", oliphaunt2); pool.checkIn(oliphaunt2); LOGGER.info(pool.toString()); - Oliphaunt oliphaunt4 = pool.checkOut(); + var oliphaunt4 = pool.checkOut(); LOGGER.info("Checked out {}", oliphaunt4); - Oliphaunt oliphaunt5 = pool.checkOut(); + var oliphaunt5 = pool.checkOut(); LOGGER.info("Checked out {}", oliphaunt5); LOGGER.info(pool.toString()); } diff --git a/object-pool/src/main/java/com/iluwatar/object/pool/ObjectPool.java b/object-pool/src/main/java/com/iluwatar/object/pool/ObjectPool.java index 37009d44b..b8ce3cc05 100644 --- a/object-pool/src/main/java/com/iluwatar/object/pool/ObjectPool.java +++ b/object-pool/src/main/java/com/iluwatar/object/pool/ObjectPool.java @@ -45,7 +45,7 @@ public abstract class ObjectPool { if (available.isEmpty()) { available.add(create()); } - T instance = available.iterator().next(); + var instance = available.iterator().next(); available.remove(instance); inUse.add(instance); return instance; diff --git a/object-pool/src/test/java/com/iluwatar/object/pool/OliphauntPoolTest.java b/object-pool/src/test/java/com/iluwatar/object/pool/OliphauntPoolTest.java index d4ca42948..880009f86 100644 --- a/object-pool/src/test/java/com/iluwatar/object/pool/OliphauntPoolTest.java +++ b/object-pool/src/test/java/com/iluwatar/object/pool/OliphauntPoolTest.java @@ -44,17 +44,17 @@ public class OliphauntPoolTest { @Test public void testSubsequentCheckinCheckout() { assertTimeout(ofMillis(5000), () -> { - final OliphauntPool pool = new OliphauntPool(); + final var pool = new OliphauntPool(); assertEquals("Pool available=0 inUse=0", pool.toString()); - final Oliphaunt expectedOliphaunt = pool.checkOut(); + final var expectedOliphaunt = pool.checkOut(); assertEquals("Pool available=0 inUse=1", pool.toString()); pool.checkIn(expectedOliphaunt); assertEquals("Pool available=1 inUse=0", pool.toString()); for (int i = 0; i < 100; i++) { - final Oliphaunt oliphaunt = pool.checkOut(); + final var oliphaunt = pool.checkOut(); assertEquals("Pool available=0 inUse=1", pool.toString()); assertSame(expectedOliphaunt, oliphaunt); assertEquals(expectedOliphaunt.getId(), oliphaunt.getId()); @@ -73,13 +73,13 @@ public class OliphauntPoolTest { @Test public void testConcurrentCheckinCheckout() { assertTimeout(ofMillis(5000), () -> { - final OliphauntPool pool = new OliphauntPool(); + final var pool = new OliphauntPool(); assertEquals(pool.toString(), "Pool available=0 inUse=0"); - final Oliphaunt firstOliphaunt = pool.checkOut(); + final var firstOliphaunt = pool.checkOut(); assertEquals(pool.toString(), "Pool available=0 inUse=1"); - final Oliphaunt secondOliphaunt = pool.checkOut(); + final var secondOliphaunt = pool.checkOut(); assertEquals(pool.toString(), "Pool available=0 inUse=2"); assertNotSame(firstOliphaunt, secondOliphaunt); @@ -89,7 +89,7 @@ public class OliphauntPoolTest { pool.checkIn(secondOliphaunt); assertEquals(pool.toString(), "Pool available=1 inUse=1"); - final Oliphaunt oliphaunt3 = pool.checkOut(); + final var oliphaunt3 = pool.checkOut(); assertEquals(pool.toString(), "Pool available=0 inUse=2"); assertSame(secondOliphaunt, oliphaunt3); @@ -97,7 +97,7 @@ public class OliphauntPoolTest { pool.checkIn(firstOliphaunt); assertEquals(pool.toString(), "Pool available=1 inUse=1"); - final Oliphaunt oliphaunt4 = pool.checkOut(); + final var oliphaunt4 = pool.checkOut(); assertEquals(pool.toString(), "Pool available=0 inUse=2"); assertSame(firstOliphaunt, oliphaunt4); @@ -110,7 +110,7 @@ public class OliphauntPoolTest { // The order of the returned instances is not determined, so just put them in a list // and verify if both expected instances are in there. - final List oliphaunts = List.of(pool.checkOut(), pool.checkOut()); + final var oliphaunts = List.of(pool.checkOut(), pool.checkOut()); assertEquals(pool.toString(), "Pool available=0 inUse=2"); assertTrue(oliphaunts.contains(firstOliphaunt)); assertTrue(oliphaunts.contains(secondOliphaunt)); diff --git a/observer/src/main/java/com/iluwatar/observer/App.java b/observer/src/main/java/com/iluwatar/observer/App.java index d0994b65c..b8fd01f32 100644 --- a/observer/src/main/java/com/iluwatar/observer/App.java +++ b/observer/src/main/java/com/iluwatar/observer/App.java @@ -51,7 +51,7 @@ public class App { */ public static void main(String[] args) { - Weather weather = new Weather(); + var weather = new Weather(); weather.addObserver(new Orcs()); weather.addObserver(new Hobbits()); @@ -62,7 +62,7 @@ public class App { // Generic observer inspired by Java Generics and Collection by Naftalin & Wadler LOGGER.info("--Running generic version--"); - GWeather genericWeather = new GWeather(); + var genericWeather = new GWeather(); genericWeather.addObserver(new GOrcs()); genericWeather.addObserver(new GHobbits()); diff --git a/observer/src/main/java/com/iluwatar/observer/Weather.java b/observer/src/main/java/com/iluwatar/observer/Weather.java index 3369e8f63..778858107 100644 --- a/observer/src/main/java/com/iluwatar/observer/Weather.java +++ b/observer/src/main/java/com/iluwatar/observer/Weather.java @@ -56,14 +56,14 @@ public class Weather { * Makes time pass for weather. */ public void timePasses() { - WeatherType[] enumValues = WeatherType.values(); + var enumValues = WeatherType.values(); currentWeather = enumValues[(currentWeather.ordinal() + 1) % enumValues.length]; LOGGER.info("The weather changed to {}.", currentWeather); notifyObservers(); } private void notifyObservers() { - for (WeatherObserver obs : observers) { + for (var obs : observers) { obs.update(currentWeather); } } diff --git a/observer/src/main/java/com/iluwatar/observer/generic/GWeather.java b/observer/src/main/java/com/iluwatar/observer/generic/GWeather.java index 13ba25534..c8f7bc701 100644 --- a/observer/src/main/java/com/iluwatar/observer/generic/GWeather.java +++ b/observer/src/main/java/com/iluwatar/observer/generic/GWeather.java @@ -44,7 +44,7 @@ public class GWeather extends Observable { * Makes time pass for weather. */ public void timePasses() { - WeatherType[] enumValues = WeatherType.values(); + var enumValues = WeatherType.values(); currentWeather = enumValues[(currentWeather.ordinal() + 1) % enumValues.length]; LOGGER.info("The weather changed to {}.", currentWeather); notifyObservers(currentWeather); diff --git a/observer/src/main/java/com/iluwatar/observer/generic/Observable.java b/observer/src/main/java/com/iluwatar/observer/generic/Observable.java index 29d350154..fbb078941 100644 --- a/observer/src/main/java/com/iluwatar/observer/generic/Observable.java +++ b/observer/src/main/java/com/iluwatar/observer/generic/Observable.java @@ -54,7 +54,7 @@ public abstract class Observable, O extends Observ */ @SuppressWarnings("unchecked") public void notifyObservers(A argument) { - for (O observer : observers) { + for (var observer : observers) { observer.update((S) this, argument); } } diff --git a/observer/src/test/java/com/iluwatar/observer/WeatherObserverTest.java b/observer/src/test/java/com/iluwatar/observer/WeatherObserverTest.java index fbaceb02b..7f9b3a790 100644 --- a/observer/src/test/java/com/iluwatar/observer/WeatherObserverTest.java +++ b/observer/src/test/java/com/iluwatar/observer/WeatherObserverTest.java @@ -80,7 +80,7 @@ public abstract class WeatherObserverTest { @ParameterizedTest @MethodSource("dataProvider") public void testObserver(WeatherType weather, String response) { - final O observer = this.factory.get(); + final var observer = this.factory.get(); assertEquals(0, appender.getLogSize()); observer.update(weather); diff --git a/observer/src/test/java/com/iluwatar/observer/WeatherTest.java b/observer/src/test/java/com/iluwatar/observer/WeatherTest.java index c00357153..90e090c8d 100644 --- a/observer/src/test/java/com/iluwatar/observer/WeatherTest.java +++ b/observer/src/test/java/com/iluwatar/observer/WeatherTest.java @@ -61,9 +61,9 @@ public class WeatherTest { */ @Test public void testAddRemoveObserver() { - final WeatherObserver observer = mock(WeatherObserver.class); + final var observer = mock(WeatherObserver.class); - final Weather weather = new Weather(); + final var weather = new Weather(); weather.addObserver(observer); verifyZeroInteractions(observer); @@ -84,13 +84,13 @@ public class WeatherTest { */ @Test public void testTimePasses() { - final WeatherObserver observer = mock(WeatherObserver.class); - final Weather weather = new Weather(); + final var observer = mock(WeatherObserver.class); + final var weather = new Weather(); weather.addObserver(observer); - final InOrder inOrder = inOrder(observer); - final WeatherType[] weatherTypes = WeatherType.values(); - for (int i = 1; i < 20; i++) { + final var inOrder = inOrder(observer); + final var weatherTypes = WeatherType.values(); + for (var i = 1; i < 20; i++) { weather.timePasses(); inOrder.verify(observer).update(weatherTypes[i % weatherTypes.length]); } diff --git a/observer/src/test/java/com/iluwatar/observer/generic/GWeatherTest.java b/observer/src/test/java/com/iluwatar/observer/generic/GWeatherTest.java index 7450a00b9..e45dd5c28 100644 --- a/observer/src/test/java/com/iluwatar/observer/generic/GWeatherTest.java +++ b/observer/src/test/java/com/iluwatar/observer/generic/GWeatherTest.java @@ -59,9 +59,9 @@ public class GWeatherTest { */ @Test public void testAddRemoveObserver() { - final Race observer = mock(Race.class); + final var observer = mock(Race.class); - final GWeather weather = new GWeather(); + final var weather = new GWeather(); weather.addObserver(observer); verifyZeroInteractions(observer); @@ -82,13 +82,13 @@ public class GWeatherTest { */ @Test public void testTimePasses() { - final Race observer = mock(Race.class); - final GWeather weather = new GWeather(); + final var observer = mock(Race.class); + final var weather = new GWeather(); weather.addObserver(observer); - final InOrder inOrder = inOrder(observer); - final WeatherType[] weatherTypes = WeatherType.values(); - for (int i = 1; i < 20; i++) { + final var inOrder = inOrder(observer); + final var weatherTypes = WeatherType.values(); + for (var i = 1; i < 20; i++) { weather.timePasses(); inOrder.verify(observer).update(weather, weatherTypes[i % weatherTypes.length]); } diff --git a/observer/src/test/java/com/iluwatar/observer/generic/ObserverTest.java b/observer/src/test/java/com/iluwatar/observer/generic/ObserverTest.java index b5ef7ec0d..f358c88e1 100644 --- a/observer/src/test/java/com/iluwatar/observer/generic/ObserverTest.java +++ b/observer/src/test/java/com/iluwatar/observer/generic/ObserverTest.java @@ -79,7 +79,7 @@ public abstract class ObserverTest> { @ParameterizedTest @MethodSource("dataProvider") public void testObserver(WeatherType weather, String response) { - final O observer = this.factory.get(); + final var observer = this.factory.get(); assertEquals(0, appender.getLogSize()); observer.update(null, weather); From 1c26bd741615e73579e5b70fdc84d96ca23c69e8 Mon Sep 17 00:00:00 2001 From: Zhang WH Date: Mon, 18 May 2020 02:44:53 +0800 Subject: [PATCH 002/211] Fix issue #1218: Arrange, Act, Assert pattern (#1221) * add AAA pattern * reformat comment * use Testing in readme tags in stead of Unit Test --- arrange-act-assert/README.md | 30 ++++++ .../etc/arrange-act-assert.urm.puml | 11 +++ arrange-act-assert/pom.xml | 44 +++++++++ .../com/iluwatar/arrangeactassert/Cash.java | 57 +++++++++++ .../arrangeactassert/CashAAATest.java | 99 +++++++++++++++++++ .../arrangeactassert/CashAntiAAATest.java | 59 +++++++++++ pom.xml | 1 + 7 files changed, 301 insertions(+) create mode 100644 arrange-act-assert/README.md create mode 100644 arrange-act-assert/etc/arrange-act-assert.urm.puml create mode 100644 arrange-act-assert/pom.xml create mode 100644 arrange-act-assert/src/main/java/com/iluwatar/arrangeactassert/Cash.java create mode 100644 arrange-act-assert/src/test/java/com/iluwatar/arrangeactassert/CashAAATest.java create mode 100644 arrange-act-assert/src/test/java/com/iluwatar/arrangeactassert/CashAntiAAATest.java diff --git a/arrange-act-assert/README.md b/arrange-act-assert/README.md new file mode 100644 index 000000000..02b7ee8b7 --- /dev/null +++ b/arrange-act-assert/README.md @@ -0,0 +1,30 @@ +--- +layout: pattern +title: Arrange/Act/Assert +folder: arrange-act-assert +permalink: /patterns/arrange-act-assert/ +categories: Idiom +tags: + - Testing +--- + +## Also known as +Given/When/Then + +## Intent +The Arrange/Act/Assert (AAA) is a pattern for organizing unit tests. +It breaks tests down into three clear and distinct steps: +1. Arrange: Perform the setup and initialization required for the test. +2. Act: Take action(s) required for the test. +3. Assert: Verify the outcome(s) of the test. + +## Applicability +Use Arrange/Act/Assert pattern when + +* you need to structure your unit tests so they're easier to read, maintain, and enhance. + +## Credits + +* [Arrange, Act, Assert: What is AAA Testing?](https://blog.ncrunch.net/post/arrange-act-assert-aaa-testing.aspx) +* [Bill Wake: 3A – Arrange, Act, Assert](https://xp123.com/articles/3a-arrange-act-assert/) +* [Martin Fowler: GivenWhenThen](https://martinfowler.com/bliki/GivenWhenThen.html) diff --git a/arrange-act-assert/etc/arrange-act-assert.urm.puml b/arrange-act-assert/etc/arrange-act-assert.urm.puml new file mode 100644 index 000000000..4b22d2a4e --- /dev/null +++ b/arrange-act-assert/etc/arrange-act-assert.urm.puml @@ -0,0 +1,11 @@ +@startuml +package com.iluwatar.arrangeactassert { + class Cash { + - amount : int + ~ Cash(amount : int) + ~ count() : int + ~ minus(subtrahend : int) : boolean + ~ plus(addend : int) + } +} +@enduml \ No newline at end of file diff --git a/arrange-act-assert/pom.xml b/arrange-act-assert/pom.xml new file mode 100644 index 000000000..bb0387e7a --- /dev/null +++ b/arrange-act-assert/pom.xml @@ -0,0 +1,44 @@ + + + + + java-design-patterns + com.iluwatar + 1.23.0-SNAPSHOT + + 4.0.0 + + arrange-act-assert + + + junit + junit + test + + + \ No newline at end of file diff --git a/arrange-act-assert/src/main/java/com/iluwatar/arrangeactassert/Cash.java b/arrange-act-assert/src/main/java/com/iluwatar/arrangeactassert/Cash.java new file mode 100644 index 000000000..71269359e --- /dev/null +++ b/arrange-act-assert/src/main/java/com/iluwatar/arrangeactassert/Cash.java @@ -0,0 +1,57 @@ +/* + * 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.arrangeactassert; + +/** + * Arrange/Act/Assert (AAA) is a unit test pattern. In this simple example, we have a ({@link Cash}) + * object for plus, minus and counting amount. + */ +public class Cash { + + private int amount; + + Cash(int amount) { + this.amount = amount; + } + + //plus + void plus(int addend) { + amount += addend; + } + + //minus + boolean minus(int subtrahend) { + if (amount >= subtrahend) { + amount -= subtrahend; + return true; + } else { + return false; + } + } + + //count + int count() { + return amount; + } +} diff --git a/arrange-act-assert/src/test/java/com/iluwatar/arrangeactassert/CashAAATest.java b/arrange-act-assert/src/test/java/com/iluwatar/arrangeactassert/CashAAATest.java new file mode 100644 index 000000000..d7841843d --- /dev/null +++ b/arrange-act-assert/src/test/java/com/iluwatar/arrangeactassert/CashAAATest.java @@ -0,0 +1,99 @@ +/* + * 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.arrangeactassert; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +/** + * Arrange/Act/Assert (AAA) is a pattern for organizing unit tests. It is a way to structure your + * tests so they're easier to read, maintain and enhance. + * + *

It breaks tests down into three clear and distinct steps: + *

1. Arrange: Perform the setup and initialization required for the test. + *

2. Act: Take action(s) required for the test. + *

3. Assert: Verify the outcome(s) of the test. + * + *

This pattern has several significant benefits. It creates a clear separation between a test's + * setup, operations, and results. This structure makes the code easier to read and understand. If + * you place the steps in order and format your code to separate them, you can scan a test and + * quickly comprehend what it does. + * + *

It also enforces a certain degree of discipline when you write your tests. You have to think + * clearly about the three steps your test will perform. But it makes tests more natural to write at + * the same time since you already have an outline. + * + *

In ({@link CashAAATest}) we have four test methods. Each of them has only one reason to + * change and one reason to fail. In a large and complicated code base, tests that honor the single + * responsibility principle are much easier to troubleshoot. + */ +public class CashAAATest { + + @Test + public void testPlus() { + //Arrange + var cash = new Cash(3); + //Act + cash.plus(4); + //Assert + assertEquals(cash.count(), 7); + } + + @Test + public void testMinus() { + //Arrange + var cash = new Cash(8); + //Act + var result = cash.minus(5); + //Assert + assertTrue(result); + assertEquals(cash.count(), 3); + } + + @Test + public void testInsufficientMinus() { + //Arrange + var cash = new Cash(1); + //Act + var result = cash.minus(6); + //Assert + assertFalse(result); + assertEquals(cash.count(), 1); + } + + @Test + public void testUpdate() { + //Arrange + var cash = new Cash(5); + //Act + cash.plus(6); + var result = cash.minus(3); + //Assert + assertTrue(result); + assertEquals(cash.count(), 8); + } +} diff --git a/arrange-act-assert/src/test/java/com/iluwatar/arrangeactassert/CashAntiAAATest.java b/arrange-act-assert/src/test/java/com/iluwatar/arrangeactassert/CashAntiAAATest.java new file mode 100644 index 000000000..3f8c33d5e --- /dev/null +++ b/arrange-act-assert/src/test/java/com/iluwatar/arrangeactassert/CashAntiAAATest.java @@ -0,0 +1,59 @@ +/* + * 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.arrangeactassert; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +/** + * ({@link CashAAATest}) is an anti-example of AAA pattern. This test is functionally correct, but + * with the addition of new feature, it needs refactoring. There are an awful lot of steps in that + * test method, but it verifies the class' important behavior in just eleven lines. It violates the + * single responsibility principle. If this test method failed after a small code change, it might + * take some digging to discover why. + */ +public class CashAntiAAATest { + + @Test + public void testCash() { + //initialize + var cash = new Cash(3); + //test plus + cash.plus(4); + assertEquals(cash.count(), 7); + //test minus + cash = new Cash(8); + assertTrue(cash.minus(5)); + assertEquals(cash.count(), 3); + assertFalse(cash.minus(6)); + assertEquals(cash.count(), 3); + //test update + cash.plus(5); + assertTrue(cash.minus(5)); + assertEquals(cash.count(), 3); + } +} diff --git a/pom.xml b/pom.xml index b81cfe8d4..97deda703 100644 --- a/pom.xml +++ b/pom.xml @@ -184,6 +184,7 @@ combinator update-method leader-followers + arrange-act-assert From a3c4d36c3dae6f7ca8286ebcd60ea3d2f336747f Mon Sep 17 00:00:00 2001 From: venkatrs-ch197 <65022470+venkatrs-ch197@users.noreply.github.com> Date: Sun, 31 May 2020 13:15:28 +0530 Subject: [PATCH 003/211] Added Java 11 support and created constants in App.java (#1238) Co-authored-by: cherukumilliv --- module/src/main/java/com/iluwatar/module/App.java | 10 ++++++---- .../java/com/iluwatar/module/FileLoggerModuleTest.java | 10 +++++----- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/module/src/main/java/com/iluwatar/module/App.java b/module/src/main/java/com/iluwatar/module/App.java index 1b6cbbd23..d50693440 100644 --- a/module/src/main/java/com/iluwatar/module/App.java +++ b/module/src/main/java/com/iluwatar/module/App.java @@ -37,6 +37,8 @@ import java.io.FileNotFoundException; */ public class App { + private static final String ERROR = "Error"; + private static final String MESSAGE = "Message"; public static FileLoggerModule fileLoggerModule; public static ConsoleLoggerModule consoleLoggerModule; @@ -71,12 +73,12 @@ public class App { public static void execute(final String... args) { /* Send logs on file system */ - fileLoggerModule.printString("Message"); - fileLoggerModule.printErrorString("Error"); + fileLoggerModule.printString(MESSAGE); + fileLoggerModule.printErrorString(ERROR); /* Send logs on console */ - consoleLoggerModule.printString("Message"); - consoleLoggerModule.printErrorString("Error"); + consoleLoggerModule.printString(MESSAGE); + consoleLoggerModule.printErrorString(ERROR); } /** diff --git a/module/src/test/java/com/iluwatar/module/FileLoggerModuleTest.java b/module/src/test/java/com/iluwatar/module/FileLoggerModuleTest.java index e88b466f2..646bba642 100644 --- a/module/src/test/java/com/iluwatar/module/FileLoggerModuleTest.java +++ b/module/src/test/java/com/iluwatar/module/FileLoggerModuleTest.java @@ -65,7 +65,7 @@ public final class FileLoggerModuleTest { public void testFileMessage() throws IOException { /* Get singletong instance of File Logger Module */ - final FileLoggerModule fileLoggerModule = FileLoggerModule.getSingleton(); + final var fileLoggerModule = FileLoggerModule.getSingleton(); /* Prepare the essential sub modules, to perform the sequence of jobs */ fileLoggerModule.prepare(); @@ -89,7 +89,7 @@ public final class FileLoggerModuleTest { public void testNoFileMessage() throws IOException { /* Get singletong instance of File Logger Module */ - final FileLoggerModule fileLoggerModule = FileLoggerModule.getSingleton(); + final var fileLoggerModule = FileLoggerModule.getSingleton(); /* Prepare the essential sub modules, to perform the sequence of jobs */ fileLoggerModule.prepare(); @@ -111,7 +111,7 @@ public final class FileLoggerModuleTest { public void testFileErrorMessage() throws FileNotFoundException { /* Get singletong instance of File Logger Module */ - final FileLoggerModule fileLoggerModule = FileLoggerModule.getSingleton(); + final var fileLoggerModule = FileLoggerModule.getSingleton(); /* Prepare the essential sub modules, to perform the sequence of jobs */ fileLoggerModule.prepare(); @@ -136,7 +136,7 @@ public final class FileLoggerModuleTest { public void testNoFileErrorMessage() throws FileNotFoundException { /* Get singletong instance of File Logger Module */ - final FileLoggerModule fileLoggerModule = FileLoggerModule.getSingleton(); + final var fileLoggerModule = FileLoggerModule.getSingleton(); /* Prepare the essential sub modules, to perform the sequence of jobs */ fileLoggerModule.prepare(); @@ -157,7 +157,7 @@ public final class FileLoggerModuleTest { private static final String readFirstLine(final String file) { String firstLine = null; - try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file))) { + try (var bufferedReader = new BufferedReader(new FileReader(file))) { while (bufferedReader.ready()) { From e68beb40ec0336e75cdce5f0b29e40df3eb6944c Mon Sep 17 00:00:00 2001 From: Alexander Iskuskov Date: Sun, 31 May 2020 10:47:14 +0300 Subject: [PATCH 004/211] Fix typo for leader-election pattern description (#1239) --- leader-election/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/leader-election/README.md b/leader-election/README.md index e6b2428dd..3cfa7a662 100644 --- a/leader-election/README.md +++ b/leader-election/README.md @@ -9,7 +9,7 @@ tags: --- ## Intent -Leader Election pattern is commonly used in cloud system design. It can help to ensure that task instances selec the leader instance correctly and do not conflict with each other, cause contention for shared resources, or inadvertently interfere with the work that other task instances are performing. +Leader Election pattern is commonly used in cloud system design. It can help to ensure that task instances select the leader instance correctly and do not conflict with each other, cause contention for shared resources, or inadvertently interfere with the work that other task instances are performing. ## Class diagram ![alt text](./etc/leader-election.urm.png "Leader Election pattern class diagram") From 3033e4c9fca8dadadaf2f2543cf2d1ccc7f7e66d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Wed, 10 Jun 2020 18:10:34 +0300 Subject: [PATCH 005/211] Improve lazy loaded Singleton example --- .../singleton/ThreadSafeLazyLoadedIvoryTower.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/singleton/src/main/java/com/iluwatar/singleton/ThreadSafeLazyLoadedIvoryTower.java b/singleton/src/main/java/com/iluwatar/singleton/ThreadSafeLazyLoadedIvoryTower.java index dd6d05fea..76afdede1 100644 --- a/singleton/src/main/java/com/iluwatar/singleton/ThreadSafeLazyLoadedIvoryTower.java +++ b/singleton/src/main/java/com/iluwatar/singleton/ThreadSafeLazyLoadedIvoryTower.java @@ -27,15 +27,13 @@ package com.iluwatar.singleton; *

Thread-safe Singleton class. The instance is lazily initialized and thus needs synchronization * mechanism.

* - *

Note: if created by reflection then a singleton will not be created but multiple options - * in the same classloader

*/ public final class ThreadSafeLazyLoadedIvoryTower { - private static ThreadSafeLazyLoadedIvoryTower instance; + private static volatile ThreadSafeLazyLoadedIvoryTower instance; private ThreadSafeLazyLoadedIvoryTower() { - // protect against instantiation via reflection + // Protect against instantiation via reflection if (instance == null) { instance = this; } else { @@ -44,13 +42,16 @@ public final class ThreadSafeLazyLoadedIvoryTower { } /** - * The instance gets created only when it is called for first time. Lazy-loading + * The instance doesn't get created until the method is called for the first time */ public static synchronized ThreadSafeLazyLoadedIvoryTower getInstance() { if (instance == null) { - instance = new ThreadSafeLazyLoadedIvoryTower(); + synchronized (ThreadSafeLazyLoadedIvoryTower.class) { + if (instance == null) { + instance = new ThreadSafeLazyLoadedIvoryTower(); + } + } } - return instance; } } From 92ecd63ccf3b697cd9a90982ce5251bd5592486b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 14 Jun 2020 17:27:43 +0300 Subject: [PATCH 006/211] Add Github Actions workflow --- .github/workflows/maven.yml | 24 ++++++++++++++++++++++++ .travis.yml | 36 ------------------------------------ 2 files changed, 24 insertions(+), 36 deletions(-) create mode 100644 .github/workflows/maven.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml new file mode 100644 index 000000000..72729cd89 --- /dev/null +++ b/.github/workflows/maven.yml @@ -0,0 +1,24 @@ +# This workflow will build a Java project with Maven +# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven + +name: Java CI with Maven + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build: + + runs-on: ubuntu-18.04 + + steps: + - uses: actions/checkout@v2 + - name: Set up JDK 11 + uses: actions/setup-java@v1 + with: + java-version: 11 + - name: Build with Maven + run: mvn clean verify diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 0a5ac7709..000000000 --- a/.travis.yml +++ /dev/null @@ -1,36 +0,0 @@ -language: java -dist: bionic -jdk: -- openjdk11 -sudo: required - -env: - global: - - secure: "DCpazS3nkLnter3sguXEAS2fC/1ZWNfM+XLyif9MfNFxlZdpni2vCD/jA0Rdpga8puQWHNVLyAec+RPFH/2qSmJ1c1UTV5MaLv8tPqwUX0VFA+1I6XoSv6oX4ldHTBWHEWqQHkRFOLoil0h0edc0tTOWQwXF8U+DLAB+HkRb4gw=" - -services: -- xvfb - -addons: - sonarcloud: - organization: "iluwatar" - token: - secure: "FpHwMYPMkdWU6CeIB7+O3qIeIM4vJMp47UjkKK53f0w0s6tPZofZZkab+gcL2TqKSil7sFVB/AQXU1cUubflRszwcLbNsc8H2yFehD79o0o0Mqd1Dd5ip/q0KQbHkkln+InFlVLfvrLB4Xd4mlQVxbGhqpULBhXjKzFzQlRFcuU=" -script: - # Because of Travis security restrictions, SonarCloud analysis cannot be run on pull requests originated from forks - # See https://docs.travis-ci.com/user/pull-requests/#pull-requests-and-security-restrictions - - 'if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then mvn clean verify; fi' - - 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then mvn clean verify sonar:sonar -Dsonar.projectKey=iluwatar_java-design-patterns -Dsonar.host.url=https://sonarcloud.io; fi' - -after_success: -- bash update-website.sh - -notifications: - email: - - iluwatar@gmail.com - webhooks: - urls: - - https://webhooks.gitter.im/e/3319623945358a093a6f - on_success: change # options: [always|never|change] default: always - on_failure: always # options: [always|never|change] default: always - on_start: never # options: [always|never|change] default: always From 0f751d40cb6c220af0bd4f568497ca201a5c5928 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 14 Jun 2020 17:36:26 +0300 Subject: [PATCH 007/211] Fix checkstyle error --- .../com/iluwatar/singleton/ThreadSafeLazyLoadedIvoryTower.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/singleton/src/main/java/com/iluwatar/singleton/ThreadSafeLazyLoadedIvoryTower.java b/singleton/src/main/java/com/iluwatar/singleton/ThreadSafeLazyLoadedIvoryTower.java index 76afdede1..c3d96445f 100644 --- a/singleton/src/main/java/com/iluwatar/singleton/ThreadSafeLazyLoadedIvoryTower.java +++ b/singleton/src/main/java/com/iluwatar/singleton/ThreadSafeLazyLoadedIvoryTower.java @@ -42,7 +42,7 @@ public final class ThreadSafeLazyLoadedIvoryTower { } /** - * The instance doesn't get created until the method is called for the first time + * The instance doesn't get created until the method is called for the first time. */ public static synchronized ThreadSafeLazyLoadedIvoryTower getInstance() { if (instance == null) { From 1aea35f8e5184202e1557892da7a86809619136a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 14 Jun 2020 17:48:42 +0300 Subject: [PATCH 008/211] Update build status badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1d8245d5d..53c9cd7a5 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ # Design patterns implemented in Java -[![Build status](https://travis-ci.org/iluwatar/java-design-patterns.svg?branch=master)](https://travis-ci.org/iluwatar/java-design-patterns) +![Java CI with Maven](https://github.com/iluwatar/java-design-patterns/workflows/Java%20CI%20with%20Maven/badge.svg) [![License MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/iluwatar/java-design-patterns/master/LICENSE.md) [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) From 3ea65e06bcf33ba0020b1403a4ffc37cee550f87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 14 Jun 2020 18:23:25 +0300 Subject: [PATCH 009/211] Install xvfb before building --- .github/workflows/maven.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 72729cd89..2467f5a80 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -20,5 +20,7 @@ jobs: uses: actions/setup-java@v1 with: java-version: 11 + - name: Install xvfb + run: sudo apt-get install xvfb - name: Build with Maven run: mvn clean verify From f28a63a46c0d0388dbdd88c2cdb5f32f833c6f02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 14 Jun 2020 18:33:48 +0300 Subject: [PATCH 010/211] Use GabrielBB/xvfb-action --- .github/workflows/maven.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 2467f5a80..486020981 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -20,7 +20,8 @@ jobs: uses: actions/setup-java@v1 with: java-version: 11 - - name: Install xvfb - run: sudo apt-get install xvfb - name: Build with Maven - run: mvn clean verify + uses: GabrielBB/xvfb-action@v1.2 + with: + working-directory: ./ #optional + run: mvn clean verify From 0b41aaaa760009e035d71c8ec61f762a91d8789b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 14 Jun 2020 18:37:29 +0300 Subject: [PATCH 011/211] Fix syntax --- .github/workflows/maven.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 486020981..3fdd0cb5a 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -22,6 +22,4 @@ jobs: java-version: 11 - name: Build with Maven uses: GabrielBB/xvfb-action@v1.2 - with: - working-directory: ./ #optional - run: mvn clean verify + run: mvn clean verify From 371263d1b363819f0ce95b723441cbebe560b841 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 14 Jun 2020 18:45:01 +0300 Subject: [PATCH 012/211] Fix xvfb setup --- .github/workflows/maven.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 3fdd0cb5a..9d6727d1e 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -20,6 +20,7 @@ jobs: uses: actions/setup-java@v1 with: java-version: 11 + - name: Install xvfb + run: sudo apt-get install xvfb - name: Build with Maven - uses: GabrielBB/xvfb-action@v1.2 - run: mvn clean verify + run: xvfb-run mvn clean verify From 71affacee286892a48d3290642e8d9fe6b2919f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 14 Jun 2020 20:19:35 +0300 Subject: [PATCH 013/211] Remove update website script --- update-website.sh | 46 ---------------------------------------------- 1 file changed, 46 deletions(-) delete mode 100644 update-website.sh diff --git a/update-website.sh b/update-website.sh deleted file mode 100644 index 66192f15f..000000000 --- a/update-website.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/bash -# -# 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. -# - - -# Clone gh-pages -git clone https://github.com/iluwatar/java-design-patterns-web.git -cd java-design-patterns-web - -# Init and update submodule to latest -git submodule update --init --recursive -cd 30-seconds-of-java -git pull origin master -cd ../patterns -git pull origin master -cd ../programming-principles -git pull origin gh-pages -cd .. - -# Setup Git -git config user.name "Travis-CI" -git config user.email "travis@no.reply" - -git add . -git commit -m ":sparkles: :up: Automagic Update via Travis-CI" -git push --quiet "https://${GH_TOKEN}:x-oauth-basic@github.com/iluwatar/java-design-patterns-web.git" master > /dev/null 2>&1 From 5db8037b8b39c797bf85ac4981e852f47ed3d03c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 14 Jun 2020 21:02:40 +0300 Subject: [PATCH 014/211] Add SonarCloud analysis --- .github/workflows/maven.yml | 6 +++++- pom.xml | 10 ++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 9d6727d1e..8fe741de4 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -23,4 +23,8 @@ jobs: - name: Install xvfb run: sudo apt-get install xvfb - name: Build with Maven - run: xvfb-run mvn clean verify + with: + args: xvfb-run mvn clean verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar + env: + GITHUB_TOKEN: ${{ secrets.REPOSITORY_ACCESS_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} diff --git a/pom.xml b/pom.xml index 97deda703..476c8acdb 100644 --- a/pom.xml +++ b/pom.xml @@ -54,6 +54,11 @@ 1.3.2 1.19.0 1.4.8 + + https://sonarcloud.io + iluwatar + iluwatar_java-design-patterns + Java Design Patterns abstract-factory @@ -400,6 +405,11 @@ + + org.sonarsource.scanner.maven + sonar-maven-plugin + 3.7.0.1746 + From cfa2b35bff873cb89a8bf5a8240b38f356e717ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 14 Jun 2020 21:04:09 +0300 Subject: [PATCH 015/211] Fix syntax --- .github/workflows/maven.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 8fe741de4..b2d55755c 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -23,8 +23,7 @@ jobs: - name: Install xvfb run: sudo apt-get install xvfb - name: Build with Maven - with: - args: xvfb-run mvn clean verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar + run: xvfb-run mvn clean verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar env: GITHUB_TOKEN: ${{ secrets.REPOSITORY_ACCESS_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} From 30678792fd71d7b14d56c2d9b558c65f172b5406 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 14 Jun 2020 21:23:07 +0300 Subject: [PATCH 016/211] Remove extra project key --- pom.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/pom.xml b/pom.xml index 476c8acdb..3dc011d32 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,6 @@ https://sonarcloud.io iluwatar - iluwatar_java-design-patterns Java Design Patterns From a396d972f6c95f4778d5fcf2bd89054d78a7f096 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 14 Jun 2020 21:54:47 +0300 Subject: [PATCH 017/211] Add sonar modulekey --- pom.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pom.xml b/pom.xml index 3dc011d32..93e0fc03b 100644 --- a/pom.xml +++ b/pom.xml @@ -57,6 +57,8 @@ https://sonarcloud.io iluwatar + iluwatar_java-design-patterns + ${artifactId} Java Design Patterns From f4f9c1a44129d52b9e8a3f1ebff5e8bb1f671dbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 14 Jun 2020 22:15:13 +0300 Subject: [PATCH 018/211] Remove gh token --- .github/workflows/maven.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index b2d55755c..1b0907950 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -25,5 +25,4 @@ jobs: - name: Build with Maven run: xvfb-run mvn clean verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar env: - GITHUB_TOKEN: ${{ secrets.REPOSITORY_ACCESS_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} From 5192beb5dd255afd1e740dc67bd4f14e2563547d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 14 Jun 2020 22:36:47 +0300 Subject: [PATCH 019/211] Re-add gh access token --- .github/workflows/maven.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 1b0907950..458075a28 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -20,9 +20,12 @@ jobs: uses: actions/setup-java@v1 with: java-version: 11 + # Some tests need screen access - name: Install xvfb run: sudo apt-get install xvfb - name: Build with Maven run: xvfb-run mvn clean verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar env: + # These two env variables are needed for sonar analysis + GITHUB_TOKEN: ${{ secrets.REPOSITORY_ACCESS_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} From 6fe219d644bb9f80c4190c82b1a45eb91089bc88 Mon Sep 17 00:00:00 2001 From: ZhouSky <57678580+ZhouSky@users.noreply.github.com> Date: Sat, 4 Jul 2020 17:05:46 +0800 Subject: [PATCH 020/211] Pr/1235 Review (#1250) * Add simple implementation for strangler pattern. * Add strangler pattern in pom.xml. * change package name * Revert "change package name" This reverts commit 430bd9073ea7bea6430586a0953c77f1798aacc8. * Code review for strangler Delete final of method parameters. Add final to private members. Change package name. * Revert "Code review for strangler" This reverts commit d5063567083e0348d678a938bd749e17343bcb8e. * Revert "Revert "Code review for strangler"" This reverts commit c8fd65fda782749c4f74f6de85da0f271d3c48a8. * Remove unnecessary files --- pom.xml | 1 + strangler/README.md | 31 ++++++++ strangler/etc/strangler.png | Bin 0 -> 77937 bytes strangler/etc/strangler.puml | 61 +++++++++++++++ strangler/pom.xml | 66 ++++++++++++++++ .../main/java/com/iluwatar/strangler/App.java | 69 ++++++++++++++++ .../iluwatar/strangler/HalfArithmetic.java | 74 ++++++++++++++++++ .../com/iluwatar/strangler/HalfSource.java | 54 +++++++++++++ .../com/iluwatar/strangler/NewArithmetic.java | 71 +++++++++++++++++ .../com/iluwatar/strangler/NewSource.java | 56 +++++++++++++ .../com/iluwatar/strangler/OldArithmetic.java | 61 +++++++++++++++ .../com/iluwatar/strangler/OldSource.java | 59 ++++++++++++++ .../java/com/iluwatar/strangler/AppTest.java | 36 +++++++++ .../strangler/HalfArithmeticTest.java | 50 ++++++++++++ .../iluwatar/strangler/HalfSourceTest.java | 47 +++++++++++ .../iluwatar/strangler/NewArithmeticTest.java | 50 ++++++++++++ .../com/iluwatar/strangler/NewSourceTest.java | 51 ++++++++++++ .../iluwatar/strangler/OldArithmeticTest.java | 45 +++++++++++ .../com/iluwatar/strangler/OldSourceTest.java | 45 +++++++++++ 19 files changed, 927 insertions(+) create mode 100644 strangler/README.md create mode 100644 strangler/etc/strangler.png create mode 100644 strangler/etc/strangler.puml create mode 100644 strangler/pom.xml create mode 100644 strangler/src/main/java/com/iluwatar/strangler/App.java create mode 100644 strangler/src/main/java/com/iluwatar/strangler/HalfArithmetic.java create mode 100644 strangler/src/main/java/com/iluwatar/strangler/HalfSource.java create mode 100644 strangler/src/main/java/com/iluwatar/strangler/NewArithmetic.java create mode 100644 strangler/src/main/java/com/iluwatar/strangler/NewSource.java create mode 100644 strangler/src/main/java/com/iluwatar/strangler/OldArithmetic.java create mode 100644 strangler/src/main/java/com/iluwatar/strangler/OldSource.java create mode 100644 strangler/src/test/java/com/iluwatar/strangler/AppTest.java create mode 100644 strangler/src/test/java/com/iluwatar/strangler/HalfArithmeticTest.java create mode 100644 strangler/src/test/java/com/iluwatar/strangler/HalfSourceTest.java create mode 100644 strangler/src/test/java/com/iluwatar/strangler/NewArithmeticTest.java create mode 100644 strangler/src/test/java/com/iluwatar/strangler/NewSourceTest.java create mode 100644 strangler/src/test/java/com/iluwatar/strangler/OldArithmeticTest.java create mode 100644 strangler/src/test/java/com/iluwatar/strangler/OldSourceTest.java diff --git a/pom.xml b/pom.xml index 93e0fc03b..f23369107 100644 --- a/pom.xml +++ b/pom.xml @@ -190,6 +190,7 @@ combinator update-method leader-followers + strangler arrange-act-assert diff --git a/strangler/README.md b/strangler/README.md new file mode 100644 index 000000000..2f157f1d2 --- /dev/null +++ b/strangler/README.md @@ -0,0 +1,31 @@ +--- +layout: pattern +title: Strangler +folder: strangler +permalink: /patterns/strangler/ +categories: Structural +tags: + - Extensibility +--- + +## Intent +Incrementally migrate a legacy system by gradually replacing specific pieces of functionality +with new applications and services. As features from the legacy system are replaced, the new +system eventually covers all the old system's features and may has its own new features, then +strangling the old system and allowing you to decommission it. + +## Class diagram +![alt text](./etc/strangler.png "Strangler") + +## Applicability +This strangler pattern is a safe way to phase one thing out for something better, cheaper, or +more expandable. Especially when you want to update legacy system with new techniques and need +continuously develop new features at the same time. Note that this pattern indeed need extra effort, +so usually use it when the system is not so simple. + +## Credits + +* [Strangler pattern](https://docs.microsoft.com/en-us/azure/architecture/patterns/strangler#context-and-problem) +* [Legacy Application Strangulation : Case Studies](https://paulhammant.com/2013/07/14/legacy-application-strangulation-case-studies/) + + diff --git a/strangler/etc/strangler.png b/strangler/etc/strangler.png new file mode 100644 index 0000000000000000000000000000000000000000..c69305e5d510465a75b001096cdd7c8c15631ed5 GIT binary patch literal 77937 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

#F}1lmPB;v?LX5AgNsNa&jF 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 literal 0 HcmV?d00001 diff --git a/strangler/etc/strangler.puml b/strangler/etc/strangler.puml new file mode 100644 index 000000000..cb2c266a1 --- /dev/null +++ b/strangler/etc/strangler.puml @@ -0,0 +1,61 @@ +@startuml + +package com.iluwatar.strangler { + class App { + + main(args : String[]) {static} + } + + class OldArithmetic { + - LOGGER : Logger {static} + - VERSION : String {static} + - source : OldSource + + sum(nums : int...) + + mul(nums : int...) + } + + class HalfArithmetic { + - LOGGER : Logger {static} + - VERSION : String {static} + - oldSource : OldSource + - newSource : HalfSource + + sum(nums : int...) + + mul(nums : int...) + + ifHasZero(nums : int...) + } + + class NewArithmetic { + - LOGGER : Logger {static} + - VERSION : String {static} + - source : NewSource + + sum(nums : int...) + + mul(nums : int...) + + ifHasZero(nums : int...) + } + + class OldSource { + - LOGGER : Logger {static} + - VERSION : String {static} + + accumulateSum(nums : int...) + + accumulateMul(nums : int...) + } + + class HalfSource { + - LOGGER : Logger {static} + - VERSION : String {static} + + accumulateSum(nums : int...) + + ifNonZero(nums : int...) + } + + class NewSource { + - LOGGER : Logger {static} + - VERSION : String {static} + + accumulateSum(nums : int...) + + accumulateMul(nums : int...) + + ifNonZero(nums : int...) + } +} +OldArithmetic o--> OldSource +HalfArithmetic o--> OldSource +HalfArithmetic o--> HalfSource +NewArithmetic o--> NewSource +@enduml \ No newline at end of file diff --git a/strangler/pom.xml b/strangler/pom.xml new file mode 100644 index 000000000..4a1fb42ba --- /dev/null +++ b/strangler/pom.xml @@ -0,0 +1,66 @@ + + + + + java-design-patterns + com.iluwatar + 1.23.0-SNAPSHOT + + 4.0.0 + + strangler + + + + org.junit.jupiter + junit-jupiter-engine + test + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + + + + com.iluwatar.strangler.App + + + + + + + + + + + \ No newline at end of file diff --git a/strangler/src/main/java/com/iluwatar/strangler/App.java b/strangler/src/main/java/com/iluwatar/strangler/App.java new file mode 100644 index 000000000..bba0f7f74 --- /dev/null +++ b/strangler/src/main/java/com/iluwatar/strangler/App.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.strangler; + +/** + * + *

The Strangler pattern is a software design pattern that incrementally migrate a legacy + * system by gradually replacing specific pieces of functionality with new applications and + * services. As features from the legacy system are replaced, the new system eventually + * replaces all of the old system's features, strangling the old system and allowing you + * to decommission it.

+ * + *

This pattern is not only about updating but also enhancement.

+ * + *

In this example, {@link OldArithmetic} indicates old system and its implementation depends + * on its source ({@link OldSource}). Now we tend to update system with new techniques and + * new features. In reality, the system may too complex, so usually need gradual migration. + * {@link HalfArithmetic} indicates system in the process of migration, its implementation + * depends on old one ({@link OldSource}) and under development one ({@link HalfSource}). The + * {@link HalfSource} covers part of {@link OldSource} and add new functionality. You can release + * this version system with new features, which also supports old version system functionalities. + * After whole migration, the new system ({@link NewArithmetic}) only depends on new source + * ({@link NewSource}).

+ * + */ +public class App { + /** + * Program entry point. + * @param args command line args + */ + public static void main(final String[] args) { + final var nums = new int[]{1, 2, 3, 4, 5}; + //Before migration + final var oldSystem = new OldArithmetic(new OldSource()); + oldSystem.sum(nums); + oldSystem.mul(nums); + //In process of migration + final var halfSystem = new HalfArithmetic(new HalfSource(), new OldSource()); + halfSystem.sum(nums); + halfSystem.mul(nums); + halfSystem.ifHasZero(nums); + //After migration + final var newSystem = new NewArithmetic(new NewSource()); + newSystem.sum(nums); + newSystem.mul(nums); + newSystem.ifHasZero(nums); + } +} diff --git a/strangler/src/main/java/com/iluwatar/strangler/HalfArithmetic.java b/strangler/src/main/java/com/iluwatar/strangler/HalfArithmetic.java new file mode 100644 index 000000000..be9c15ec5 --- /dev/null +++ b/strangler/src/main/java/com/iluwatar/strangler/HalfArithmetic.java @@ -0,0 +1,74 @@ +/* + * 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.strangler; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * System under migration. Depends on old version source ({@link OldSource}) and + * developing one ({@link HalfSource}). + */ +public class HalfArithmetic { + private static final Logger LOGGER = LoggerFactory.getLogger(HalfArithmetic.class); + private static final String VERSION = "1.5"; + + private final HalfSource newSource; + private final OldSource oldSource; + + public HalfArithmetic(HalfSource newSource, OldSource oldSource) { + this.newSource = newSource; + this.oldSource = oldSource; + } + + /** + * Accumulate sum. + * @param nums numbers need to add together + * @return accumulate sum + */ + public int sum(int... nums) { + LOGGER.info("Arithmetic sum {}", VERSION); + return newSource.accumulateSum(nums); + } + + /** + * Accumulate multiplication. + * @param nums numbers need to multiply together + * @return accumulate multiplication + */ + public int mul(int... nums) { + LOGGER.info("Arithmetic mul {}", VERSION); + return oldSource.accumulateMul(nums); + } + + /** + * Chech if has any zero. + * @param nums numbers need to check + * @return if has any zero, return true, else, return false + */ + public boolean ifHasZero(int... nums) { + LOGGER.info("Arithmetic check zero {}", VERSION); + return !newSource.ifNonZero(nums); + } +} diff --git a/strangler/src/main/java/com/iluwatar/strangler/HalfSource.java b/strangler/src/main/java/com/iluwatar/strangler/HalfSource.java new file mode 100644 index 000000000..b83293335 --- /dev/null +++ b/strangler/src/main/java/com/iluwatar/strangler/HalfSource.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.strangler; + +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Source under development. Replace part of old source and has added some new features. + */ +public class HalfSource { + private static final Logger LOGGER = LoggerFactory.getLogger(HalfSource.class); + private static final String VERSION = "1.5"; + + /** + * Implement accumulate sum with new technique. + * Replace old one in {@link OldSource} + */ + public int accumulateSum(int... nums) { + LOGGER.info("Source module {}", VERSION); + return Arrays.stream(nums).reduce(0, Integer::sum); + } + + /** + * Check if all number is not zero. + * New feature. + */ + public boolean ifNonZero(int... nums) { + LOGGER.info("Source module {}", VERSION); + return Arrays.stream(nums).allMatch(num -> num != 0); + } +} diff --git a/strangler/src/main/java/com/iluwatar/strangler/NewArithmetic.java b/strangler/src/main/java/com/iluwatar/strangler/NewArithmetic.java new file mode 100644 index 000000000..8e482c8b3 --- /dev/null +++ b/strangler/src/main/java/com/iluwatar/strangler/NewArithmetic.java @@ -0,0 +1,71 @@ +/* + * 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.strangler; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * System after whole migration. Only depends on new version source ({@link NewSource}). + */ +public class NewArithmetic { + private static final Logger LOGGER = LoggerFactory.getLogger(NewArithmetic.class); + private static final String VERSION = "2.0"; + + private final NewSource source; + + public NewArithmetic(NewSource source) { + this.source = source; + } + + /** + * Accumulate sum. + * @param nums numbers need to add together + * @return accumulate sum + */ + public int sum(int... nums) { + LOGGER.info("Arithmetic sum {}", VERSION); + return source.accumulateSum(nums); + } + + /** + * Accumulate multiplication. + * @param nums numbers need to multiply together + * @return accumulate multiplication + */ + public int mul(int... nums) { + LOGGER.info("Arithmetic mul {}", VERSION); + return source.accumulateMul(nums); + } + + /** + * Chech if has any zero. + * @param nums numbers need to check + * @return if has any zero, return true, else, return false + */ + public boolean ifHasZero(int... nums) { + LOGGER.info("Arithmetic check zero {}", VERSION); + return !source.ifNonZero(nums); + } +} diff --git a/strangler/src/main/java/com/iluwatar/strangler/NewSource.java b/strangler/src/main/java/com/iluwatar/strangler/NewSource.java new file mode 100644 index 000000000..f53a31bd8 --- /dev/null +++ b/strangler/src/main/java/com/iluwatar/strangler/NewSource.java @@ -0,0 +1,56 @@ +/* + * 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.strangler; + +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * New source. Completely covers functionalities of old source with new techniques + * and also has some new features. + */ +public class NewSource { + private static final Logger LOGGER = LoggerFactory.getLogger(NewSource.class); + private static final String VERSION = "2.0"; + + public int accumulateSum(int... nums) { + LOGGER.info("Source module {}", VERSION); + return Arrays.stream(nums).reduce(0, Integer::sum); + } + + /** + * Implement accumulate multiply with new technique. + * Replace old one in {@link OldSource} + */ + public int accumulateMul(int... nums) { + LOGGER.info("Source module {}", VERSION); + return Arrays.stream(nums).reduce(1, (a, b) -> a * b); + } + + public boolean ifNonZero(int... nums) { + LOGGER.info("Source module {}", VERSION); + return Arrays.stream(nums).allMatch(num -> num != 0); + } +} diff --git a/strangler/src/main/java/com/iluwatar/strangler/OldArithmetic.java b/strangler/src/main/java/com/iluwatar/strangler/OldArithmetic.java new file mode 100644 index 000000000..e9d57987a --- /dev/null +++ b/strangler/src/main/java/com/iluwatar/strangler/OldArithmetic.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.strangler; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Old version system depends on old version source ({@link OldSource}). + */ +public class OldArithmetic { + private static final Logger LOGGER = LoggerFactory.getLogger(OldArithmetic.class); + private static final String VERSION = "1.0"; + + private final OldSource source; + + public OldArithmetic(OldSource source) { + this.source = source; + } + + /** + * Accumulate sum. + * @param nums numbers need to add together + * @return accumulate sum + */ + public int sum(int... nums) { + LOGGER.info("Arithmetic sum {}", VERSION); + return source.accumulateSum(nums); + } + + /** + * Accumulate multiplication. + * @param nums numbers need to multiply together + * @return accumulate multiplication + */ + public int mul(int... nums) { + LOGGER.info("Arithmetic mul {}", VERSION); + return source.accumulateMul(nums); + } +} diff --git a/strangler/src/main/java/com/iluwatar/strangler/OldSource.java b/strangler/src/main/java/com/iluwatar/strangler/OldSource.java new file mode 100644 index 000000000..0ac0b5a07 --- /dev/null +++ b/strangler/src/main/java/com/iluwatar/strangler/OldSource.java @@ -0,0 +1,59 @@ +/* + * 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.strangler; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Old source with techniques out of date. + */ +public class OldSource { + private static final Logger LOGGER = LoggerFactory.getLogger(OldSource.class); + private static final String VERSION = "1.0"; + + /** + * Implement accumulate sum with old technique. + */ + public int accumulateSum(int... nums) { + LOGGER.info("Source module {}", VERSION); + var sum = 0; + for (final var num : nums) { + sum += num; + } + return sum; + } + + /** + * Implement accumulate multiply with old technique. + */ + public int accumulateMul(int... nums) { + LOGGER.info("Source module {}", VERSION); + var sum = 1; + for (final var num : nums) { + sum *= num; + } + return sum; + } +} diff --git a/strangler/src/test/java/com/iluwatar/strangler/AppTest.java b/strangler/src/test/java/com/iluwatar/strangler/AppTest.java new file mode 100644 index 000000000..a9e878a94 --- /dev/null +++ b/strangler/src/test/java/com/iluwatar/strangler/AppTest.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.strangler; + +import org.junit.jupiter.api.Test; + +/** + * Application test + */ +public class AppTest { + @Test + public void test() { + App.main(new String[]{}); + } +} diff --git a/strangler/src/test/java/com/iluwatar/strangler/HalfArithmeticTest.java b/strangler/src/test/java/com/iluwatar/strangler/HalfArithmeticTest.java new file mode 100644 index 000000000..004631966 --- /dev/null +++ b/strangler/src/test/java/com/iluwatar/strangler/HalfArithmeticTest.java @@ -0,0 +1,50 @@ +/* + * 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.strangler; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Test methods in HalfArithmetic + */ +class HalfArithmeticTest { + private static final HalfArithmetic arithmetic = new HalfArithmetic(new HalfSource(), new OldSource()); + + @Test + public void testSum() { + assertEquals(0, arithmetic.sum(-1, 0, 1)); + } + + @Test + public void testMul() { + assertEquals(0, arithmetic.mul(-1, 0, 1)); + } + + @Test + public void testIfHasZero() { + assertTrue(arithmetic.ifHasZero(-1, 0, 1)); + } +} \ No newline at end of file diff --git a/strangler/src/test/java/com/iluwatar/strangler/HalfSourceTest.java b/strangler/src/test/java/com/iluwatar/strangler/HalfSourceTest.java new file mode 100644 index 000000000..a8f9fc6ac --- /dev/null +++ b/strangler/src/test/java/com/iluwatar/strangler/HalfSourceTest.java @@ -0,0 +1,47 @@ +/* + * 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.strangler; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertFalse; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Test methods in HalfSource + */ +public class HalfSourceTest { + private static final HalfSource source = new HalfSource(); + + @Test + public void testAccumulateSum() { + assertEquals(0, source.accumulateSum(-1, 0, 1)); + } + + @Test + public void testIfNonZero() { + assertFalse(source.ifNonZero(-1, 0, 1)); + } +} diff --git a/strangler/src/test/java/com/iluwatar/strangler/NewArithmeticTest.java b/strangler/src/test/java/com/iluwatar/strangler/NewArithmeticTest.java new file mode 100644 index 000000000..edb20241b --- /dev/null +++ b/strangler/src/test/java/com/iluwatar/strangler/NewArithmeticTest.java @@ -0,0 +1,50 @@ +/* + * 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.strangler; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Test methods in NewArithmetic + */ +class NewArithmeticTest { + private static final NewArithmetic arithmetic = new NewArithmetic(new NewSource()); + + @Test + public void testSum() { + assertEquals(0, arithmetic.sum(-1, 0, 1)); + } + + @Test + public void testMul() { + assertEquals(0, arithmetic.mul(-1, 0, 1)); + } + + @Test + public void testIfHasZero() { + assertTrue(arithmetic.ifHasZero(-1, 0, 1)); + } +} \ No newline at end of file diff --git a/strangler/src/test/java/com/iluwatar/strangler/NewSourceTest.java b/strangler/src/test/java/com/iluwatar/strangler/NewSourceTest.java new file mode 100644 index 000000000..577cc0daf --- /dev/null +++ b/strangler/src/test/java/com/iluwatar/strangler/NewSourceTest.java @@ -0,0 +1,51 @@ +/* + * 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.strangler; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + +/** + * Test methods in NewSource + */ +public class NewSourceTest { + private static final NewSource source = new NewSource(); + + @Test + public void testAccumulateSum() { + assertEquals(0, source.accumulateSum(-1, 0, 1)); + } + + @Test + public void testAccumulateMul() { + assertEquals(0, source.accumulateMul(-1, 0, 1)); + } + + @Test + public void testIfNonZero() { + assertFalse(source.ifNonZero(-1, 0, 1)); + } +} diff --git a/strangler/src/test/java/com/iluwatar/strangler/OldArithmeticTest.java b/strangler/src/test/java/com/iluwatar/strangler/OldArithmeticTest.java new file mode 100644 index 000000000..7f653d311 --- /dev/null +++ b/strangler/src/test/java/com/iluwatar/strangler/OldArithmeticTest.java @@ -0,0 +1,45 @@ +/* + * 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.strangler; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Test methods in OldArithmetic + */ +class OldArithmeticTest { + private static final OldArithmetic arithmetic = new OldArithmetic(new OldSource()); + + @Test + public void testSum() { + assertEquals(0, arithmetic.sum(-1, 0, 1)); + } + + @Test + public void testMul() { + assertEquals(0, arithmetic.mul(-1, 0, 1)); + } +} \ No newline at end of file diff --git a/strangler/src/test/java/com/iluwatar/strangler/OldSourceTest.java b/strangler/src/test/java/com/iluwatar/strangler/OldSourceTest.java new file mode 100644 index 000000000..12d6a6c14 --- /dev/null +++ b/strangler/src/test/java/com/iluwatar/strangler/OldSourceTest.java @@ -0,0 +1,45 @@ +/* + * 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.strangler; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Test methods in OldSource + */ +public class OldSourceTest { + private static final OldSource source = new OldSource(); + + @Test + public void testAccumulateSum() { + assertEquals(0, source.accumulateSum(-1, 0, 1)); + } + + @Test + public void testAccumulateMul() { + assertEquals(0, source.accumulateMul(-1, 0, 1)); + } +} From 9e30383eb6c6c4373d6ecdb7e1ca6cd83fc44726 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sat, 4 Jul 2020 12:20:54 +0300 Subject: [PATCH 021/211] Update license and puml --- .github/workflows/maven.yml | 23 ++++++++++++ strangler/etc/strangler.urm.puml | 61 ++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 strangler/etc/strangler.urm.puml diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 458075a28..53460c97d 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -1,3 +1,26 @@ +# +# 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. +# + # This workflow will build a Java project with Maven # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven diff --git a/strangler/etc/strangler.urm.puml b/strangler/etc/strangler.urm.puml new file mode 100644 index 000000000..afbe4d499 --- /dev/null +++ b/strangler/etc/strangler.urm.puml @@ -0,0 +1,61 @@ +@startuml +package com.iluwatar.strangler { + class App { + + App() + + main(args : String[]) {static} + } + class HalfArithmetic { + - LOGGER : Logger {static} + - VERSION : String {static} + - newSource : HalfSource + - oldSource : OldSource + + HalfArithmetic(newSource : HalfSource, oldSource : OldSource) + + ifHasZero(nums : int[]) : boolean + + mul(nums : int[]) : int + + sum(nums : int[]) : int + } + class HalfSource { + - LOGGER : Logger {static} + - VERSION : String {static} + + HalfSource() + + accumulateSum(nums : int[]) : int + + ifNonZero(nums : int[]) : boolean + } + class NewArithmetic { + - LOGGER : Logger {static} + - VERSION : String {static} + - source : NewSource + + NewArithmetic(source : NewSource) + + ifHasZero(nums : int[]) : boolean + + mul(nums : int[]) : int + + sum(nums : int[]) : int + } + class NewSource { + - LOGGER : Logger {static} + - VERSION : String {static} + + NewSource() + + accumulateMul(nums : int[]) : int + + accumulateSum(nums : int[]) : int + + ifNonZero(nums : int[]) : boolean + } + class OldArithmetic { + - LOGGER : Logger {static} + - VERSION : String {static} + - source : OldSource + + OldArithmetic(source : OldSource) + + mul(nums : int[]) : int + + sum(nums : int[]) : int + } + class OldSource { + - LOGGER : Logger {static} + - VERSION : String {static} + + OldSource() + + accumulateMul(nums : int[]) : int + + accumulateSum(nums : int[]) : int + } +} +OldArithmetic --> "-source" OldSource +NewArithmetic --> "-source" NewSource +HalfArithmetic --> "-newSource" HalfSource +HalfArithmetic --> "-oldSource" OldSource +@enduml \ No newline at end of file From a3564a8847f5938bd7345e3bd7473b9ac110337d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Mon, 6 Jul 2020 13:31:07 +0300 Subject: [PATCH 022/211] Update links --- abstract-factory/README.md | 2 +- adapter/README.md | 4 ++-- bridge/README.md | 2 +- builder/README.md | 4 ++-- business-delegate/README.md | 2 +- chain/README.md | 2 +- command/README.md | 2 +- composite/README.md | 2 +- dao/README.md | 2 +- decorator/README.md | 6 +++--- eip-publish-subscribe/README.md | 2 +- execute-around/README.md | 2 +- facade/README.md | 2 +- factory-method/README.md | 2 +- flyweight/README.md | 2 +- front-controller/README.md | 4 ++-- half-sync-half-async/README.md | 2 +- interpreter/README.md | 2 +- iterator/README.md | 2 +- layers/README.md | 2 +- lazy-loading/README.md | 2 +- marker/README.md | 2 +- mediator/README.md | 2 +- memento/README.md | 2 +- model-view-controller/README.md | 4 ++-- null-object/README.md | 2 +- observer/README.md | 4 ++-- prototype/README.md | 2 +- proxy/README.md | 2 +- reactor/README.md | 2 +- service-layer/README.md | 2 +- service-locator/README.md | 2 +- singleton/README.md | 4 ++-- state/README.md | 2 +- strategy/README.md | 4 ++-- template-method/README.md | 2 +- typeobjectpattern/README.md | 4 ++-- visitor/README.md | 2 +- 38 files changed, 48 insertions(+), 48 deletions(-) diff --git a/abstract-factory/README.md b/abstract-factory/README.md index 6a840f316..2c6a31237 100644 --- a/abstract-factory/README.md +++ b/abstract-factory/README.md @@ -198,4 +198,4 @@ Use the Abstract Factory pattern when ## Credits -* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) +* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) diff --git a/adapter/README.md b/adapter/README.md index a8a0214be..d3090dae8 100644 --- a/adapter/README.md +++ b/adapter/README.md @@ -129,5 +129,5 @@ An object adapter ## 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) +* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) +* [J2EE Design Patterns](https://www.amazon.com/gp/product/0596004273/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596004273&linkCode=as2&tag=javadesignpat-20&linkId=48d37c67fb3d845b802fa9b619ad8f31) diff --git a/bridge/README.md b/bridge/README.md index ebd6e5b41..8049305d5 100644 --- a/bridge/README.md +++ b/bridge/README.md @@ -194,4 +194,4 @@ Use the Bridge pattern when ## Credits -* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) +* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) diff --git a/builder/README.md b/builder/README.md index ccfc378d6..ee02a913b 100644 --- a/builder/README.md +++ b/builder/README.md @@ -131,5 +131,5 @@ Use the Builder pattern when ## 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) +* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) +* [Effective Java](https://www.amazon.com/gp/product/0134685997/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0134685997&linkCode=as2&tag=javadesignpat-20&linkId=4e349f4b3ff8c50123f8147c828e53eb) diff --git a/business-delegate/README.md b/business-delegate/README.md index 38eb591b8..b00c67819 100644 --- a/business-delegate/README.md +++ b/business-delegate/README.md @@ -26,4 +26,4 @@ Use the Business Delegate pattern when ## Credits -* [J2EE Design Patterns](http://www.amazon.com/J2EE-Design-Patterns-William-Crawford/dp/0596004273/ref=sr_1_2) +* [J2EE Design Patterns](https://www.amazon.com/gp/product/0596004273/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596004273&linkCode=as2&tag=javadesignpat-20&linkId=48d37c67fb3d845b802fa9b619ad8f31) diff --git a/chain/README.md b/chain/README.md index 1dc8af41c..ce105feec 100644 --- a/chain/README.md +++ b/chain/README.md @@ -157,4 +157,4 @@ Use Chain of Responsibility when ## Credits -* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) +* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) diff --git a/command/README.md b/command/README.md index bab95b90c..17d754d97 100644 --- a/command/README.md +++ b/command/README.md @@ -43,4 +43,4 @@ Use the Command pattern when you want to ## Credits -* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) +* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) diff --git a/composite/README.md b/composite/README.md index 1db1ce14f..b30c8dfc6 100644 --- a/composite/README.md +++ b/composite/README.md @@ -168,4 +168,4 @@ Use the Composite pattern when ## Credits -* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) +* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) diff --git a/dao/README.md b/dao/README.md index 9065cb3ee..3fe1ec20e 100644 --- a/dao/README.md +++ b/dao/README.md @@ -23,4 +23,4 @@ Use the Data Access Object in any of the following situations ## Credits -* [J2EE Design Patterns](http://www.amazon.com/J2EE-Design-Patterns-William-Crawford/dp/0596004273/ref=sr_1_2) +* [J2EE Design Patterns](https://www.amazon.com/gp/product/0596004273/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596004273&linkCode=as2&tag=javadesignpat-20&linkId=48d37c67fb3d845b802fa9b619ad8f31) diff --git a/decorator/README.md b/decorator/README.md index 99f225a4c..3534e9d23 100644 --- a/decorator/README.md +++ b/decorator/README.md @@ -131,6 +131,6 @@ Use Decorator ## 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) +* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) +* [Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions](https://www.amazon.com/gp/product/1937785467/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1937785467&linkCode=as2&tag=javadesignpat-20&linkId=7e4e2fb7a141631491534255252fd08b) +* [J2EE Design Patterns](https://www.amazon.com/gp/product/0596004273/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596004273&linkCode=as2&tag=javadesignpat-20&linkId=48d37c67fb3d845b802fa9b619ad8f31) diff --git a/eip-publish-subscribe/README.md b/eip-publish-subscribe/README.md index 3952913af..339885b34 100644 --- a/eip-publish-subscribe/README.md +++ b/eip-publish-subscribe/README.md @@ -21,4 +21,4 @@ Use the Publish Subscribe Channel pattern when ## Credits -* [J2EE Design Patterns](http://www.amazon.com/J2EE-Design-Patterns-William-Crawford/dp/0596004273/ref=sr_1_2) +* [J2EE Design Patterns](https://www.amazon.com/gp/product/0596004273/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596004273&linkCode=as2&tag=javadesignpat-20&linkId=48d37c67fb3d845b802fa9b619ad8f31) diff --git a/execute-around/README.md b/execute-around/README.md index 677a97a6e..25cb09313 100644 --- a/execute-around/README.md +++ b/execute-around/README.md @@ -24,4 +24,4 @@ Use the Execute Around idiom when ## Credits -* [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) +* [Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions](https://www.amazon.com/gp/product/1937785467/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1937785467&linkCode=as2&tag=javadesignpat-20&linkId=7e4e2fb7a141631491534255252fd08b) diff --git a/facade/README.md b/facade/README.md index 48650dfbb..6fabb4cd5 100644 --- a/facade/README.md +++ b/facade/README.md @@ -204,4 +204,4 @@ Use the Facade pattern when ## Credits -* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) +* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) diff --git a/factory-method/README.md b/factory-method/README.md index 48ba6649c..957960706 100644 --- a/factory-method/README.md +++ b/factory-method/README.md @@ -83,4 +83,4 @@ Use the Factory Method pattern when ## Credits -* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) +* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) diff --git a/flyweight/README.md b/flyweight/README.md index a263cc438..e33c09fc5 100644 --- a/flyweight/README.md +++ b/flyweight/README.md @@ -128,4 +128,4 @@ true ## Credits -* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) +* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) diff --git a/front-controller/README.md b/front-controller/README.md index f4a2da970..c93ee70eb 100644 --- a/front-controller/README.md +++ b/front-controller/README.md @@ -29,6 +29,6 @@ Use the Front Controller pattern when ## Credits -* [J2EE Design Patterns](http://www.amazon.com/J2EE-Design-Patterns-William-Crawford/dp/0596004273/ref=sr_1_2) +* [J2EE Design Patterns](https://www.amazon.com/gp/product/0596004273/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596004273&linkCode=as2&tag=javadesignpat-20&linkId=48d37c67fb3d845b802fa9b619ad8f31) * [Presentation Tier Patterns](http://www.javagyan.com/tutorials/corej2eepatterns/presentation-tier-patterns) -* [Patterns of Enterprise Application Architecture](http://www.amazon.com/Patterns-Enterprise-Application-Architecture-Martin/dp/0321127420) +* [Patterns of Enterprise Application Architecture](https://www.amazon.com/gp/product/0321127420/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321127420&linkCode=as2&tag=javadesignpat-20&linkId=d9f7d37b032ca6e96253562d075fcc4a) diff --git a/half-sync-half-async/README.md b/half-sync-half-async/README.md index 5cfb411e5..6a6384422 100644 --- a/half-sync-half-async/README.md +++ b/half-sync-half-async/README.md @@ -34,4 +34,4 @@ Use Half-Sync/Half-Async pattern when ## Credits * [Douglas C. Schmidt and Charles D. Cranor - Half Sync/Half Async](https://www.dre.vanderbilt.edu/~schmidt/PDF/PLoP-95.pdf) -* [Pattern Oriented Software Architecture Vol I-V](http://www.amazon.com/Pattern-Oriented-Software-Architecture-Volume-Patterns/dp/0471958697) +* [Pattern Oriented Software Architecture Volume 2: Patterns for Concurrent and Networked Objects](https://www.amazon.com/gp/product/0471606952/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0471606952&linkCode=as2&tag=javadesignpat-20&linkId=889e4af72dca8261129bf14935e0f8dc) diff --git a/interpreter/README.md b/interpreter/README.md index 6a941d2e5..d99a43809 100644 --- a/interpreter/README.md +++ b/interpreter/README.md @@ -34,4 +34,4 @@ trees. The Interpreter pattern works best when ## Credits -* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) +* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) diff --git a/iterator/README.md b/iterator/README.md index 61cf0291a..7722c3166 100644 --- a/iterator/README.md +++ b/iterator/README.md @@ -32,4 +32,4 @@ Use the Iterator pattern ## Credits -* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) +* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) diff --git a/layers/README.md b/layers/README.md index 58c9cd828..c3c56ad00 100644 --- a/layers/README.md +++ b/layers/README.md @@ -103,4 +103,4 @@ Use the Layers architecture when ## Credits -* [Pattern Oriented Software Architecture Vol I-V](http://www.amazon.com/Pattern-Oriented-Software-Architecture-Volume-Patterns/dp/0471958697) +* [Pattern Oriented Software Architecture Volume 1: A System of Patterns](https://www.amazon.com/gp/product/0471958697/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0471958697&linkCode=as2&tag=javadesignpat-20&linkId=e3f42d7a2a4cc8c619bbc0136b20dadb) diff --git a/lazy-loading/README.md b/lazy-loading/README.md index 997149b03..116a17351 100644 --- a/lazy-loading/README.md +++ b/lazy-loading/README.md @@ -28,4 +28,4 @@ Use the Lazy Loading idiom when ## Credits -* [J2EE Design Patterns](http://www.amazon.com/J2EE-Design-Patterns-William-Crawford/dp/0596004273/ref=sr_1_2) +* [J2EE Design Patterns](https://www.amazon.com/gp/product/0596004273/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596004273&linkCode=as2&tag=javadesignpat-20&linkId=48d37c67fb3d845b802fa9b619ad8f31) diff --git a/marker/README.md b/marker/README.md index a411827c3..d8664327f 100644 --- a/marker/README.md +++ b/marker/README.md @@ -27,4 +27,4 @@ Use the Marker Interface pattern when ## Credits -* [Effective Java 2nd Edition by Joshua Bloch](https://www.amazon.com/Effective-Java-2nd-Joshua-Bloch/dp/0321356683) +* [Effective Java](https://www.amazon.com/gp/product/0134685997/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0134685997&linkCode=as2&tag=javadesignpat-20&linkId=4e349f4b3ff8c50123f8147c828e53eb) diff --git a/mediator/README.md b/mediator/README.md index e8e0fa412..5071cff7a 100644 --- a/mediator/README.md +++ b/mediator/README.md @@ -34,4 +34,4 @@ Use the Mediator pattern when ## Credits -* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) +* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) diff --git a/memento/README.md b/memento/README.md index 6dd262f9c..c2bc2210f 100644 --- a/memento/README.md +++ b/memento/README.md @@ -30,4 +30,4 @@ Use the Memento pattern when ## Credits -* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) +* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) diff --git a/model-view-controller/README.md b/model-view-controller/README.md index c1542df04..0b5314ad8 100644 --- a/model-view-controller/README.md +++ b/model-view-controller/README.md @@ -25,5 +25,5 @@ Use the Model-View-Controller pattern when ## Credits * [Trygve Reenskaug - Model-view-controller](http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) -* [J2EE Design Patterns](http://www.amazon.com/J2EE-Design-Patterns-William-Crawford/dp/0596004273/ref=sr_1_2) -* [Patterns of Enterprise Application Architecture](http://www.amazon.com/Patterns-Enterprise-Application-Architecture-Martin/dp/0321127420) +* [J2EE Design Patterns](https://www.amazon.com/gp/product/0596004273/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596004273&linkCode=as2&tag=javadesignpat-20&linkId=48d37c67fb3d845b802fa9b619ad8f31) +* [Patterns of Enterprise Application Architecture](https://www.amazon.com/gp/product/0321127420/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321127420&linkCode=as2&tag=javadesignpat-20&linkId=d9f7d37b032ca6e96253562d075fcc4a) diff --git a/null-object/README.md b/null-object/README.md index d0a6f530d..37dbb1cb4 100644 --- a/null-object/README.md +++ b/null-object/README.md @@ -28,4 +28,4 @@ Use the Null Object pattern when ## Credits -* [Pattern Languages of Program Design](http://www.amazon.com/Pattern-Languages-Program-Design-Coplien/dp/0201607344/ref=sr_1_1) +* [Pattern Languages of Program Design 3](https://www.amazon.com/gp/product/0201310112/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201310112&linkCode=as2&tag=javadesignpat-20&linkId=7372ffb8a4e39a3bb10f199b89aef921) diff --git a/observer/README.md b/observer/README.md index 7b31c7450..11f0a405a 100644 --- a/observer/README.md +++ b/observer/README.md @@ -40,5 +40,5 @@ Use the Observer pattern in any of the following situations ## Credits -* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) -* [Java Generics and Collections](http://www.amazon.com/Java-Generics-Collections-Maurice-Naftalin/dp/0596527756/) +* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) +* [Java Generics and Collections](https://www.amazon.com/gp/product/0596527756/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596527756&linkCode=as2&tag=javadesignpat-20&linkId=246e5e2c26fe1c3ada6a70b15afcb195) diff --git a/prototype/README.md b/prototype/README.md index 65d0dbb88..cc18cd681 100644 --- a/prototype/README.md +++ b/prototype/README.md @@ -78,4 +78,4 @@ Use the Prototype pattern when a system should be independent of how its product ## Credits -* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) +* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) diff --git a/proxy/README.md b/proxy/README.md index f9538f4cd..07d4b6942 100644 --- a/proxy/README.md +++ b/proxy/README.md @@ -140,4 +140,4 @@ are several common situations in which the Proxy pattern is applicable ## Credits -* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) +* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) diff --git a/reactor/README.md b/reactor/README.md index 9e66708dd..faf0702d4 100644 --- a/reactor/README.md +++ b/reactor/README.md @@ -30,6 +30,6 @@ Use Reactor pattern when ## Credits * [Douglas C. Schmidt - Reactor](https://www.dre.vanderbilt.edu/~schmidt/PDF/Reactor.pdf) -* [Pattern Oriented Software Architecture Vol I-V](http://www.amazon.com/Pattern-Oriented-Software-Architecture-Volume-Patterns/dp/0471958697) +* [Pattern Oriented Software Architecture Volume 2: Patterns for Concurrent and Networked Objects](https://www.amazon.com/gp/product/0471606952/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0471606952&linkCode=as2&tag=javadesignpat-20&linkId=889e4af72dca8261129bf14935e0f8dc) * [Doug Lea - Scalable IO in Java](http://gee.cs.oswego.edu/dl/cpjslides/nio.pdf) * [Netty](http://netty.io/) diff --git a/service-layer/README.md b/service-layer/README.md index b2b61a17a..3feaf8395 100644 --- a/service-layer/README.md +++ b/service-layer/README.md @@ -28,4 +28,4 @@ Use the Service Layer pattern when ## Credits * [Martin Fowler - Service Layer](http://martinfowler.com/eaaCatalog/serviceLayer.html) -* [Patterns of Enterprise Application Architecture](http://www.amazon.com/Patterns-Enterprise-Application-Architecture-Martin/dp/0321127420) +* [Patterns of Enterprise Application Architecture](https://www.amazon.com/gp/product/0321127420/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321127420&linkCode=as2&tag=javadesignpat-20&linkId=d9f7d37b032ca6e96253562d075fcc4a) diff --git a/service-locator/README.md b/service-locator/README.md index 16c10f4de..0d54f8211 100644 --- a/service-locator/README.md +++ b/service-locator/README.md @@ -40,4 +40,4 @@ to a number of services that they don't potentially need. ## Credits -* [J2EE Design Patterns](http://www.amazon.com/J2EE-Design-Patterns-William-Crawford/dp/0596004273/ref=sr_1_2) +* [J2EE Design Patterns](https://www.amazon.com/gp/product/0596004273/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596004273&linkCode=as2&tag=javadesignpat-20&linkId=48d37c67fb3d845b802fa9b619ad8f31) diff --git a/singleton/README.md b/singleton/README.md index b2fc0420e..4fd300ae8 100644 --- a/singleton/README.md +++ b/singleton/README.md @@ -77,5 +77,5 @@ Use the Singleton pattern when ## 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) +* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) +* [Effective Java](https://www.amazon.com/gp/product/0134685997/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0134685997&linkCode=as2&tag=javadesignpat-20&linkId=4e349f4b3ff8c50123f8147c828e53eb) diff --git a/state/README.md b/state/README.md index d41b75df1..a63945f7e 100644 --- a/state/README.md +++ b/state/README.md @@ -31,4 +31,4 @@ Use the State pattern in either of the following cases ## Credits -* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) +* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) diff --git a/strategy/README.md b/strategy/README.md index 4c6f889e1..338b20e0a 100644 --- a/strategy/README.md +++ b/strategy/README.md @@ -33,5 +33,5 @@ Use the Strategy pattern when ## 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) +* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) +* [Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions](https://www.amazon.com/gp/product/1937785467/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1937785467&linkCode=as2&tag=javadesignpat-20&linkId=7e4e2fb7a141631491534255252fd08b) diff --git a/template-method/README.md b/template-method/README.md index 668d6e28c..5bd5893ef 100644 --- a/template-method/README.md +++ b/template-method/README.md @@ -37,4 +37,4 @@ Method `GenericServlet.init(ServletConfig config)` is the template method in thi ## Credits -* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) +* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) diff --git a/typeobjectpattern/README.md b/typeobjectpattern/README.md index a5a193c54..29e48f216 100644 --- a/typeobjectpattern/README.md +++ b/typeobjectpattern/README.md @@ -30,5 +30,5 @@ This pattern can be used when: ## Credits -* [Game Programming Patterns/Type Object](http://gameprogrammingpatterns.com/type-object.html) by Robert Nystrom -* [http://www.cs.sjsu.edu/~pearce/modules/patterns/analysis/top.htm] +* [Game Programming Patterns - Type Object](http://gameprogrammingpatterns.com/type-object.html) +* [Types as Objects Pattern](http://www.cs.sjsu.edu/~pearce/modules/patterns/analysis/top.htm) diff --git a/visitor/README.md b/visitor/README.md index 382752610..d9162db5b 100644 --- a/visitor/README.md +++ b/visitor/README.md @@ -32,4 +32,4 @@ Use the Visitor pattern when ## Credits -* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) +* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) From bd1dbec19f1bc163c321f48a7816e3c560187ac9 Mon Sep 17 00:00:00 2001 From: "gitlocalize-app[bot]" <55277160+gitlocalize-app[bot]@users.noreply.github.com> Date: Tue, 7 Jul 2020 21:17:11 +0800 Subject: [PATCH 023/211] Translate README.md via GitLocalize (#1259) Co-authored-by: xiaod-dev <657829312@qq.com> --- zh/README.md | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 zh/README.md diff --git a/zh/README.md b/zh/README.md new file mode 100644 index 000000000..d41b5ac07 --- /dev/null +++ b/zh/README.md @@ -0,0 +1,39 @@ + + +# 设计模式Java版 + +![Java CI with Maven](https://github.com/iluwatar/java-design-patterns/workflows/Java%20CI%20with%20Maven/badge.svg) [](https://raw.githubusercontent.com/iluwatar/java-design-patterns/master/LICENSE.md)![License MIT](https://img.shields.io/badge/license-MIT-blue.svg) [](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg) [](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns)![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status) + +# 介绍 + +设计模式是程序员在设计应用程序或系统时可以用来解决常见问题的最佳形式化实践。 + +设计模式可以通过提供经过测试的,经过验证的开发范例来加快开发过程。 + +重用设计模式有助于防止引起重大问题的细微问题,并且还可以为熟悉模式的程序员和架构师们提高代码可读性。 + +# 入门 + +这个站点展示了Java设计模式。该解决方案是由开源社区中经验丰富的程序员和架构师开发的。可以通过他们高级描述或查看源代码来浏览这些设计模式。源代码示例得到了很好的注释,可以视为编程教程,以了解如何实现特定的模式。我们使用最流行的,久经考验的开源Java技术。 + +在深入学习该材料之前,您应该熟悉各种软件设计原则。 + +所有设计应尽可能简单。您应该从KISS,YAGNI开始,并做可能可行的最简单的事情。仅在实际可扩展性需要它们时才应引入复杂性和模式。 + +熟悉这些概念后,您可以通过以下任何一种方法开始深入研究模式 + +- 使用难度标签: `入门难度` , `中等难度`和`专家难度` 。 +- 使用模式分类`创建型` ,`行为型`和其他类别。 +- 搜索特定的模式。一个也找不到?请[在这里](https://github.com/iluwatar/java-design-patterns/issues)反馈新模式。 + +希望您在本站上找到的面向对象解决方案能够对您的体系结构很有用,并在学习它们的时候能够像我们开发它们一样有趣。 + +# 如何做出贡献 + +如果您愿意为该项目做出贡献,则可以在我们的[开发人员Wiki中](https://github.com/iluwatar/java-design-patterns/wiki)找到相关信息。我们将在[Gitter聊天室为](https://gitter.im/iluwatar/java-design-patterns)您提供帮助并回答您的问题。 + +# 许可证 + +该项目使用MIT许可证。 From 0b1a98137a6d4dbd05bd38d5a9aaa2d29882d3ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Tue, 7 Jul 2020 18:05:11 +0300 Subject: [PATCH 024/211] Add links to Head First Design Patterns book --- abstract-factory/README.md | 1 + adapter/README.md | 1 + bridge/README.md | 1 + builder/README.md | 1 + chain/README.md | 1 + command/README.md | 1 + composite/README.md | 1 + decorator/README.md | 1 + facade/README.md | 1 + factory-method/README.md | 1 + flyweight/README.md | 1 + interpreter/README.md | 1 + iterator/README.md | 1 + mediator/README.md | 1 + memento/README.md | 1 + model-view-controller/README.md | 1 + observer/README.md | 1 + prototype/README.md | 1 + proxy/README.md | 1 + singleton/README.md | 1 + state/README.md | 1 + template-method/README.md | 1 + visitor/README.md | 1 + 23 files changed, 23 insertions(+) diff --git a/abstract-factory/README.md b/abstract-factory/README.md index 2c6a31237..fba3460c1 100644 --- a/abstract-factory/README.md +++ b/abstract-factory/README.md @@ -199,3 +199,4 @@ Use the Abstract Factory pattern when ## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) +* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) diff --git a/adapter/README.md b/adapter/README.md index d3090dae8..727bc3ad1 100644 --- a/adapter/README.md +++ b/adapter/README.md @@ -131,3 +131,4 @@ An object adapter * [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) * [J2EE Design Patterns](https://www.amazon.com/gp/product/0596004273/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596004273&linkCode=as2&tag=javadesignpat-20&linkId=48d37c67fb3d845b802fa9b619ad8f31) +* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) diff --git a/bridge/README.md b/bridge/README.md index 8049305d5..82c2f2735 100644 --- a/bridge/README.md +++ b/bridge/README.md @@ -195,3 +195,4 @@ Use the Bridge pattern when ## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) +* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) diff --git a/builder/README.md b/builder/README.md index ee02a913b..861ab6401 100644 --- a/builder/README.md +++ b/builder/README.md @@ -133,3 +133,4 @@ Use the Builder pattern when * [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) * [Effective Java](https://www.amazon.com/gp/product/0134685997/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0134685997&linkCode=as2&tag=javadesignpat-20&linkId=4e349f4b3ff8c50123f8147c828e53eb) +* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) diff --git a/chain/README.md b/chain/README.md index ce105feec..cdc5966bd 100644 --- a/chain/README.md +++ b/chain/README.md @@ -158,3 +158,4 @@ Use Chain of Responsibility when ## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) +* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) diff --git a/command/README.md b/command/README.md index 17d754d97..9d7a70f64 100644 --- a/command/README.md +++ b/command/README.md @@ -44,3 +44,4 @@ Use the Command pattern when you want to ## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) +* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) diff --git a/composite/README.md b/composite/README.md index b30c8dfc6..42057f2ea 100644 --- a/composite/README.md +++ b/composite/README.md @@ -169,3 +169,4 @@ Use the Composite pattern when ## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) +* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) diff --git a/decorator/README.md b/decorator/README.md index 3534e9d23..680cdd66a 100644 --- a/decorator/README.md +++ b/decorator/README.md @@ -134,3 +134,4 @@ Use Decorator * [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) * [Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions](https://www.amazon.com/gp/product/1937785467/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1937785467&linkCode=as2&tag=javadesignpat-20&linkId=7e4e2fb7a141631491534255252fd08b) * [J2EE Design Patterns](https://www.amazon.com/gp/product/0596004273/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596004273&linkCode=as2&tag=javadesignpat-20&linkId=48d37c67fb3d845b802fa9b619ad8f31) +* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) diff --git a/facade/README.md b/facade/README.md index 6fabb4cd5..018c493a7 100644 --- a/facade/README.md +++ b/facade/README.md @@ -205,3 +205,4 @@ Use the Facade pattern when ## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) +* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) diff --git a/factory-method/README.md b/factory-method/README.md index 957960706..5889acb1c 100644 --- a/factory-method/README.md +++ b/factory-method/README.md @@ -84,3 +84,4 @@ Use the Factory Method pattern when ## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) +* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) diff --git a/flyweight/README.md b/flyweight/README.md index e33c09fc5..7b52ef800 100644 --- a/flyweight/README.md +++ b/flyweight/README.md @@ -129,3 +129,4 @@ true ## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) +* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) diff --git a/interpreter/README.md b/interpreter/README.md index d99a43809..1a3122fde 100644 --- a/interpreter/README.md +++ b/interpreter/README.md @@ -35,3 +35,4 @@ trees. The Interpreter pattern works best when ## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) +* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) diff --git a/iterator/README.md b/iterator/README.md index 7722c3166..0836c5970 100644 --- a/iterator/README.md +++ b/iterator/README.md @@ -33,3 +33,4 @@ Use the Iterator pattern ## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) +* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) diff --git a/mediator/README.md b/mediator/README.md index 5071cff7a..22b4556ac 100644 --- a/mediator/README.md +++ b/mediator/README.md @@ -35,3 +35,4 @@ Use the Mediator pattern when ## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) +* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) diff --git a/memento/README.md b/memento/README.md index c2bc2210f..1bf6e442b 100644 --- a/memento/README.md +++ b/memento/README.md @@ -31,3 +31,4 @@ Use the Memento pattern when ## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) +* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) diff --git a/model-view-controller/README.md b/model-view-controller/README.md index 0b5314ad8..1660320fa 100644 --- a/model-view-controller/README.md +++ b/model-view-controller/README.md @@ -27,3 +27,4 @@ Use the Model-View-Controller pattern when * [Trygve Reenskaug - Model-view-controller](http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) * [J2EE Design Patterns](https://www.amazon.com/gp/product/0596004273/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596004273&linkCode=as2&tag=javadesignpat-20&linkId=48d37c67fb3d845b802fa9b619ad8f31) * [Patterns of Enterprise Application Architecture](https://www.amazon.com/gp/product/0321127420/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321127420&linkCode=as2&tag=javadesignpat-20&linkId=d9f7d37b032ca6e96253562d075fcc4a) +* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) diff --git a/observer/README.md b/observer/README.md index 11f0a405a..11195f4c3 100644 --- a/observer/README.md +++ b/observer/README.md @@ -42,3 +42,4 @@ Use the Observer pattern in any of the following situations * [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) * [Java Generics and Collections](https://www.amazon.com/gp/product/0596527756/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596527756&linkCode=as2&tag=javadesignpat-20&linkId=246e5e2c26fe1c3ada6a70b15afcb195) +* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) diff --git a/prototype/README.md b/prototype/README.md index cc18cd681..c51f5c9bc 100644 --- a/prototype/README.md +++ b/prototype/README.md @@ -79,3 +79,4 @@ Use the Prototype pattern when a system should be independent of how its product ## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) +* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) diff --git a/proxy/README.md b/proxy/README.md index 07d4b6942..b89d2a624 100644 --- a/proxy/README.md +++ b/proxy/README.md @@ -141,3 +141,4 @@ are several common situations in which the Proxy pattern is applicable ## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) +* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) diff --git a/singleton/README.md b/singleton/README.md index 4fd300ae8..6732b8c0f 100644 --- a/singleton/README.md +++ b/singleton/README.md @@ -79,3 +79,4 @@ Use the Singleton pattern when * [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) * [Effective Java](https://www.amazon.com/gp/product/0134685997/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0134685997&linkCode=as2&tag=javadesignpat-20&linkId=4e349f4b3ff8c50123f8147c828e53eb) +* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) diff --git a/state/README.md b/state/README.md index a63945f7e..749d0e1d4 100644 --- a/state/README.md +++ b/state/README.md @@ -32,3 +32,4 @@ Use the State pattern in either of the following cases ## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) +* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) diff --git a/template-method/README.md b/template-method/README.md index 5bd5893ef..950dd52b4 100644 --- a/template-method/README.md +++ b/template-method/README.md @@ -38,3 +38,4 @@ Method `GenericServlet.init(ServletConfig config)` is the template method in thi ## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) +* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) diff --git a/visitor/README.md b/visitor/README.md index d9162db5b..4948f2f58 100644 --- a/visitor/README.md +++ b/visitor/README.md @@ -33,3 +33,4 @@ Use the Visitor pattern when ## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) +* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) From 4beb53b8b8c36a912f9547677a948a0f0af76085 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Tue, 7 Jul 2020 18:44:00 +0300 Subject: [PATCH 025/211] Add references to Refactoring to Patterns book --- adapter/README.md | 1 + builder/README.md | 1 + command/README.md | 1 + composite/README.md | 1 + decorator/README.md | 1 + factory-method/README.md | 1 + interpreter/README.md | 1 + null-object/README.md | 1 + observer/README.md | 1 + singleton/README.md | 1 + state/README.md | 1 + strategy/README.md | 2 ++ template-method/README.md | 1 + visitor/README.md | 1 + 14 files changed, 15 insertions(+) diff --git a/adapter/README.md b/adapter/README.md index 727bc3ad1..b36558cbc 100644 --- a/adapter/README.md +++ b/adapter/README.md @@ -132,3 +132,4 @@ An object adapter * [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) * [J2EE Design Patterns](https://www.amazon.com/gp/product/0596004273/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596004273&linkCode=as2&tag=javadesignpat-20&linkId=48d37c67fb3d845b802fa9b619ad8f31) * [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) +* [Refactoring to Patterns](https://www.amazon.com/gp/product/0321213351/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321213351&linkCode=as2&tag=javadesignpat-20&linkId=2a76fcb387234bc71b1c61150b3cc3a7) diff --git a/builder/README.md b/builder/README.md index 861ab6401..bb7426e35 100644 --- a/builder/README.md +++ b/builder/README.md @@ -134,3 +134,4 @@ Use the Builder pattern when * [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) * [Effective Java](https://www.amazon.com/gp/product/0134685997/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0134685997&linkCode=as2&tag=javadesignpat-20&linkId=4e349f4b3ff8c50123f8147c828e53eb) * [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) +* [Refactoring to Patterns](https://www.amazon.com/gp/product/0321213351/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321213351&linkCode=as2&tag=javadesignpat-20&linkId=2a76fcb387234bc71b1c61150b3cc3a7) diff --git a/command/README.md b/command/README.md index 9d7a70f64..d362a7e47 100644 --- a/command/README.md +++ b/command/README.md @@ -45,3 +45,4 @@ Use the Command pattern when you want to * [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) * [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) +* [Refactoring to Patterns](https://www.amazon.com/gp/product/0321213351/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321213351&linkCode=as2&tag=javadesignpat-20&linkId=2a76fcb387234bc71b1c61150b3cc3a7) diff --git a/composite/README.md b/composite/README.md index 42057f2ea..25b553b76 100644 --- a/composite/README.md +++ b/composite/README.md @@ -170,3 +170,4 @@ Use the Composite pattern when * [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) * [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) +* [Refactoring to Patterns](https://www.amazon.com/gp/product/0321213351/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321213351&linkCode=as2&tag=javadesignpat-20&linkId=2a76fcb387234bc71b1c61150b3cc3a7) diff --git a/decorator/README.md b/decorator/README.md index 680cdd66a..a2100ff37 100644 --- a/decorator/README.md +++ b/decorator/README.md @@ -135,3 +135,4 @@ Use Decorator * [Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions](https://www.amazon.com/gp/product/1937785467/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1937785467&linkCode=as2&tag=javadesignpat-20&linkId=7e4e2fb7a141631491534255252fd08b) * [J2EE Design Patterns](https://www.amazon.com/gp/product/0596004273/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596004273&linkCode=as2&tag=javadesignpat-20&linkId=48d37c67fb3d845b802fa9b619ad8f31) * [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) +* [Refactoring to Patterns](https://www.amazon.com/gp/product/0321213351/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321213351&linkCode=as2&tag=javadesignpat-20&linkId=2a76fcb387234bc71b1c61150b3cc3a7) diff --git a/factory-method/README.md b/factory-method/README.md index 5889acb1c..206388537 100644 --- a/factory-method/README.md +++ b/factory-method/README.md @@ -85,3 +85,4 @@ Use the Factory Method pattern when * [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) * [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) +* [Refactoring to Patterns](https://www.amazon.com/gp/product/0321213351/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321213351&linkCode=as2&tag=javadesignpat-20&linkId=2a76fcb387234bc71b1c61150b3cc3a7) diff --git a/interpreter/README.md b/interpreter/README.md index 1a3122fde..505f417d1 100644 --- a/interpreter/README.md +++ b/interpreter/README.md @@ -36,3 +36,4 @@ trees. The Interpreter pattern works best when * [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) * [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) +* [Refactoring to Patterns](https://www.amazon.com/gp/product/0321213351/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321213351&linkCode=as2&tag=javadesignpat-20&linkId=2a76fcb387234bc71b1c61150b3cc3a7) diff --git a/null-object/README.md b/null-object/README.md index 37dbb1cb4..184e903a0 100644 --- a/null-object/README.md +++ b/null-object/README.md @@ -29,3 +29,4 @@ Use the Null Object pattern when ## Credits * [Pattern Languages of Program Design 3](https://www.amazon.com/gp/product/0201310112/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201310112&linkCode=as2&tag=javadesignpat-20&linkId=7372ffb8a4e39a3bb10f199b89aef921) +* [Refactoring to Patterns](https://www.amazon.com/gp/product/0321213351/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321213351&linkCode=as2&tag=javadesignpat-20&linkId=2a76fcb387234bc71b1c61150b3cc3a7) diff --git a/observer/README.md b/observer/README.md index 11195f4c3..034a90e7d 100644 --- a/observer/README.md +++ b/observer/README.md @@ -43,3 +43,4 @@ Use the Observer pattern in any of the following situations * [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) * [Java Generics and Collections](https://www.amazon.com/gp/product/0596527756/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596527756&linkCode=as2&tag=javadesignpat-20&linkId=246e5e2c26fe1c3ada6a70b15afcb195) * [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) +* [Refactoring to Patterns](https://www.amazon.com/gp/product/0321213351/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321213351&linkCode=as2&tag=javadesignpat-20&linkId=2a76fcb387234bc71b1c61150b3cc3a7) diff --git a/singleton/README.md b/singleton/README.md index 6732b8c0f..83f7fb355 100644 --- a/singleton/README.md +++ b/singleton/README.md @@ -80,3 +80,4 @@ Use the Singleton pattern when * [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) * [Effective Java](https://www.amazon.com/gp/product/0134685997/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0134685997&linkCode=as2&tag=javadesignpat-20&linkId=4e349f4b3ff8c50123f8147c828e53eb) * [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) +* [Refactoring to Patterns](https://www.amazon.com/gp/product/0321213351/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321213351&linkCode=as2&tag=javadesignpat-20&linkId=2a76fcb387234bc71b1c61150b3cc3a7) diff --git a/state/README.md b/state/README.md index 749d0e1d4..4f61d3025 100644 --- a/state/README.md +++ b/state/README.md @@ -33,3 +33,4 @@ Use the State pattern in either of the following cases * [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) * [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) +* [Refactoring to Patterns](https://www.amazon.com/gp/product/0321213351/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321213351&linkCode=as2&tag=javadesignpat-20&linkId=2a76fcb387234bc71b1c61150b3cc3a7) diff --git a/strategy/README.md b/strategy/README.md index 338b20e0a..c78753535 100644 --- a/strategy/README.md +++ b/strategy/README.md @@ -35,3 +35,5 @@ Use the Strategy pattern when * [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) * [Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions](https://www.amazon.com/gp/product/1937785467/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1937785467&linkCode=as2&tag=javadesignpat-20&linkId=7e4e2fb7a141631491534255252fd08b) +* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) +* [Refactoring to Patterns](https://www.amazon.com/gp/product/0321213351/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321213351&linkCode=as2&tag=javadesignpat-20&linkId=2a76fcb387234bc71b1c61150b3cc3a7) diff --git a/template-method/README.md b/template-method/README.md index 950dd52b4..e87cfd6de 100644 --- a/template-method/README.md +++ b/template-method/README.md @@ -39,3 +39,4 @@ Method `GenericServlet.init(ServletConfig config)` is the template method in thi * [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) * [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) +* [Refactoring to Patterns](https://www.amazon.com/gp/product/0321213351/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321213351&linkCode=as2&tag=javadesignpat-20&linkId=2a76fcb387234bc71b1c61150b3cc3a7) diff --git a/visitor/README.md b/visitor/README.md index 4948f2f58..3d5d0ee23 100644 --- a/visitor/README.md +++ b/visitor/README.md @@ -34,3 +34,4 @@ Use the Visitor pattern when * [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) * [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) +* [Refactoring to Patterns](https://www.amazon.com/gp/product/0321213351/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321213351&linkCode=as2&tag=javadesignpat-20&linkId=2a76fcb387234bc71b1c61150b3cc3a7) From 2212690468b14c77b956b4d805cd793e18ace2cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Tue, 7 Jul 2020 20:05:35 +0300 Subject: [PATCH 026/211] Add references to J2EE Design Patterns book --- command/README.md | 1 + data-transfer-object/README.md | 1 + decorator/README.md | 1 + dirty-flag/README.md | 4 ++++ front-controller/README.md | 1 + model-view-controller/README.md | 1 + value-object/README.md | 1 + 7 files changed, 10 insertions(+) diff --git a/command/README.md b/command/README.md index d362a7e47..a063b2db0 100644 --- a/command/README.md +++ b/command/README.md @@ -46,3 +46,4 @@ Use the Command pattern when you want to * [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) * [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) * [Refactoring to Patterns](https://www.amazon.com/gp/product/0321213351/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321213351&linkCode=as2&tag=javadesignpat-20&linkId=2a76fcb387234bc71b1c61150b3cc3a7) +* [J2EE Design Patterns](https://www.amazon.com/gp/product/0596004273/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596004273&linkCode=as2&tag=javadesignpat-20&linkId=f27d2644fbe5026ea448791a8ad09c94) diff --git a/data-transfer-object/README.md b/data-transfer-object/README.md index f269fc66b..633c07e41 100644 --- a/data-transfer-object/README.md +++ b/data-transfer-object/README.md @@ -26,3 +26,4 @@ Use the Data Transfer Object pattern when * [Design Pattern - Transfer Object Pattern](https://www.tutorialspoint.com/design_pattern/transfer_object_pattern.htm) * [Data Transfer Object](https://msdn.microsoft.com/en-us/library/ff649585.aspx) +* [J2EE Design Patterns](https://www.amazon.com/gp/product/0596004273/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596004273&linkCode=as2&tag=javadesignpat-20&linkId=f27d2644fbe5026ea448791a8ad09c94) diff --git a/decorator/README.md b/decorator/README.md index a2100ff37..a9dd5d745 100644 --- a/decorator/README.md +++ b/decorator/README.md @@ -136,3 +136,4 @@ Use Decorator * [J2EE Design Patterns](https://www.amazon.com/gp/product/0596004273/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596004273&linkCode=as2&tag=javadesignpat-20&linkId=48d37c67fb3d845b802fa9b619ad8f31) * [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) * [Refactoring to Patterns](https://www.amazon.com/gp/product/0321213351/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321213351&linkCode=as2&tag=javadesignpat-20&linkId=2a76fcb387234bc71b1c61150b3cc3a7) +* [J2EE Design Patterns](https://www.amazon.com/gp/product/0596004273/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596004273&linkCode=as2&tag=javadesignpat-20&linkId=f27d2644fbe5026ea448791a8ad09c94) diff --git a/dirty-flag/README.md b/dirty-flag/README.md index 31cfbae1f..28041782c 100644 --- a/dirty-flag/README.md +++ b/dirty-flag/README.md @@ -9,6 +9,9 @@ tags: - Performance --- +## Also known as +* IsDirty pattern + ## Intent To avoid expensive re-acquisition of resources. The resources retain their identity, are kept in some fast-access storage, and are re-used to avoid having to acquire them again. @@ -24,3 +27,4 @@ Use the Dirty Flag pattern when ## Credits * [Design Patterns: Dirty Flag](https://www.takeupcode.com/podcast/89-design-patterns-dirty-flag/) +* [J2EE Design Patterns](https://www.amazon.com/gp/product/0596004273/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596004273&linkCode=as2&tag=javadesignpat-20&linkId=48d37c67fb3d845b802fa9b619ad8f31) diff --git a/front-controller/README.md b/front-controller/README.md index c93ee70eb..a1c90b950 100644 --- a/front-controller/README.md +++ b/front-controller/README.md @@ -32,3 +32,4 @@ Use the Front Controller pattern when * [J2EE Design Patterns](https://www.amazon.com/gp/product/0596004273/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596004273&linkCode=as2&tag=javadesignpat-20&linkId=48d37c67fb3d845b802fa9b619ad8f31) * [Presentation Tier Patterns](http://www.javagyan.com/tutorials/corej2eepatterns/presentation-tier-patterns) * [Patterns of Enterprise Application Architecture](https://www.amazon.com/gp/product/0321127420/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321127420&linkCode=as2&tag=javadesignpat-20&linkId=d9f7d37b032ca6e96253562d075fcc4a) +* [J2EE Design Patterns](https://www.amazon.com/gp/product/0596004273/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596004273&linkCode=as2&tag=javadesignpat-20&linkId=f27d2644fbe5026ea448791a8ad09c94) diff --git a/model-view-controller/README.md b/model-view-controller/README.md index 1660320fa..7d2430642 100644 --- a/model-view-controller/README.md +++ b/model-view-controller/README.md @@ -28,3 +28,4 @@ Use the Model-View-Controller pattern when * [J2EE Design Patterns](https://www.amazon.com/gp/product/0596004273/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596004273&linkCode=as2&tag=javadesignpat-20&linkId=48d37c67fb3d845b802fa9b619ad8f31) * [Patterns of Enterprise Application Architecture](https://www.amazon.com/gp/product/0321127420/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321127420&linkCode=as2&tag=javadesignpat-20&linkId=d9f7d37b032ca6e96253562d075fcc4a) * [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) +* [J2EE Design Patterns](https://www.amazon.com/gp/product/0596004273/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596004273&linkCode=as2&tag=javadesignpat-20&linkId=f27d2644fbe5026ea448791a8ad09c94) diff --git a/value-object/README.md b/value-object/README.md index ee6d7143b..c4e3ef359 100644 --- a/value-object/README.md +++ b/value-object/README.md @@ -32,3 +32,4 @@ Use the Value Object when * [Patterns of Enterprise Application Architecture](http://www.martinfowler.com/books/eaa.html) * [VALJOs - Value Java Objects : Stephen Colebourne's blog](http://blog.joda.org/2014/03/valjos-value-java-objects.html) * [Value Object : Wikipedia](https://en.wikipedia.org/wiki/Value_object) +* [J2EE Design Patterns](https://www.amazon.com/gp/product/0596004273/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596004273&linkCode=as2&tag=javadesignpat-20&linkId=f27d2644fbe5026ea448791a8ad09c94) From 51f6282e9b1dc0a193ba704d3a599b236a5b35dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Tue, 7 Jul 2020 21:19:14 +0300 Subject: [PATCH 027/211] Add references to Patterns of Enterprise Application Architecture --- data-transfer-object/README.md | 1 + lazy-loading/README.md | 1 + repository/README.md | 1 + unit-of-work/README.md | 1 + 4 files changed, 4 insertions(+) diff --git a/data-transfer-object/README.md b/data-transfer-object/README.md index 633c07e41..c32ecaff7 100644 --- a/data-transfer-object/README.md +++ b/data-transfer-object/README.md @@ -27,3 +27,4 @@ Use the Data Transfer Object pattern when * [Design Pattern - Transfer Object Pattern](https://www.tutorialspoint.com/design_pattern/transfer_object_pattern.htm) * [Data Transfer Object](https://msdn.microsoft.com/en-us/library/ff649585.aspx) * [J2EE Design Patterns](https://www.amazon.com/gp/product/0596004273/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596004273&linkCode=as2&tag=javadesignpat-20&linkId=f27d2644fbe5026ea448791a8ad09c94) +* [Patterns of Enterprise Application Architecture](https://www.amazon.com/gp/product/0321127420/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321127420&linkCode=as2&tag=javadesignpat-20&linkId=014237a67c9d46f384b35e10151956bd) diff --git a/lazy-loading/README.md b/lazy-loading/README.md index 116a17351..53e3b0a83 100644 --- a/lazy-loading/README.md +++ b/lazy-loading/README.md @@ -29,3 +29,4 @@ Use the Lazy Loading idiom when ## Credits * [J2EE Design Patterns](https://www.amazon.com/gp/product/0596004273/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596004273&linkCode=as2&tag=javadesignpat-20&linkId=48d37c67fb3d845b802fa9b619ad8f31) +* [Patterns of Enterprise Application Architecture](https://www.amazon.com/gp/product/0321127420/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321127420&linkCode=as2&tag=javadesignpat-20&linkId=d9f7d37b032ca6e96253562d075fcc4a) diff --git a/repository/README.md b/repository/README.md index b500d2efd..7b5258ea5 100644 --- a/repository/README.md +++ b/repository/README.md @@ -35,3 +35,4 @@ Use the Repository pattern when * [Don’t use DAO, use Repository](http://thinkinginobjects.com/2012/08/26/dont-use-dao-use-repository/) * [Advanced Spring Data JPA - Specifications and Querydsl](https://spring.io/blog/2011/04/26/advanced-spring-data-jpa-specifications-and-querydsl/) * [Repository Pattern Benefits and Spring Implementation](https://stackoverflow.com/questions/40068965/repository-pattern-benefits-and-spring-implementation) +* [Patterns of Enterprise Application Architecture](https://www.amazon.com/gp/product/0321127420/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321127420&linkCode=as2&tag=javadesignpat-20&linkId=d9f7d37b032ca6e96253562d075fcc4a) diff --git a/unit-of-work/README.md b/unit-of-work/README.md index 21f653b7d..94ef784f5 100644 --- a/unit-of-work/README.md +++ b/unit-of-work/README.md @@ -27,3 +27,4 @@ Use the Unit Of Work pattern when * [Design Pattern - Unit Of Work Pattern](https://www.codeproject.com/Articles/581487/Unit-of-Work-Design-Pattern) * [Unit Of Work](https://martinfowler.com/eaaCatalog/unitOfWork.html) +* [Patterns of Enterprise Application Architecture](https://www.amazon.com/gp/product/0321127420/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321127420&linkCode=as2&tag=javadesignpat-20&linkId=d9f7d37b032ca6e96253562d075fcc4a) From ee654cf7b28eaca74d9a5ea85d491ad34525bff3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Tue, 7 Jul 2020 21:23:04 +0300 Subject: [PATCH 028/211] Add references to Enterprise Integration Patterns --- eip-aggregator/README.md | 1 + eip-message-channel/README.md | 1 + eip-publish-subscribe/README.md | 1 + eip-splitter/README.md | 1 + eip-wire-tap/README.md | 1 + 5 files changed, 5 insertions(+) diff --git a/eip-aggregator/README.md b/eip-aggregator/README.md index 6138af0a8..8f19c21ad 100644 --- a/eip-aggregator/README.md +++ b/eip-aggregator/README.md @@ -29,3 +29,4 @@ Use the Aggregator pattern when * [Gregor Hohpe, Bobby Woolf - Enterprise Integration Patterns](http://www.enterpriseintegrationpatterns.com/patterns/messaging/Aggregator.html) * [Apache Camel - Documentation](http://camel.apache.org/aggregator2.html) +* [Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions](https://www.amazon.com/gp/product/0321200683/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321200683&linkCode=as2&tag=javadesignpat-20&linkId=122e0cff74eedd004cc81a3ecfa623cf) diff --git a/eip-message-channel/README.md b/eip-message-channel/README.md index 8e2f5dc8f..b1c456aeb 100644 --- a/eip-message-channel/README.md +++ b/eip-message-channel/README.md @@ -23,3 +23,4 @@ Use the Message Channel pattern when ## Real world examples * [akka-camel](http://doc.akka.io/docs/akka/snapshot/scala/camel.html) +* [Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions](https://www.amazon.com/gp/product/0321200683/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321200683&linkCode=as2&tag=javadesignpat-20&linkId=122e0cff74eedd004cc81a3ecfa623cf) diff --git a/eip-publish-subscribe/README.md b/eip-publish-subscribe/README.md index 339885b34..f4df3135f 100644 --- a/eip-publish-subscribe/README.md +++ b/eip-publish-subscribe/README.md @@ -22,3 +22,4 @@ Use the Publish Subscribe Channel pattern when ## Credits * [J2EE Design Patterns](https://www.amazon.com/gp/product/0596004273/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596004273&linkCode=as2&tag=javadesignpat-20&linkId=48d37c67fb3d845b802fa9b619ad8f31) +* [Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions](https://www.amazon.com/gp/product/0321200683/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321200683&linkCode=as2&tag=javadesignpat-20&linkId=122e0cff74eedd004cc81a3ecfa623cf) diff --git a/eip-splitter/README.md b/eip-splitter/README.md index 648462229..d1206664f 100644 --- a/eip-splitter/README.md +++ b/eip-splitter/README.md @@ -28,3 +28,4 @@ Use the Splitter pattern when * [Gregor Hohpe, Bobby Woolf - Enterprise Integration Patterns](http://www.enterpriseintegrationpatterns.com/patterns/messaging/Sequencer.html) * [Apache Camel - Documentation](http://camel.apache.org/splitter.html) +* [Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions](https://www.amazon.com/gp/product/0321200683/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321200683&linkCode=as2&tag=javadesignpat-20&linkId=122e0cff74eedd004cc81a3ecfa623cf) diff --git a/eip-wire-tap/README.md b/eip-wire-tap/README.md index 83b43dfd1..b1fd80466 100644 --- a/eip-wire-tap/README.md +++ b/eip-wire-tap/README.md @@ -26,3 +26,4 @@ Use the Wire Tap pattern when * [Gregor Hohpe, Bobby Woolf - Enterprise Integration Patterns](http://www.enterpriseintegrationpatterns.com/patterns/messaging/WireTap.html) * [Apache Camel - Documentation](http://camel.apache.org/wire-tap.html) +* [Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions](https://www.amazon.com/gp/product/0321200683/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321200683&linkCode=as2&tag=javadesignpat-20&linkId=122e0cff74eedd004cc81a3ecfa623cf) From 4264f52d49230d2a912a51292840f8f9d30203b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Wed, 15 Jul 2020 11:03:23 +0300 Subject: [PATCH 029/211] #590 add explanation for Command pattern --- command/README.md | 211 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 208 insertions(+), 3 deletions(-) diff --git a/command/README.md b/command/README.md index a063b2db0..02a290e4d 100644 --- a/command/README.md +++ b/command/README.md @@ -12,9 +12,214 @@ tags: 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. +Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations. + +## Explanation +Real world example + +> There is a wizard casting spells on a goblin. The spells are executed on the goblin one by one. The first spell shrinks the goblin and the second makes him invisible. Then the wizard reverses the spells one by one. Each spell here is a command object that can be undone. + +In plain words + +> Storing requests as command objects allows performing an action or undoing it at a later time. + +Wikipedia says + +> In object-oriented programming, 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. + +**Programmatic Example** + +Here's the sample code with wizard and goblin. Let's start from the wizard class. + +```java +public class Wizard { + + private static final Logger LOGGER = LoggerFactory.getLogger(Wizard.class); + + private Deque undoStack = new LinkedList<>(); + private Deque redoStack = new LinkedList<>(); + + public Wizard() {} + + public void castSpell(Command command, Target target) { + LOGGER.info("{} casts {} at {}", this, command, target); + command.execute(target); + undoStack.offerLast(command); + } + + public void undoLastSpell() { + if (!undoStack.isEmpty()) { + var previousSpell = undoStack.pollLast(); + redoStack.offerLast(previousSpell); + LOGGER.info("{} undoes {}", this, previousSpell); + previousSpell.undo(); + } + } + + public void redoLastSpell() { + if (!redoStack.isEmpty()) { + var previousSpell = redoStack.pollLast(); + undoStack.offerLast(previousSpell); + LOGGER.info("{} redoes {}", this, previousSpell); + previousSpell.redo(); + } + } + + @Override + public String toString() { + return "Wizard"; + } +} +``` + +Next we present the spell hierarchy. + +```java +public abstract class Command { + + public abstract void execute(Target target); + + public abstract void undo(); + + public abstract void redo(); + + @Override + public abstract String toString(); +} + +public class InvisibilitySpell extends Command { + + private 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 redo() { + if (target != null) { + target.setVisibility(Visibility.INVISIBLE); + } + } + + @Override + public String toString() { + return "Invisibility spell"; + } +} + +public class ShrinkSpell extends Command { + + 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 undo() { + if (oldSize != null && target != null) { + var temp = target.getSize(); + target.setSize(oldSize); + oldSize = temp; + } + } + + @Override + public void redo() { + undo(); + } + + @Override + public String toString() { + return "Shrink spell"; + } +} +``` + +And last we have the goblin who's the target of the spells. + +```java +public abstract class Target { + + private static final Logger LOGGER = LoggerFactory.getLogger(Target.class); + + private Size size; + + private Visibility visibility; + + public Size getSize() { + return size; + } + + public void setSize(Size size) { + this.size = size; + } + + public Visibility getVisibility() { + return visibility; + } + + public void setVisibility(Visibility visibility) { + this.visibility = visibility; + } + + @Override + public abstract String toString(); + + public void printStatus() { + LOGGER.info("{}, [size={}] [visibility={}]", this, getSize(), getVisibility()); + } +} + +public class Goblin extends Target { + + public Goblin() { + setSize(Size.NORMAL); + setVisibility(Visibility.VISIBLE); + } + + @Override + public String toString() { + return "Goblin"; + } + +} +``` + +Finally here's the whole example in action. + +```java +var wizard = new Wizard(); +var goblin = new Goblin(); +goblin.printStatus(); +// Goblin, [size=normal] [visibility=visible] +wizard.castSpell(new ShrinkSpell(), goblin); +// Wizard casts Shrink spell at Goblin +goblin.printStatus(); +// Goblin, [size=small] [visibility=visible] +wizard.castSpell(new InvisibilitySpell(), goblin); +// Wizard casts Invisibility spell at Goblin +goblin.printStatus(); +// Goblin, [size=small] [visibility=invisible] +wizard.undoLastSpell(); +// Wizard undoes Invisibility spell +goblin.printStatus(); +// Goblin, [size=small] [visibility=visible] +``` ## Class diagram ![alt text](./etc/command.png "Command") From e98ad671e9a9e3e995f29c5986abe2d8513101e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Wed, 15 Jul 2020 20:06:58 +0300 Subject: [PATCH 030/211] #590 add explanation for Iterator pattern --- iterator/README.md | 99 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/iterator/README.md b/iterator/README.md index 0836c5970..7f06a64b9 100644 --- a/iterator/README.md +++ b/iterator/README.md @@ -15,6 +15,105 @@ Cursor Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation. +## Explanation + +Real world example + +> Treasure chest contains a set of magical items. There multiple types of items such as rings, potions and weapons. The items can be browsed by type using an iterator the treasure chest provides. + +In plain words + +> Containers can provide a representation agnostic iterator interface to provide access to the elements. + +Wikipedia says + +> In object-oriented programming, the iterator pattern is a design pattern in which an iterator is used to traverse a container and access the container's elements. + +**Programmatic Example** + +The main class in our example is the treasure chest that contains items. + +```java +public class TreasureChest { + + private List items; + + public TreasureChest() { + items = List.of( + new Item(ItemType.POTION, "Potion of courage"), + new Item(ItemType.RING, "Ring of shadows"), + new Item(ItemType.POTION, "Potion of wisdom"), + new Item(ItemType.POTION, "Potion of blood"), + new Item(ItemType.WEAPON, "Sword of silver +1"), + new Item(ItemType.POTION, "Potion of rust"), + new Item(ItemType.POTION, "Potion of healing"), + new Item(ItemType.RING, "Ring of armor"), + new Item(ItemType.WEAPON, "Steel halberd"), + new Item(ItemType.WEAPON, "Dagger of poison")); + } + + public Iterator iterator(ItemType itemType) { + return new TreasureChestItemIterator(this, itemType); + } + + public List getItems() { + return new ArrayList<>(items); + } +} + +public class Item { + + private ItemType type; + private String name; + + public Item(ItemType type, String name) { + this.setType(type); + this.name = name; + } + + @Override + public String toString() { + return name; + } + + public ItemType getType() { + return type; + } + + public final void setType(ItemType type) { + this.type = type; + } +} + +public enum ItemType { + + ANY, WEAPON, RING, POTION + +} +``` + +The iterator interface is extremely simple. + +```java +public interface Iterator { + + boolean hasNext(); + + T next(); +} +``` + +In the following example we iterate through the ring type items found in the chest. + +```java +var itemIterator = TREASURE_CHEST.iterator(ItemType.RING); +while (itemIterator.hasNext()) { + LOGGER.info(itemIterator.next().toString()); +} +// Ring of shadows +// Ring of armor +``` + ## Class diagram ![alt text](./etc/iterator_1.png "Iterator") From 68fa6f451b225f1d746acb312e59981943f71f5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Thu, 16 Jul 2020 20:46:00 +0300 Subject: [PATCH 031/211] #590 add explanation for Visitor --- visitor/README.md | 185 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 182 insertions(+), 3 deletions(-) diff --git a/visitor/README.md b/visitor/README.md index 3d5d0ee23..3b4be5082 100644 --- a/visitor/README.md +++ b/visitor/README.md @@ -9,9 +9,188 @@ tags: --- ## Intent -Represent an operation to be performed on the elements of an object -structure. Visitor lets you define a new operation without changing the classes -of the elements on which it operates. +Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates. + +## Explanation + +Real world example + +> Consider a tree structure with army units. Commander has two sergeants under it and each sergeant has three soldiers under them. Given that the hierarchy implements the visitor pattern, we can easily create new objects that interact with the commander, sergeants, soldiers or all of them. + +In plain words + +> Visitor pattern defines operations that can be performed on the nodes of the data structure. + +Wikipedia says + +> In object-oriented programming and software engineering, the visitor design pattern is a way of separating an algorithm from an object structure on which it operates. A practical result of this separation is the ability to add new operations to existing object structures without modifying the structures. + +**Programmatic Example** + +Given the army unit example from above, we first have the Unit and UnitVisitor base types. + +```java +public abstract class Unit { + + private Unit[] children; + + public Unit(Unit... children) { + this.children = children; + } + + public void accept(UnitVisitor visitor) { + Arrays.stream(children).forEach(child -> child.accept(visitor)); + } +} + +public interface UnitVisitor { + + void visitSoldier(Soldier soldier); + + void visitSergeant(Sergeant sergeant); + + void visitCommander(Commander commander); +} +``` + +Then we have the concrete units. + +```java +public class Commander extends Unit { + + public Commander(Unit... children) { + super(children); + } + + @Override + public void accept(UnitVisitor visitor) { + visitor.visitCommander(this); + super.accept(visitor); + } + + @Override + public String toString() { + return "commander"; + } +} + +public class Sergeant extends Unit { + + public Sergeant(Unit... children) { + super(children); + } + + @Override + public void accept(UnitVisitor visitor) { + visitor.visitSergeant(this); + super.accept(visitor); + } + + @Override + public String toString() { + return "sergeant"; + } +} + +public class Soldier extends Unit { + + public Soldier(Unit... children) { + super(children); + } + + @Override + public void accept(UnitVisitor visitor) { + visitor.visitSoldier(this); + super.accept(visitor); + } + + @Override + public String toString() { + return "soldier"; + } +} +``` + +And then some concrete visitors. + +```java +public class CommanderVisitor implements UnitVisitor { + + private static final Logger LOGGER = LoggerFactory.getLogger(CommanderVisitor.class); + + @Override + public void visitSoldier(Soldier soldier) { + // Do nothing + } + + @Override + public void visitSergeant(Sergeant sergeant) { + // Do nothing + } + + @Override + public void visitCommander(Commander commander) { + LOGGER.info("Good to see you {}", commander); + } +} + +public class SergeantVisitor implements UnitVisitor { + + private static final Logger LOGGER = LoggerFactory.getLogger(SergeantVisitor.class); + + @Override + public void visitSoldier(Soldier soldier) { + // Do nothing + } + + @Override + public void visitSergeant(Sergeant sergeant) { + LOGGER.info("Hello {}", sergeant); + } + + @Override + public void visitCommander(Commander commander) { + // Do nothing + } +} + +public class SoldierVisitor implements UnitVisitor { + + private static final Logger LOGGER = LoggerFactory.getLogger(SoldierVisitor.class); + + @Override + public void visitSoldier(Soldier soldier) { + LOGGER.info("Greetings {}", soldier); + } + + @Override + public void visitSergeant(Sergeant sergeant) { + // Do nothing + } + + @Override + public void visitCommander(Commander commander) { + // Do nothing + } +} +``` + +Finally we can show the power of visitors in action. + +```java +commander.accept(new SoldierVisitor()); +// Greetings soldier +// Greetings soldier +// Greetings soldier +// Greetings soldier +// Greetings soldier +// Greetings soldier +commander.accept(new SergeantVisitor()); +// Hello sergeant +// Hello sergeant +commander.accept(new CommanderVisitor()); +// Good to see you commander +``` ## Class diagram ![alt text](./etc/visitor_1.png "Visitor") From 76fb9aff8b44ae3da01a36b0b200691be0adc755 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sat, 18 Jul 2020 10:22:43 +0300 Subject: [PATCH 032/211] #590 add explanation for Dao --- dao/README.md | 294 +++++++++++++++++- .../main/java/com/iluwatar/dao/Customer.java | 2 +- 2 files changed, 293 insertions(+), 3 deletions(-) diff --git a/dao/README.md b/dao/README.md index 3fe1ec20e..4b65679c4 100644 --- a/dao/README.md +++ b/dao/README.md @@ -9,8 +9,298 @@ tags: --- ## Intent -Object provides an abstract interface to some type of database or -other persistence mechanism. +Object provides an abstract interface to some type of database or other persistence mechanism. + +## Explanation + +Real world example + +> There's a set of customers that need to be persisted to database. Additionally we need the whole set of CRUD (create/read/update/delete) operations so we can operate on customers easily. + +In plain words + +> DAO is an interface we provide over the base persistence mechanism. + +Wikipedia says + +> In computer software, a data access object (DAO) is a pattern that provides an abstract interface to some type of database or other persistence mechanism. + +**Programmatic Example** + +Walking through our customers example, here's the basic Customer entity. + +```java +public class Customer { + + private int id; + private String firstName; + private String lastName; + + public Customer(int id, String firstName, String lastName) { + this.id = id; + this.firstName = firstName; + this.lastName = lastName; + } + + public int getId() { + return id; + } + + public void setId(final int id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(final String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(final String lastName) { + this.lastName = lastName; + } + + @Override + public String toString() { + return "Customer{" + "id=" + getId() + ", firstName='" + getFirstName() + '\'' + ", lastName='" + + getLastName() + '\'' + '}'; + } + + @Override + public boolean equals(final Object that) { + var isEqual = false; + if (this == that) { + isEqual = true; + } else if (that != null && getClass() == that.getClass()) { + final var customer = (Customer) that; + if (getId() == customer.getId()) { + isEqual = true; + } + } + return isEqual; + } + + @Override + public int hashCode() { + return getId(); + } +} +``` + +Here's the DAO interface and two different implementations for it. InMemoryCustomerDao keeps a simple map of customers +in memory while DBCustomerDao is the real RDBMS implementation. + +```java +public interface CustomerDao { + + Stream getAll() throws Exception; + + Optional getById(int id) throws Exception; + + boolean add(Customer customer) throws Exception; + + boolean update(Customer customer) throws Exception; + + boolean delete(Customer customer) throws Exception; +} + +public class InMemoryCustomerDao implements CustomerDao { + + private Map idToCustomer = new HashMap<>(); + + @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; + } +} + +public class DbCustomerDao implements CustomerDao { + + private static final Logger LOGGER = LoggerFactory.getLogger(DbCustomerDao.class); + + private final DataSource dataSource; + + public DbCustomerDao(DataSource dataSource) { + this.dataSource = dataSource; + } + + @Override + public Stream getAll() throws Exception { + try { + var connection = getConnection(); + var statement = connection.prepareStatement("SELECT * FROM CUSTOMERS"); + var resultSet = statement.executeQuery(); + return StreamSupport.stream(new Spliterators.AbstractSpliterator(Long.MAX_VALUE, + Spliterator.ORDERED) { + + @Override + public boolean tryAdvance(Consumer action) { + try { + if (!resultSet.next()) { + return false; + } + action.accept(createCustomer(resultSet)); + return true; + } catch (SQLException e) { + throw new RuntimeException(e); + } + } + }, false).onClose(() -> mutedClose(connection, statement, resultSet)); + } catch (SQLException e) { + throw new CustomException(e.getMessage(), e); + } + } + + private Connection getConnection() throws SQLException { + return dataSource.getConnection(); + } + + private void mutedClose(Connection connection, PreparedStatement statement, ResultSet resultSet) { + try { + resultSet.close(); + statement.close(); + connection.close(); + } catch (SQLException e) { + LOGGER.info("Exception thrown " + e.getMessage()); + } + } + + private Customer createCustomer(ResultSet resultSet) throws SQLException { + return new Customer(resultSet.getInt("ID"), + resultSet.getString("FNAME"), + resultSet.getString("LNAME")); + } + + @Override + public Optional getById(int id) throws Exception { + + ResultSet resultSet = null; + + try (var connection = getConnection(); + var statement = connection.prepareStatement("SELECT * FROM CUSTOMERS WHERE ID = ?")) { + + statement.setInt(1, id); + resultSet = statement.executeQuery(); + if (resultSet.next()) { + return Optional.of(createCustomer(resultSet)); + } else { + return Optional.empty(); + } + } catch (SQLException ex) { + throw new CustomException(ex.getMessage(), ex); + } finally { + if (resultSet != null) { + resultSet.close(); + } + } + } + + @Override + public boolean add(Customer customer) throws Exception { + if (getById(customer.getId()).isPresent()) { + return false; + } + + try (var connection = getConnection(); + var 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 CustomException(ex.getMessage(), ex); + } + } + + @Override + public boolean update(Customer customer) throws Exception { + try (var connection = getConnection(); + var 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 CustomException(ex.getMessage(), ex); + } + } + + @Override + public boolean delete(Customer customer) throws Exception { + try (var connection = getConnection(); + var statement = connection.prepareStatement("DELETE FROM CUSTOMERS WHERE ID = ?")) { + statement.setInt(1, customer.getId()); + return statement.executeUpdate() > 0; + } catch (SQLException ex) { + throw new CustomException(ex.getMessage(), ex); + } + } +} +``` + +Finally here's how we use our DAO to manage customers. + +```java + final var dataSource = createDataSource(); + createSchema(dataSource); + final var customerDao = new DbCustomerDao(dataSource); + + addCustomers(customerDao); + log.info(ALL_CUSTOMERS); + try (var customerStream = customerDao.getAll()) { + customerStream.forEach((customer) -> log.info(customer.toString())); + } + log.info("customerDao.getCustomerById(2): " + customerDao.getById(2)); + final var customer = new Customer(4, "Dan", "Danson"); + customerDao.add(customer); + log.info(ALL_CUSTOMERS + customerDao.getAll()); + customer.setFirstName("Daniel"); + customer.setLastName("Danielson"); + customerDao.update(customer); + log.info(ALL_CUSTOMERS); + try (var customerStream = customerDao.getAll()) { + customerStream.forEach((cust) -> log.info(cust.toString())); + } + customerDao.delete(customer); + log.info(ALL_CUSTOMERS + customerDao.getAll()); + + deleteSchema(dataSource); +``` + ## Class diagram ![alt text](./etc/dao.png "Data Access Object") diff --git a/dao/src/main/java/com/iluwatar/dao/Customer.java b/dao/src/main/java/com/iluwatar/dao/Customer.java index 43649989b..2630c9252 100644 --- a/dao/src/main/java/com/iluwatar/dao/Customer.java +++ b/dao/src/main/java/com/iluwatar/dao/Customer.java @@ -35,7 +35,7 @@ public class Customer { /** * Creates an instance of customer. */ - public Customer(final int id, final String firstName, final String lastName) { + public Customer(int id, String firstName, String lastName) { this.id = id; this.firstName = firstName; this.lastName = lastName; From eeea3c7b1f37b8b2520acd6bc21fc0890161061d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sat, 18 Jul 2020 10:51:02 +0300 Subject: [PATCH 033/211] #590 add explanation for Object Pool --- object-pool/README.md | 98 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/object-pool/README.md b/object-pool/README.md index efbf692ae..a8a20638c 100644 --- a/object-pool/README.md +++ b/object-pool/README.md @@ -15,6 +15,104 @@ short periods of time it is advantageous to utilize the Object Pool pattern. The Object Pool provides a cache for instantiated objects tracking which ones are in use and which are available. +## Explanation + +Real world example + +> In our war game we need to use oliphaunts, massive and mythic beasts, but the problem is that they are extremely expensive to create. The solution is to create a pool of them, track which ones are in-use, and instead of disposing them re-use the instances. + +In plain words + +> Object Pool manages a set of instances instead of creating and destroying them on demand. + +Wikipedia says + +> The object pool pattern is a software creational design pattern that uses a set of initialized objects kept ready to use – a "pool" – rather than allocating and destroying them on demand. + +**Programmatic Example** + +Here's the basic Oliphaunt class. These are very expensive to create. + +```java +public class Oliphaunt { + + private static AtomicInteger counter = new AtomicInteger(0); + + private final int id; + + public Oliphaunt() { + id = counter.incrementAndGet(); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + public int getId() { + return id; + } + + @Override + public String toString() { + return String.format("Oliphaunt id=%d", id); + } +} +``` + +Next we present the Object Pool and more specifically Oliphaunt Pool. + +```java +public abstract class ObjectPool { + + private Set available = new HashSet<>(); + private Set inUse = new HashSet<>(); + + protected abstract T create(); + + public synchronized T checkOut() { + if (available.isEmpty()) { + available.add(create()); + } + var instance = available.iterator().next(); + available.remove(instance); + inUse.add(instance); + return instance; + } + + public synchronized void checkIn(T instance) { + inUse.remove(instance); + available.add(instance); + } + + @Override + public synchronized String toString() { + return String.format("Pool available=%d inUse=%d", available.size(), inUse.size()); + } +} + +public class OliphauntPool extends ObjectPool { + + @Override + protected Oliphaunt create() { + return new Oliphaunt(); + } +} +``` + +And finally here's how we utilize the pool. + +```java + var pool = new OliphauntPool(); + var oliphaunt1 = pool.checkOut(); + var oliphaunt2 = pool.checkOut(); + var oliphaunt3 = pool.checkOut(); + pool.checkIn(oliphaunt1); + pool.checkIn(oliphaunt2); + var oliphaunt4 = pool.checkOut(); + var oliphaunt5 = pool.checkOut(); +``` + ## Class diagram ![alt text](./etc/object-pool.png "Object Pool") From 5aacdecc6c8ce614086b8cefc8f97a45fe76799c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sat, 18 Jul 2020 11:25:49 +0300 Subject: [PATCH 034/211] #590 add explanation for Callback --- callback/README.md | 61 ++++++++++++++++++- .../com/iluwatar/callback/LambdasApp.java | 48 --------------- .../main/java/com/iluwatar/callback/Task.java | 2 +- 3 files changed, 59 insertions(+), 52 deletions(-) delete mode 100644 callback/src/main/java/com/iluwatar/callback/LambdasApp.java diff --git a/callback/README.md b/callback/README.md index 6942019f3..78766cc15 100644 --- a/callback/README.md +++ b/callback/README.md @@ -9,9 +9,64 @@ tags: --- ## 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. +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. + +## Explanation + +Real world example + +> We need to be notified after executing task has finished. We pass a callback method for the executor and wait for it to call back on us. + +In plain words + +> Callback is a method passed to the executor which will be called at defined moment. + +Wikipedia says + +> In computer programming, a callback, also known as a "call-after" function, is any executable code that is passed as an argument to other code; that other code is expected to call back (execute) the argument at a given time. + +**Programmatic Example** + +Callback is a simple interface with single method. + +```java +public interface Callback { + + void call(); +} +``` + +Next we define a task that will execute the callback after the task execution has finished. + +```java +public abstract class Task { + + final void executeWith(Callback callback) { + execute(); + Optional.ofNullable(callback).ifPresent(Callback::call); + } + + public abstract void execute(); +} + +public final class SimpleTask extends Task { + + private static final Logger LOGGER = getLogger(SimpleTask.class); + + @Override + public void execute() { + LOGGER.info("Perform some important activity and after call the callback method."); + } +} +``` + +Finally here's how we execute a task and receive a callback when it's finished. + +```java + var task = new SimpleTask(); + task.executeWith(() -> LOGGER.info("I'm done now.")); +``` ## Class diagram ![alt text](./etc/callback.png "Callback") diff --git a/callback/src/main/java/com/iluwatar/callback/LambdasApp.java b/callback/src/main/java/com/iluwatar/callback/LambdasApp.java deleted file mode 100644 index d433217ba..000000000 --- a/callback/src/main/java/com/iluwatar/callback/LambdasApp.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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.callback; - -import static org.slf4j.LoggerFactory.getLogger; - -import org.slf4j.Logger; - -/** - * This example generates the exact same output as {@link App} however the callback has been defined - * as a Lambdas expression. - */ -public final class LambdasApp { - - private static final Logger LOGGER = getLogger(LambdasApp.class); - - private LambdasApp() { - } - - /** - * Program entry point. - */ - public static void main(final String[] args) { - var task = new SimpleTask(); - task.executeWith(() -> LOGGER.info("I'm done now.")); - } -} diff --git a/callback/src/main/java/com/iluwatar/callback/Task.java b/callback/src/main/java/com/iluwatar/callback/Task.java index 5632dbc4f..f3e8e478a 100644 --- a/callback/src/main/java/com/iluwatar/callback/Task.java +++ b/callback/src/main/java/com/iluwatar/callback/Task.java @@ -33,7 +33,7 @@ public abstract class Task { /** * Execute with callback. */ - final void executeWith(final Callback callback) { + final void executeWith(Callback callback) { execute(); Optional.ofNullable(callback).ifPresent(Callback::call); } From 09cee8ffa7b50f51e39eb0c6d6a94aa037229ec6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sat, 18 Jul 2020 17:10:50 +0300 Subject: [PATCH 035/211] #590 add explanation for DTO --- data-transfer-object/README.md | 85 ++++++++++++++++++- .../etc/data-transfer-object.ucls | 2 +- data-transfer-object/pom.xml | 2 +- .../{CustomerClientApp.java => App.java} | 6 +- .../com/iluwatar/datatransfer/AppTest.java | 33 +++++++ 5 files changed, 121 insertions(+), 7 deletions(-) rename data-transfer-object/src/main/java/com/iluwatar/datatransfer/{CustomerClientApp.java => App.java} (93%) create mode 100644 data-transfer-object/src/test/java/com/iluwatar/datatransfer/AppTest.java diff --git a/data-transfer-object/README.md b/data-transfer-object/README.md index c32ecaff7..e9286ce03 100644 --- a/data-transfer-object/README.md +++ b/data-transfer-object/README.md @@ -9,8 +9,89 @@ tags: --- ## Intent -Pass data with multiple attributes in one shot from client to server, -to avoid multiple calls to remote server. +Pass data with multiple attributes in one shot from client to server, to avoid multiple calls to remote server. + +## Explanation + +Real world example + +> We need to fetch information about customers from remote database. Instead of querying the attributes one at a time, we use DTOs to transfer all the relevant attributes in a single shot. + +In plain words + +> Using DTO relevant information can be fetched with a single backend query. + +Wikipedia says + +> In the field of programming a data transfer object (DTO) is an object that carries data between processes. The +motivation for its use is that communication between processes is usually done resorting to remote interfaces +(e.g., web services), where each call is an expensive operation. Because the majority of the cost of each call is +related to the round-trip time between the client and the server, one way of reducing the number of calls is to use an +object (the DTO) that aggregates the data that would have been transferred by the several calls, but that is served by +one call only. + +**Programmatic Example** + +Let's first introduce our simple customer DTO class. + +```java +public class CustomerDto { + private final String id; + private final String firstName; + private final String lastName; + + public CustomerDto(String id, String firstName, String lastName) { + this.id = id; + this.firstName = firstName; + this.lastName = lastName; + } + + public String getId() { + return id; + } + + public String getFirstName() { + return firstName; + } + + public String getLastName() { + return lastName; + } +} +``` + +Customer resource class acts as the server for customer information. + +```java +public class CustomerResource { + private List customers; + + public CustomerResource(List customers) { + this.customers = customers; + } + + public List getAllCustomers() { + return customers; + } + + public void save(CustomerDto customer) { + customers.add(customer); + } + + public void delete(String customerId) { + customers.removeIf(customer -> customer.getId().equals(customerId)); + } +} +``` + +Now fetching customer information is easy since we have the DTOs. + +```java + var allCustomers = customerResource.getAllCustomers(); + allCustomers.forEach(customer -> LOGGER.info(customer.getFirstName())); + // Kelly + // Alfonso +``` ## Class diagram ![alt text](./etc/data-transfer-object.urm.png "data-transfer-object") diff --git a/data-transfer-object/etc/data-transfer-object.ucls b/data-transfer-object/etc/data-transfer-object.ucls index 15f777aad..66236f32d 100644 --- a/data-transfer-object/etc/data-transfer-object.ucls +++ b/data-transfer-object/etc/data-transfer-object.ucls @@ -1,7 +1,7 @@ - diff --git a/data-transfer-object/pom.xml b/data-transfer-object/pom.xml index 5889daba8..459b1ab1e 100644 --- a/data-transfer-object/pom.xml +++ b/data-transfer-object/pom.xml @@ -48,7 +48,7 @@ - com.iluwatar.datatransfer.CustomerClientApp + com.iluwatar.datatransfer.App diff --git a/data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerClientApp.java b/data-transfer-object/src/main/java/com/iluwatar/datatransfer/App.java similarity index 93% rename from data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerClientApp.java rename to data-transfer-object/src/main/java/com/iluwatar/datatransfer/App.java index ebc44dc57..b8630d4ea 100644 --- a/data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerClientApp.java +++ b/data-transfer-object/src/main/java/com/iluwatar/datatransfer/App.java @@ -32,15 +32,15 @@ import org.slf4j.LoggerFactory; * The Data Transfer Object pattern is a design pattern in which an data transfer object is used to * serve related information together to avoid multiple call for each piece of information. * - *

In this example, ({@link CustomerClientApp}) as as customer details consumer i.e. client to + *

In this example, ({@link App}) as as customer details consumer i.e. client to * request for customer details to server. * *

CustomerResource ({@link CustomerResource}) act as server to serve customer information. And * The CustomerDto ({@link CustomerDto} is data transfer object to share customer information. */ -public class CustomerClientApp { +public class App { - private static final Logger LOGGER = LoggerFactory.getLogger(CustomerClientApp.class); + private static final Logger LOGGER = LoggerFactory.getLogger(App.class); /** * Method as act client and request to server for details. diff --git a/data-transfer-object/src/test/java/com/iluwatar/datatransfer/AppTest.java b/data-transfer-object/src/test/java/com/iluwatar/datatransfer/AppTest.java new file mode 100644 index 000000000..3a58d0c54 --- /dev/null +++ b/data-transfer-object/src/test/java/com/iluwatar/datatransfer/AppTest.java @@ -0,0 +1,33 @@ +/* + * 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.datatransfer; + +import org.junit.jupiter.api.Test; + +public class AppTest { + @Test + public void test() throws Exception { + App.main(new String[]{}); + } +} From 61dfa50822f1ab6e21507f4affaa828418fc5ae9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sat, 18 Jul 2020 17:43:12 +0300 Subject: [PATCH 036/211] #590 add explanation for Execute Around --- execute-around/README.md | 54 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 50 insertions(+), 4 deletions(-) diff --git a/execute-around/README.md b/execute-around/README.md index 25cb09313..2873aef9b 100644 --- a/execute-around/README.md +++ b/execute-around/README.md @@ -9,10 +9,56 @@ tags: --- ## Intent -Execute Around idiom frees the user from certain actions that -should always be executed before and after the business method. A good example -of this is resource allocation and deallocation leaving the user to specify -only what to do with the resource. +Execute Around idiom frees the user from certain actions that should always be executed before and after the business +method. A good example of this is resource allocation and deallocation leaving the user to specify only what to do with +the resource. + +## Explanation + +Real world example + +> We need to provide a class that can be used to write text strings to files. To make it easy for the user we let our service class open and close the file automatically, the user only has to specify what is written into which file. + +In plain words + +> Execute Around idiom handles boilerplate code before and after business method. + +[Stack Overflow](https://stackoverflow.com/questions/341971/what-is-the-execute-around-idiom) says + +> Basically it's the pattern where you write a method to do things which are always required, e.g. resource allocation and clean-up, and make the caller pass in "what we want to do with the resource". + +**Programmatic Example** + +Let's introduce our file writer class. + +```java +@FunctionalInterface +public interface FileWriterAction { + + void writeFile(FileWriter writer) throws IOException; + +} + +public class SimpleFileWriter { + + public SimpleFileWriter(String filename, FileWriterAction action) throws IOException { + try (var writer = new FileWriter(filename)) { + action.writeFile(writer); + } + } +} +``` + +To utilize the file writer the following code is needed. + +```java + FileWriterAction writeHello = writer -> { + writer.write("Hello"); + writer.append(" "); + writer.append("there!"); + }; + new SimpleFileWriter("testfile.txt", writeHello); +``` ## Class diagram ![alt text](./etc/execute-around.png "Execute Around") From 9a81ddb7d8680c9bfb1e9cfbf4a9eeb8c976c939 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 19 Jul 2020 17:14:02 +0300 Subject: [PATCH 037/211] #590 add explanation for Observer --- observer/README.md | 146 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 143 insertions(+), 3 deletions(-) diff --git a/observer/README.md b/observer/README.md index 034a90e7d..5d76ab61f 100644 --- a/observer/README.md +++ b/observer/README.md @@ -13,9 +13,149 @@ tags: Dependents, Publish-Subscribe ## Intent -Define a one-to-many dependency between objects so that when one -object changes state, all its dependents are notified and updated -automatically. +Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified +and updated automatically. + +## Explanation + +Real world example + +> In a land far away lives the races of hobbits and orcs. Both of them are mostly outdoors so they closely follow the changes in weather. One could say that they are constantly observing the weather. + +In plain words + +> Register as an observer to receive state changes in the object. + +Wikipedia says + +> The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. + +**Programmatic Example** + +Let's first introduce the weather observer interface and our races, orcs and hobbits. + +```java +public interface WeatherObserver { + + void update(WeatherType currentWeather); +} + +public class Orcs implements WeatherObserver { + + private static final Logger LOGGER = LoggerFactory.getLogger(Orcs.class); + + @Override + public void update(WeatherType currentWeather) { + switch (currentWeather) { + case COLD: + LOGGER.info("The orcs are freezing cold."); + break; + case RAINY: + LOGGER.info("The orcs are dripping wet."); + break; + case SUNNY: + LOGGER.info("The sun hurts the orcs' eyes."); + break; + case WINDY: + LOGGER.info("The orc smell almost vanishes in the wind."); + break; + default: + break; + } + } +} + +public class Hobbits implements WeatherObserver { + + private static final Logger LOGGER = LoggerFactory.getLogger(Hobbits.class); + + @Override + public void update(WeatherType currentWeather) { + switch (currentWeather) { + case COLD: + LOGGER.info("The hobbits are shivering in the cold weather."); + break; + case RAINY: + LOGGER.info("The hobbits look for cover from the rain."); + break; + case SUNNY: + LOGGER.info("The happy hobbits bade in the warm sun."); + break; + case WINDY: + LOGGER.info("The hobbits hold their hats tightly in the windy weather."); + break; + default: + break; + } + } +} +``` + +Then here's the weather that is constantly changing. + +```java +public class Weather { + + private static final Logger LOGGER = LoggerFactory.getLogger(Weather.class); + + private WeatherType currentWeather; + private List observers; + + public Weather() { + observers = new ArrayList<>(); + currentWeather = WeatherType.SUNNY; + } + + public void addObserver(WeatherObserver obs) { + observers.add(obs); + } + + public void removeObserver(WeatherObserver obs) { + observers.remove(obs); + } + + /** + * Makes time pass for weather. + */ + public void timePasses() { + var enumValues = WeatherType.values(); + currentWeather = enumValues[(currentWeather.ordinal() + 1) % enumValues.length]; + LOGGER.info("The weather changed to {}.", currentWeather); + notifyObservers(); + } + + private void notifyObservers() { + for (var obs : observers) { + obs.update(currentWeather); + } + } +} +``` + +Here's the full example in action. + +```java + var weather = new Weather(); + weather.addObserver(new Orcs()); + weather.addObserver(new Hobbits()); + + weather.timePasses(); + // The weather changed to rainy. + // The orcs are dripping wet. + // The hobbits look for cover from the rain. + weather.timePasses(); + // The weather changed to windy. + // The orc smell almost vanishes in the wind. + // The hobbits hold their hats tightly in the windy weather. + weather.timePasses(); + // The weather changed to cold. + // The orcs are freezing cold. + // The hobbits are shivering in the cold weather. + weather.timePasses(); + // The weather changed to sunny. + //The sun hurts the orcs' eyes. + // The happy hobbits bade in the warm sun. +``` ## Class diagram ![alt text](./etc/observer.png "Observer") From d2724e8091d3d12b451dabfac2411eebf0df0fc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 19 Jul 2020 17:34:58 +0300 Subject: [PATCH 038/211] #590 add explanation for Strategy --- strategy/README.md | 103 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 100 insertions(+), 3 deletions(-) diff --git a/strategy/README.md b/strategy/README.md index c78753535..21ac1c94b 100644 --- a/strategy/README.md +++ b/strategy/README.md @@ -12,9 +12,106 @@ tags: Policy ## Intent -Define a family of algorithms, encapsulate each one, and make them -interchangeable. Strategy lets the algorithm vary independently from clients -that use it. +Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary +independently from clients that use it. + +## Explanation + +Real world example + +> Slaying dragons is a dangerous profession. With experience it becomes easier. Veteran dragonslayers have developed different fighting strategies against different types of dragons. + +In plain words + +> Strategy pattern allows choosing the best suited algorithm at runtime. + +Wikipedia says + +> In computer programming, the strategy pattern (also known as the policy pattern) is a behavioral software design pattern that enables selecting an algorithm at runtime. + +**Programmatic Example** + +Let's first introduce the dragon slaying strategy interface and its implementations. + +```java +@FunctionalInterface +public interface DragonSlayingStrategy { + + void execute(); +} + +public class MeleeStrategy implements DragonSlayingStrategy { + + private static final Logger LOGGER = LoggerFactory.getLogger(MeleeStrategy.class); + + @Override + public void execute() { + LOGGER.info("With your Excalibur you sever the dragon's head!"); + } +} + +public class ProjectileStrategy implements DragonSlayingStrategy { + + private static final Logger LOGGER = LoggerFactory.getLogger(ProjectileStrategy.class); + + @Override + public void execute() { + LOGGER.info("You shoot the dragon with the magical crossbow and it falls dead on the ground!"); + } +} + +public class SpellStrategy implements DragonSlayingStrategy { + + private static final Logger LOGGER = LoggerFactory.getLogger(SpellStrategy.class); + + @Override + public void execute() { + LOGGER.info("You cast the spell of disintegration and the dragon vaporizes in a pile of dust!"); + } +} +``` + +And here is the mighty dragonslayer who is able to pick his fighting strategy based on the opponent. + +```java +public class DragonSlayer { + + private DragonSlayingStrategy strategy; + + public DragonSlayer(DragonSlayingStrategy strategy) { + this.strategy = strategy; + } + + public void changeStrategy(DragonSlayingStrategy strategy) { + this.strategy = strategy; + } + + public void goToBattle() { + strategy.execute(); + } +} +``` + +Finally here's dragonslayer in action. + +```java + LOGGER.info("Green dragon spotted ahead!"); + var dragonSlayer = new DragonSlayer(new MeleeStrategy()); + dragonSlayer.goToBattle(); + LOGGER.info("Red dragon emerges."); + dragonSlayer.changeStrategy(new ProjectileStrategy()); + dragonSlayer.goToBattle(); + LOGGER.info("Black dragon lands before you."); + dragonSlayer.changeStrategy(new SpellStrategy()); + dragonSlayer.goToBattle(); + + // Green dragon spotted ahead! + // With your Excalibur you sever the dragon's head! + // Red dragon emerges. + // You shoot the dragon with the magical crossbow and it falls dead on the ground! + // Black dragon lands before you. + // You cast the spell of disintegration and the dragon vaporizes in a pile of dust! +``` ## Class diagram ![alt text](./etc/strategy_1.png "Strategy") From 4d95d38b8d3a2c1b7b9d60bbf338635ecfed4164 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 19 Jul 2020 19:37:40 +0300 Subject: [PATCH 039/211] #590 explanation for Multiton --- multiton/README.md | 84 ++++++++++++++++++++++++++++++++++++++++++++-- observer/README.md | 2 +- 2 files changed, 83 insertions(+), 3 deletions(-) diff --git a/multiton/README.md b/multiton/README.md index 4387cf7ac..ec1429a8f 100644 --- a/multiton/README.md +++ b/multiton/README.md @@ -12,8 +12,88 @@ tags: Registry ## Intent -Ensure a class only has limited number of instances, and provide a -global point of access to them. +Ensure a class only has limited number of instances and provide a global point of access to them. + +## Explanation + +Real world example + +> The Nazgûl, also called ringwraiths or the Nine Riders, are Sauron's most terrible servants. By definition there's always nine of them. + +In plain words + +> Multiton pattern ensures there's predefined amount of instances available globally. + +Wikipedia says + +> In software engineering, the multiton pattern is a design pattern which generalizes the singleton pattern. Whereas the singleton allows only one instance of a class to be created, the multiton pattern allows for the controlled creation of multiple instances, which it manages through the use of a map. + +**Programmatic Example** + +Nazgul is the multiton class. + +```java +public enum NazgulName { + + KHAMUL, MURAZOR, DWAR, JI_INDUR, AKHORAHIL, HOARMURATH, ADUNAPHEL, REN, UVATHA; +} + +public final class Nazgul { + + private static Map nazguls; + + private NazgulName name; + + static { + nazguls = new ConcurrentHashMap<>(); + nazguls.put(NazgulName.KHAMUL, new Nazgul(NazgulName.KHAMUL)); + nazguls.put(NazgulName.MURAZOR, new Nazgul(NazgulName.MURAZOR)); + nazguls.put(NazgulName.DWAR, new Nazgul(NazgulName.DWAR)); + nazguls.put(NazgulName.JI_INDUR, new Nazgul(NazgulName.JI_INDUR)); + nazguls.put(NazgulName.AKHORAHIL, new Nazgul(NazgulName.AKHORAHIL)); + nazguls.put(NazgulName.HOARMURATH, new Nazgul(NazgulName.HOARMURATH)); + nazguls.put(NazgulName.ADUNAPHEL, new Nazgul(NazgulName.ADUNAPHEL)); + nazguls.put(NazgulName.REN, new Nazgul(NazgulName.REN)); + nazguls.put(NazgulName.UVATHA, new Nazgul(NazgulName.UVATHA)); + } + + private Nazgul(NazgulName name) { + this.name = name; + } + + public static Nazgul getInstance(NazgulName name) { + return nazguls.get(name); + } + + public NazgulName getName() { + return name; + } +} +``` + +And here's how we access the Nazgul instances. + +```java + LOGGER.info("KHAMUL={}", Nazgul.getInstance(NazgulName.KHAMUL)); + LOGGER.info("MURAZOR={}", Nazgul.getInstance(NazgulName.MURAZOR)); + LOGGER.info("DWAR={}", Nazgul.getInstance(NazgulName.DWAR)); + LOGGER.info("JI_INDUR={}", Nazgul.getInstance(NazgulName.JI_INDUR)); + LOGGER.info("AKHORAHIL={}", Nazgul.getInstance(NazgulName.AKHORAHIL)); + LOGGER.info("HOARMURATH={}", Nazgul.getInstance(NazgulName.HOARMURATH)); + LOGGER.info("ADUNAPHEL={}", Nazgul.getInstance(NazgulName.ADUNAPHEL)); + LOGGER.info("REN={}", Nazgul.getInstance(NazgulName.REN)); + LOGGER.info("UVATHA={}", Nazgul.getInstance(NazgulName.UVATHA)); + + // KHAMUL=com.iluwatar.multiton.Nazgul@2b214b94 + // MURAZOR=com.iluwatar.multiton.Nazgul@17814b1c + // DWAR=com.iluwatar.multiton.Nazgul@7ac9af2a + // JI_INDUR=com.iluwatar.multiton.Nazgul@7bb004b8 + // AKHORAHIL=com.iluwatar.multiton.Nazgul@78e89bfe + // HOARMURATH=com.iluwatar.multiton.Nazgul@652ce654 + // ADUNAPHEL=com.iluwatar.multiton.Nazgul@522ba524 + // REN=com.iluwatar.multiton.Nazgul@29c5ee1d + // UVATHA=com.iluwatar.multiton.Nazgul@15cea7b0 +``` ## Class diagram ![alt text](./etc/multiton.png "Multiton") diff --git a/observer/README.md b/observer/README.md index 5d76ab61f..edc72ae24 100644 --- a/observer/README.md +++ b/observer/README.md @@ -153,7 +153,7 @@ Here's the full example in action. // The hobbits are shivering in the cold weather. weather.timePasses(); // The weather changed to sunny. - //The sun hurts the orcs' eyes. + // The sun hurts the orcs' eyes. // The happy hobbits bade in the warm sun. ``` From e34de39ae72f6e3a2ff0f1b2be743e4a4cb1831c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 19 Jul 2020 19:53:31 +0300 Subject: [PATCH 040/211] #590 explanation for Null Object --- null-object/README.md | 137 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) diff --git a/null-object/README.md b/null-object/README.md index 184e903a0..0fce86f0e 100644 --- a/null-object/README.md +++ b/null-object/README.md @@ -18,6 +18,143 @@ implements the expected interface, but whose method body is empty. The advantage of this approach over a working default implementation is that a Null Object is very predictable and has no side effects: it does nothing. +## Explanation + +Real world example + +> We are building a binary tree from nodes. There are ordinary nodes and "empty" nodes. Traversing the tree normally should not cause errors, so we use null object pattern where necessary. + +In plain words + +> Null Object pattern handles "empty" objects gracefully. + +Wikipedia says + +> In object-oriented computer programming, a null object is an object with no referenced value or with defined neutral ("null") behavior. The null object design pattern describes the uses of such objects and their behavior (or lack thereof). + +**Programmatic Example** + +Here's the definitions for node interface and its implementations. + +```java +public interface Node { + + String getName(); + + int getTreeSize(); + + Node getLeft(); + + Node getRight(); + + void walk(); +} + +public class NodeImpl implements Node { + + private static final Logger LOGGER = LoggerFactory.getLogger(NodeImpl.class); + + private final String name; + private final Node left; + private final Node right; + + /** + * Constructor. + */ + public NodeImpl(String name, Node left, Node right) { + this.name = name; + this.left = left; + this.right = right; + } + + @Override + public int getTreeSize() { + return 1 + left.getTreeSize() + right.getTreeSize(); + } + + @Override + public Node getLeft() { + return left; + } + + @Override + public Node getRight() { + return right; + } + + @Override + public String getName() { + return name; + } + + @Override + public void walk() { + LOGGER.info(name); + if (left.getTreeSize() > 0) { + left.walk(); + } + if (right.getTreeSize() > 0) { + right.walk(); + } + } +} + +public final class NullNode implements Node { + + private static NullNode instance = new NullNode(); + + private NullNode() { + } + + public static NullNode getInstance() { + return instance; + } + + @Override + public int getTreeSize() { + return 0; + } + + @Override + public Node getLeft() { + return null; + } + + @Override + public Node getRight() { + return null; + } + + @Override + public String getName() { + return null; + } + + @Override + public void walk() { + // Do nothing + } +} + +``` + +Then we can construct and traverse the binary tree without errors as follows. + +```java + Node root = + new NodeImpl("1", new NodeImpl("11", new NodeImpl("111", NullNode.getInstance(), + NullNode.getInstance()), NullNode.getInstance()), new NodeImpl("12", + NullNode.getInstance(), new NodeImpl("122", NullNode.getInstance(), + NullNode.getInstance()))); + root.walk(); + + // 1 + // 11 + // 111 + // 12 + // 122 +``` + ## Class diagram ![alt text](./etc/null-object.png "Null Object") From a18c0f76ea07ca5fb4f7dc94e3a6b2537919ca02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 19 Jul 2020 20:23:12 +0300 Subject: [PATCH 041/211] #590 add explanation for Poison Pill --- poison-pill/README.md | 246 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 244 insertions(+), 2 deletions(-) diff --git a/poison-pill/README.md b/poison-pill/README.md index 7fd152891..823bb7df8 100644 --- a/poison-pill/README.md +++ b/poison-pill/README.md @@ -10,8 +10,250 @@ tags: --- ## Intent -Poison Pill is known predefined data item that allows to provide -graceful shutdown for separate distributed consumption process. +Poison Pill is known predefined data item that allows to provide graceful shutdown for separate distributed consumption +process. + +## Explanation + +Real world example + +> Let's think about a message queue with one producer and one consumer. The producer keeps pushing new messages in the queue and the consumer keeps reading them. Finally when it's time to gracefully shut down the producer sends the poison pill message. + +In plain words + +> Poison Pill is a known message structure that ends the message exchange. + +**Programmatic Example** + +Let's define the message structure first. + +```java +public interface Message { + + Message POISON_PILL = new Message() { + + @Override + public void addHeader(Headers header, String value) { + throw poison(); + } + + @Override + public String getHeader(Headers header) { + throw poison(); + } + + @Override + public Map getHeaders() { + throw poison(); + } + + @Override + public void setBody(String body) { + throw poison(); + } + + @Override + public String getBody() { + throw poison(); + } + + private RuntimeException poison() { + return new UnsupportedOperationException("Poison"); + } + + }; + + enum Headers { + DATE, SENDER + } + + void addHeader(Headers header, String value); + + String getHeader(Headers header); + + Map getHeaders(); + + void setBody(String body); + + String getBody(); +} + +public class SimpleMessage implements Message { + + private Map headers = new HashMap<>(); + private String body; + + @Override + public void addHeader(Headers header, String value) { + headers.put(header, value); + } + + @Override + public String getHeader(Headers header) { + return headers.get(header); + } + + @Override + public Map getHeaders() { + return Collections.unmodifiableMap(headers); + } + + @Override + public void setBody(String body) { + this.body = body; + } + + @Override + public String getBody() { + return body; + } +} +``` + +Next we define the types related to the message queue. + +```java +public interface MqPublishPoint { + + void put(Message msg) throws InterruptedException; +} + +public interface MqSubscribePoint { + + Message take() throws InterruptedException; +} + +public interface MessageQueue extends MqPublishPoint, MqSubscribePoint { +} + +public class SimpleMessageQueue implements MessageQueue { + + private final BlockingQueue queue; + + public SimpleMessageQueue(int bound) { + queue = new ArrayBlockingQueue<>(bound); + } + + @Override + public void put(Message msg) throws InterruptedException { + queue.put(msg); + } + + @Override + public Message take() throws InterruptedException { + return queue.take(); + } +} +``` + +Now we need to create the message producer and consumer. + +```java +public class Producer { + + private static final Logger LOGGER = LoggerFactory.getLogger(Producer.class); + + private final MqPublishPoint queue; + private final String name; + private boolean isStopped; + + /** + * Constructor. + */ + public Producer(String name, MqPublishPoint queue) { + this.name = name; + this.queue = queue; + this.isStopped = false; + } + + /** + * Send message to queue. + */ + public void send(String body) { + if (isStopped) { + throw new IllegalStateException(String.format( + "Producer %s was stopped and fail to deliver requested message [%s].", body, name)); + } + var msg = new SimpleMessage(); + msg.addHeader(Headers.DATE, new Date().toString()); + msg.addHeader(Headers.SENDER, name); + msg.setBody(body); + + try { + queue.put(msg); + } catch (InterruptedException e) { + // allow thread to exit + LOGGER.error("Exception caught.", e); + } + } + + /** + * Stop system by sending poison pill. + */ + public void stop() { + isStopped = true; + try { + queue.put(Message.POISON_PILL); + } catch (InterruptedException e) { + // allow thread to exit + LOGGER.error("Exception caught.", e); + } + } +} + +public class Consumer { + + private static final Logger LOGGER = LoggerFactory.getLogger(Consumer.class); + + private final MqSubscribePoint queue; + private final String name; + + public Consumer(String name, MqSubscribePoint queue) { + this.name = name; + this.queue = queue; + } + + /** + * Consume message. + */ + public void consume() { + while (true) { + try { + var msg = queue.take(); + if (Message.POISON_PILL.equals(msg)) { + LOGGER.info("Consumer {} receive request to terminate.", name); + break; + } + var sender = msg.getHeader(Headers.SENDER); + var body = msg.getBody(); + LOGGER.info("Message [{}] from [{}] received by [{}]", body, sender, name); + } catch (InterruptedException e) { + // allow thread to exit + LOGGER.error("Exception caught.", e); + return; + } + } + } +} +``` + +Finally we are ready to present the whole example in action. + +```java + var queue = new SimpleMessageQueue(10000); + + final var producer = new Producer("PRODUCER_1", queue); + final var consumer = new Consumer("CONSUMER_1", queue); + + new Thread(consumer::consume).start(); + + new Thread(() -> { + producer.send("hand shake"); + producer.send("some very important information"); + producer.send("bye!"); + producer.stop(); + }).start(); +``` ## Class diagram ![alt text](./etc/poison-pill.png "Poison Pill") From 467f647ca266306d72f35749c661d0867efd1dfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Mon, 20 Jul 2020 17:31:58 +0300 Subject: [PATCH 042/211] #590 add explanation for Repository --- repository/README.md | 236 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 231 insertions(+), 5 deletions(-) diff --git a/repository/README.md b/repository/README.md index 7b5258ea5..09a9a2bba 100644 --- a/repository/README.md +++ b/repository/README.md @@ -9,11 +9,236 @@ tags: --- ## Intent -Repository layer is added between the domain and data mapping -layers to isolate domain objects from details of the database access code and -to minimize scattering and duplication of query code. The Repository pattern is -especially useful in systems where number of domain classes is large or heavy -querying is utilized. +Repository layer is added between the domain and data mapping layers to isolate domain objects from details of the +database access code and to minimize scattering and duplication of query code. The Repository pattern is especially +useful in systems where number of domain classes is large or heavy querying is utilized. + +## Explanation +Real world example + +> Let's say we need a persistent data store for persons. Adding new persons and searching for them according to different criteria must be easy. + +In plain words + +> Repository architectural pattern creates a uniform layer of data repositories that can be used for CRUD operations. + +[Microsoft documentation](https://docs.microsoft.com/en-us/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/infrastructure-persistence-layer-design) says + +> Repositories are classes or components that encapsulate the logic required to access data sources. They centralize common data access functionality, providing better maintainability and decoupling the infrastructure or technology used to access databases from the domain model layer. + +**Programmatic Example** + +Let's first look at the person class that we need to persist. + +```java +@Entity +public class Person { + + @Id + @GeneratedValue + private Long id; + private String name; + private String surname; + + private int age; + + public Person() { + } + + /** + * Constructor. + */ + public Person(String name, String surname, int age) { + this.name = name; + this.surname = surname; + this.age = age; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getSurname() { + return surname; + } + + public void setSurname(String surname) { + this.surname = surname; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + @Override + public String toString() { + return "Person [id=" + id + ", name=" + name + ", surname=" + surname + ", age=" + age + "]"; + } + + @Override + public int hashCode() { + final var prime = 31; + var result = 1; + result = prime * result + age; + result = prime * result + (id == null ? 0 : id.hashCode()); + result = prime * result + (name == null ? 0 : name.hashCode()); + result = prime * result + (surname == null ? 0 : surname.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + var other = (Person) obj; + if (age != other.age) { + return false; + } + if (id == null) { + if (other.id != null) { + return false; + } + } else if (!id.equals(other.id)) { + return false; + } + if (name == null) { + if (other.name != null) { + return false; + } + } else if (!name.equals(other.name)) { + return false; + } + if (surname == null) { + return other.surname == null; + } + return surname.equals(other.surname); + } +} +``` + +We are using Spring Data to create the repository so it becomes really simple. + +```java +@Repository +public interface PersonRepository + extends CrudRepository, JpaSpecificationExecutor { + + Person findByName(String name); +} +``` + +Additionally we define a helper class for specification queries. + +```java +public class PersonSpecifications { + + public static class AgeBetweenSpec implements Specification { + + private int from; + + private int to; + + public AgeBetweenSpec(int from, int to) { + this.from = from; + this.to = to; + } + + @Override + public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder cb) { + return cb.between(root.get("age"), from, to); + } + + } + + public static class NameEqualSpec implements Specification { + + public String name; + + public NameEqualSpec(String name) { + this.name = name; + } + + public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder cb) { + return cb.equal(root.get("name"), this.name); + } + } + +} +``` + +And here's the repository in action. + +```java + var peter = new Person("Peter", "Sagan", 17); + var nasta = new Person("Nasta", "Kuzminova", 25); + var john = new Person("John", "lawrence", 35); + var terry = new Person("Terry", "Law", 36); + + repository.save(peter); + repository.save(nasta); + repository.save(john); + repository.save(terry); + + LOGGER.info("Count Person records: {}", repository.count()); + + var persons = (List) repository.findAll(); + persons.stream().map(Person::toString).forEach(LOGGER::info); + + nasta.setName("Barbora"); + nasta.setSurname("Spotakova"); + repository.save(nasta); + + repository.findById(2L).ifPresent(p -> LOGGER.info("Find by id 2: {}", p)); + repository.deleteById(2L); + + LOGGER.info("Count Person records: {}", repository.count()); + + repository + .findOne(new PersonSpecifications.NameEqualSpec("John")) + .ifPresent(p -> LOGGER.info("Find by John is {}", p)); + + persons = repository.findAll(new PersonSpecifications.AgeBetweenSpec(20, 40)); + + LOGGER.info("Find Person with age between 20,40: "); + persons.stream().map(Person::toString).forEach(LOGGER::info); + + repository.deleteAll(); + + // Count Person records: 4 + // Person [id=1, name=Peter, surname=Sagan, age=17] + // Person [id=2, name=Nasta, surname=Kuzminova, age=25] + // Person [id=3, name=John, surname=lawrence, age=35] + // Person [id=4, name=Terry, surname=Law, age=36] + // Find by id 2: Person [id=2, name=Barbora, surname=Spotakova, age=25] + // Count Person records: 3 + // Find by John is Person [id=3, name=John, surname=lawrence, age=35] + // Find Person with age between 20,40: + // Person [id=3, name=John, surname=lawrence, age=35] + // Person [id=4, name=Terry, surname=Law, age=36] +``` ## Class diagram ![alt text](./etc/repository.png "Repository") @@ -36,3 +261,4 @@ Use the Repository pattern when * [Advanced Spring Data JPA - Specifications and Querydsl](https://spring.io/blog/2011/04/26/advanced-spring-data-jpa-specifications-and-querydsl/) * [Repository Pattern Benefits and Spring Implementation](https://stackoverflow.com/questions/40068965/repository-pattern-benefits-and-spring-implementation) * [Patterns of Enterprise Application Architecture](https://www.amazon.com/gp/product/0321127420/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321127420&linkCode=as2&tag=javadesignpat-20&linkId=d9f7d37b032ca6e96253562d075fcc4a) +* [Design patterns that I often avoid: Repository pattern](https://www.infoworld.com/article/3117713/design-patterns-that-i-often-avoid-repository-pattern.html) From b907a2a9bc41be02e5f375c5bf06055940cdcb60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Mon, 20 Jul 2020 17:52:44 +0300 Subject: [PATCH 043/211] #590 add explanation for Memento --- memento/README.md | 173 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 171 insertions(+), 2 deletions(-) diff --git a/memento/README.md b/memento/README.md index 1bf6e442b..8011dfc49 100644 --- a/memento/README.md +++ b/memento/README.md @@ -12,8 +12,177 @@ tags: Token ## Intent -Without violating encapsulation, capture and externalize an -object's internal state so that the object can be restored to this state later. +Without violating encapsulation, capture and externalize an object's internal state so that the object can be restored +to this state later. + +## Explanation +Real world example + +> We are working on astrology application where we need to analyze star properties over time. We are creating snapshots of star state using Memento pattern. + +In plain words + +> Memento pattern captures object internal state making it easy to store and restore objects in any point of time. + +Wikipedia says + +> The memento pattern is a software design pattern that provides the ability to restore an object to its previous state (undo via rollback). + +**Programmatic Example** + +Let's first define the types of stars we are capable to handle. + +```java +public enum StarType { + + SUN("sun"), RED_GIANT("red giant"), WHITE_DWARF("white dwarf"), SUPERNOVA("supernova"), DEAD( + "dead star"), UNDEFINED(""); + + private String title; + + StarType(String title) { + this.title = title; + } + + @Override + public String toString() { + return title; + } +} +``` + +Next let's jump straight to the essentials. Here's the star class along with the mementos that we need manipulate. + +```java +public interface StarMemento { +} + +public class Star { + + private StarType type; + private int ageYears; + private int massTons; + + public Star(StarType startType, int startAge, int startMass) { + this.type = startType; + this.ageYears = startAge; + this.massTons = startMass; + } + + public void timePasses() { + ageYears *= 2; + massTons *= 8; + switch (type) { + case RED_GIANT: + type = StarType.WHITE_DWARF; + break; + case SUN: + type = StarType.RED_GIANT; + break; + case SUPERNOVA: + type = StarType.DEAD; + break; + case WHITE_DWARF: + type = StarType.SUPERNOVA; + break; + case DEAD: + ageYears *= 2; + massTons = 0; + break; + default: + break; + } + } + + StarMemento getMemento() { + + StarMementoInternal state = new StarMementoInternal(); + state.setAgeYears(ageYears); + state.setMassTons(massTons); + state.setType(type); + return state; + } + + void setMemento(StarMemento memento) { + + StarMementoInternal state = (StarMementoInternal) memento; + this.type = state.getType(); + this.ageYears = state.getAgeYears(); + this.massTons = state.getMassTons(); + } + + @Override + public String toString() { + return String.format("%s age: %d years mass: %d tons", type.toString(), ageYears, massTons); + } + + private static class StarMementoInternal implements StarMemento { + + private StarType type; + private int ageYears; + private int massTons; + + public StarType getType() { + return type; + } + + public void setType(StarType type) { + this.type = type; + } + + public int getAgeYears() { + return ageYears; + } + + public void setAgeYears(int ageYears) { + this.ageYears = ageYears; + } + + public int getMassTons() { + return massTons; + } + + public void setMassTons(int massTons) { + this.massTons = massTons; + } + } +} +``` + +And finally here's how we use the mementos to store and restore star states. + +```java + Stack states = new Stack<>(); + Star star = new Star(StarType.SUN, 10000000, 500000); + LOGGER.info(star.toString()); + states.add(star.getMemento()); + star.timePasses(); + LOGGER.info(star.toString()); + states.add(star.getMemento()); + star.timePasses(); + LOGGER.info(star.toString()); + states.add(star.getMemento()); + star.timePasses(); + LOGGER.info(star.toString()); + states.add(star.getMemento()); + star.timePasses(); + LOGGER.info(star.toString()); + while (states.size() > 0) { + star.setMemento(states.pop()); + LOGGER.info(star.toString()); + } + + // sun age: 10000000 years mass: 500000 tons + // red giant age: 20000000 years mass: 4000000 tons + // white dwarf age: 40000000 years mass: 32000000 tons + // supernova age: 80000000 years mass: 256000000 tons + // dead star age: 160000000 years mass: 2048000000 tons + // supernova age: 80000000 years mass: 256000000 tons + // white dwarf age: 40000000 years mass: 32000000 tons + // red giant age: 20000000 years mass: 4000000 tons + // sun age: 10000000 years mass: 500000 tons +``` + ## Class diagram ![alt text](./etc/memento.png "Memento") From ab4e53a468fe1de6dc0ad731e2308ad80d37465c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Mon, 20 Jul 2020 20:06:39 +0300 Subject: [PATCH 044/211] #590 add explanation for State --- state/README.md | 122 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 120 insertions(+), 2 deletions(-) diff --git a/state/README.md b/state/README.md index 4f61d3025..7be4d3351 100644 --- a/state/README.md +++ b/state/README.md @@ -12,8 +12,126 @@ tags: Objects for States ## Intent -Allow an object to alter its behavior when its internal state -changes. The object will appear to change its class. +Allow an object to alter its behavior when its internal state changes. The object will appear to change its class. + +## Explanation +Real world example + +> When observing a mammoth in its natural habitat it seems to change its behavior based on the situation. It may first appear calm but over time when it detects a threat it gets angry and dangerous to its surroundings. + +In plain words + +> State pattern allows an object to change its behavior. + +Wikipedia says + +> The state pattern is a behavioral software design pattern that allows an object to alter its behavior when its internal state changes. This pattern is close to the concept of finite-state machines. The state pattern can be interpreted as a strategy pattern, which is able to switch a strategy through invocations of methods defined in the pattern's interface. + +**Programmatic Example** + +Here is the state interface and its concrete implementations. + +```java +public interface State { + + void onEnterState(); + + void observe(); +} + +public class PeacefulState implements State { + + private static final Logger LOGGER = LoggerFactory.getLogger(PeacefulState.class); + + private Mammoth mammoth; + + public PeacefulState(Mammoth mammoth) { + this.mammoth = mammoth; + } + + @Override + public void observe() { + LOGGER.info("{} is calm and peaceful.", mammoth); + } + + @Override + public void onEnterState() { + LOGGER.info("{} calms down.", mammoth); + } +} + +public class AngryState implements State { + + private static final Logger LOGGER = LoggerFactory.getLogger(AngryState.class); + + private Mammoth mammoth; + + public AngryState(Mammoth mammoth) { + this.mammoth = mammoth; + } + + @Override + public void observe() { + LOGGER.info("{} is furious!", mammoth); + } + + @Override + public void onEnterState() { + LOGGER.info("{} gets angry!", mammoth); + } +} +``` + +And here is the mammoth containing the state. + +```java +public class Mammoth { + + private State state; + + public Mammoth() { + state = new PeacefulState(this); + } + + public void timePasses() { + if (state.getClass().equals(PeacefulState.class)) { + changeStateTo(new AngryState(this)); + } else { + changeStateTo(new PeacefulState(this)); + } + } + + private void changeStateTo(State newState) { + this.state = newState; + this.state.onEnterState(); + } + + @Override + public String toString() { + return "The mammoth"; + } + + public void observe() { + this.state.observe(); + } +} +``` + +And here is the full example how the mammoth behaves over time. + +```java + var mammoth = new Mammoth(); + mammoth.observe(); + mammoth.timePasses(); + mammoth.observe(); + mammoth.timePasses(); + mammoth.observe(); + + // The mammoth gets angry! + // The mammoth is furious! + // The mammoth calms down. + // The mammoth is calm and peaceful. +``` ## Class diagram ![alt text](./etc/state_1.png "State") From 172964e75c1c299e19b38b9058db77aabcd5f1e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Mon, 20 Jul 2020 20:23:39 +0300 Subject: [PATCH 045/211] #590 explanation for Template Method --- template-method/README.md | 112 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 108 insertions(+), 4 deletions(-) diff --git a/template-method/README.md b/template-method/README.md index e87cfd6de..695644488 100644 --- a/template-method/README.md +++ b/template-method/README.md @@ -9,11 +9,115 @@ tags: --- ## Intent -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. +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`. +## Explanation +Real world example + +> The general steps in stealing an item are the same. First you pick the target, next you confuse him somehow and finally you steal the item. However there are many ways to implement these steps. + +In plain words + +> Template Method pattern outlines the general steps in the parent class and lets the concrete child implementations define the details. + +Wikipedia says + +> In object-oriented programming, the template method is one of the behavioral design patterns identified by Gamma et al. in the book Design Patterns. The template method is a method in a superclass, usually an abstract superclass, and defines the skeleton of an operation in terms of a number of high-level steps. These steps are themselves implemented by additional helper methods in the same class as the template method. + +**Programmatic Example** + +Let's first introduce the template method class along with its concrete implementations. + +```java +public abstract class StealingMethod { + + private static final Logger LOGGER = LoggerFactory.getLogger(StealingMethod.class); + + protected abstract String pickTarget(); + + protected abstract void confuseTarget(String target); + + protected abstract void stealTheItem(String target); + + public void steal() { + var target = pickTarget(); + LOGGER.info("The target has been chosen as {}.", target); + confuseTarget(target); + stealTheItem(target); + } +} + +public class SubtleMethod extends StealingMethod { + + private static final Logger LOGGER = LoggerFactory.getLogger(SubtleMethod.class); + + @Override + protected String pickTarget() { + return "shop keeper"; + } + + @Override + protected void confuseTarget(String target) { + LOGGER.info("Approach the {} with tears running and hug him!", target); + } + + @Override + protected void stealTheItem(String target) { + LOGGER.info("While in close contact grab the {}'s wallet.", target); + } +} + +public class HitAndRunMethod extends StealingMethod { + + private static final Logger LOGGER = LoggerFactory.getLogger(HitAndRunMethod.class); + + @Override + protected String pickTarget() { + return "old goblin woman"; + } + + @Override + protected void confuseTarget(String target) { + LOGGER.info("Approach the {} from behind.", target); + } + + @Override + protected void stealTheItem(String target) { + LOGGER.info("Grab the handbag and run away fast!"); + } +} +``` + +Here's the halfling thief class containing the template method. + +```java +public class HalflingThief { + + private StealingMethod method; + + public HalflingThief(StealingMethod method) { + this.method = method; + } + + public void steal() { + method.steal(); + } + + public void changeMethod(StealingMethod method) { + this.method = method; + } +} +``` + +And finally we show how the halfling thief utilizes the different stealing methods. + +```java + var thief = new HalflingThief(new HitAndRunMethod()); + thief.steal(); + thief.changeMethod(new SubtleMethod()); + thief.steal(); +``` ## Class diagram ![alt text](./etc/template-method_1.png "Template Method") From 6c2114330396b579efedfec610362bf1a50014d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Tue, 21 Jul 2020 20:04:06 +0300 Subject: [PATCH 046/211] #590 add explanation for Dependency Injection --- dependency-injection/README.md | 89 +++++++++++++++++++++++++++++++--- 1 file changed, 81 insertions(+), 8 deletions(-) diff --git a/dependency-injection/README.md b/dependency-injection/README.md index 90edd4061..abf647b50 100644 --- a/dependency-injection/README.md +++ b/dependency-injection/README.md @@ -9,12 +9,78 @@ tags: --- ## 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 -behavior, which allows program designs to be loosely coupled and to follow the -inversion of control and single responsibility principles. +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 behavior, which allows program designs to be loosely coupled and +to follow the inversion of control and single responsibility principles. + +## Explanation +Real world example + +> The old wizard likes to fill his pipe and smoke tobacco once in a while. However, he doesn't want to depend on a single tobacco brand only but likes to be able to enjoy them all interchangeably. + +In plain words + +> Dependency Injection separates creation of client's dependencies from its own behavior. + +Wikipedia says + +> In software engineering, dependency injection is a technique in which an object receives other objects that it depends on. These other objects are called dependencies. + +**Programmatic Example** + +Let's first introduce the tobacco brands. + +```java +public abstract class Tobacco { + + private static final Logger LOGGER = LoggerFactory.getLogger(Tobacco.class); + + public void smoke(Wizard wizard) { + LOGGER.info("{} smoking {}", wizard.getClass().getSimpleName(), + this.getClass().getSimpleName()); + } +} + +public class SecondBreakfastTobacco extends Tobacco { +} + +public class RivendellTobacco extends Tobacco { +} + +public class OldTobyTobacco extends Tobacco { +} +``` + +Next here's the wizard class hierarchy. + +```java +public interface Wizard { + + void smoke(); +} + +public class AdvancedWizard implements Wizard { + + private Tobacco tobacco; + + public AdvancedWizard(Tobacco tobacco) { + this.tobacco = tobacco; + } + + @Override + public void smoke() { + tobacco.smoke(this); + } +} +``` + +And lastly we can show how easy it is to give the old wizard any brand of tobacco. + +```java + var advancedWizard = new AdvancedWizard(new SecondBreakfastTobacco()); + advancedWizard.smoke(); +``` ## Class diagram ![alt text](./etc/dependency-injection.png "Dependency Injection") @@ -22,5 +88,12 @@ inversion of control and single responsibility principles. ## 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 +* When you need to remove knowledge of concrete implementation from object +* To enable unit testing of classes in isolation using mock objects or stubs + +## Credits + +* [Dependency Injection Principles, Practices, and Patterns](https://www.amazon.com/gp/product/161729473X/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=161729473X&linkId=57079257a5c7d33755493802f3b884bd) +* [Clean Code: A Handbook of Agile Software Craftsmanship](https://www.amazon.com/gp/product/0132350882/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0132350882&linkCode=as2&tag=javadesignpat-20&linkId=2c390d89cc9e61c01b9e7005c7842871) +* [Java 9 Dependency Injection: Write loosely coupled code with Spring 5 and Guice](https://www.amazon.com/gp/product/1788296257/ref=as_li_tl?ie=UTF8&tag=javadesignpat-20&camp=1789&creative=9325&linkCode=as2&creativeASIN=1788296257&linkId=4e9137a3bf722a8b5b156cce1eec0fc1) +* [Google Guice Tutorial: Open source Java based dependency injection framework](https://www.amazon.com/gp/product/B083P7DZ8M/ref=as_li_tl?ie=UTF8&tag=javadesignpat-20&camp=1789&creative=9325&linkCode=as2&creativeASIN=B083P7DZ8M&linkId=04f0f902c877921e45215b624a124bfe) From 082d63a1b3186bc9dcd60fd2fa0b0f66d90dcf49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Tue, 21 Jul 2020 22:57:11 +0300 Subject: [PATCH 047/211] #590 add explanation for Tolerant Reader --- tolerant-reader/README.md | 188 +++++++++++++++++++++++++++++++++++++- 1 file changed, 184 insertions(+), 4 deletions(-) diff --git a/tolerant-reader/README.md b/tolerant-reader/README.md index c60e75707..a62e5f4cd 100644 --- a/tolerant-reader/README.md +++ b/tolerant-reader/README.md @@ -9,10 +9,189 @@ tags: --- ## Intent -Tolerant Reader is an integration pattern that helps creating -robust communication systems. The idea is to be as tolerant as possible when -reading data from another service. This way, when the communication schema -changes, the readers must not break. +Tolerant Reader is an integration pattern that helps creating robust communication systems. The idea is to be as +tolerant as possible when reading data from another service. This way, when the communication schema changes, the +readers must not break. + +## Explanation +Real world example + +> We are persisting rainbowfish objects to file and later on they need to be restored. What makes it problematic is that rainbowfish data structure is versioned and evolves over time. New version of rainbowfish needs to be able to restore old versions as well. + +In plain words + +> Tolerant Reader pattern is used to create robust communication mechanisms between services. + +[Robustness Principle](https://java-design-patterns.com/principles/#robustness-principle) says + +> Be conservative in what you do, be liberal in what you accept from others + +**Programmatic Example** + +Here's the versioned rainbowfish. Notice how the second version introduces additional properties. + +```java +public class RainbowFish implements Serializable { + + private static final long serialVersionUID = 1L; + + private String name; + private int age; + private int lengthMeters; + private int weightTons; + + /** + * Constructor. + */ + public RainbowFish(String name, int age, int lengthMeters, int weightTons) { + this.name = name; + this.age = age; + this.lengthMeters = lengthMeters; + this.weightTons = weightTons; + } + + public String getName() { + return name; + } + + public int getAge() { + return age; + } + + public int getLengthMeters() { + return lengthMeters; + } + + public int getWeightTons() { + return weightTons; + } +} + +public class RainbowFishV2 extends RainbowFish { + + private static final long serialVersionUID = 1L; + + private boolean sleeping; + private boolean hungry; + private boolean angry; + + public RainbowFishV2(String name, int age, int lengthMeters, int weightTons) { + super(name, age, lengthMeters, weightTons); + } + + /** + * Constructor. + */ + public RainbowFishV2(String name, int age, int lengthMeters, int weightTons, boolean sleeping, + boolean hungry, boolean angry) { + this(name, age, lengthMeters, weightTons); + this.sleeping = sleeping; + this.hungry = hungry; + this.angry = angry; + } + + public boolean getSleeping() { + return sleeping; + } + + public boolean getHungry() { + return hungry; + } + + public boolean getAngry() { + return angry; + } +} +``` + +Next we introduce the rainbowfish serializer. This is the class that implements the Tolerant Reader pattern. + +```java +public final class RainbowFishSerializer { + + private RainbowFishSerializer() { + } + + public static void writeV1(RainbowFish rainbowFish, String filename) throws IOException { + var map = Map.of( + "name", rainbowFish.getName(), + "age", String.format("%d", rainbowFish.getAge()), + "lengthMeters", String.format("%d", rainbowFish.getLengthMeters()), + "weightTons", String.format("%d", rainbowFish.getWeightTons()) + ); + + try (var fileOut = new FileOutputStream(filename); + var objOut = new ObjectOutputStream(fileOut)) { + objOut.writeObject(map); + } + } + + public static void writeV2(RainbowFishV2 rainbowFish, String filename) throws IOException { + var map = Map.of( + "name", rainbowFish.getName(), + "age", String.format("%d", rainbowFish.getAge()), + "lengthMeters", String.format("%d", rainbowFish.getLengthMeters()), + "weightTons", String.format("%d", rainbowFish.getWeightTons()), + "angry", Boolean.toString(rainbowFish.getAngry()), + "hungry", Boolean.toString(rainbowFish.getHungry()), + "sleeping", Boolean.toString(rainbowFish.getSleeping()) + ); + + try (var fileOut = new FileOutputStream(filename); + var objOut = new ObjectOutputStream(fileOut)) { + objOut.writeObject(map); + } + } + + public static RainbowFish readV1(String filename) throws IOException, ClassNotFoundException { + Map map; + + try (var fileIn = new FileInputStream(filename); + var objIn = new ObjectInputStream(fileIn)) { + map = (Map) objIn.readObject(); + } + + return new RainbowFish( + map.get("name"), + Integer.parseInt(map.get("age")), + Integer.parseInt(map.get("lengthMeters")), + Integer.parseInt(map.get("weightTons")) + ); + } +} +``` + +And finally here's the full example in action. + +```java + var fishV1 = new RainbowFish("Zed", 10, 11, 12); + LOGGER.info("fishV1 name={} age={} length={} weight={}", fishV1.getName(), + fishV1.getAge(), fishV1.getLengthMeters(), fishV1.getWeightTons()); + RainbowFishSerializer.writeV1(fishV1, "fish1.out"); + + var deserializedRainbowFishV1 = RainbowFishSerializer.readV1("fish1.out"); + LOGGER.info("deserializedFishV1 name={} age={} length={} weight={}", + deserializedRainbowFishV1.getName(), deserializedRainbowFishV1.getAge(), + deserializedRainbowFishV1.getLengthMeters(), deserializedRainbowFishV1.getWeightTons()); + + var fishV2 = new RainbowFishV2("Scar", 5, 12, 15, true, true, true); + LOGGER.info( + "fishV2 name={} age={} length={} weight={} sleeping={} hungry={} angry={}", + fishV2.getName(), fishV2.getAge(), fishV2.getLengthMeters(), fishV2.getWeightTons(), + fishV2.getHungry(), fishV2.getAngry(), fishV2.getSleeping()); + RainbowFishSerializer.writeV2(fishV2, "fish2.out"); + + var deserializedFishV2 = RainbowFishSerializer.readV1("fish2.out"); + LOGGER.info("deserializedFishV2 name={} age={} length={} weight={}", + deserializedFishV2.getName(), deserializedFishV2.getAge(), + deserializedFishV2.getLengthMeters(), deserializedFishV2.getWeightTons()); + + // fishV1 name=Zed age=10 length=11 weight=12 + // deserializedFishV1 name=Zed age=10 length=11 weight=12 + // fishV2 name=Scar age=5 length=12 weight=15 sleeping=true hungry=true angry=true + // deserializedFishV2 name=Scar age=5 length=12 weight=15 +``` + ## Class diagram ![alt text](./etc/tolerant-reader.png "Tolerant Reader") @@ -25,3 +204,4 @@ Use the Tolerant Reader pattern when ## Credits * [Martin Fowler - Tolerant Reader](http://martinfowler.com/bliki/TolerantReader.html) +* [Service Design Patterns: Fundamental Design Solutions for SOAP/WSDL and RESTful Web Services](https://www.amazon.com/gp/product/032154420X/ref=as_li_tl?ie=UTF8&tag=javadesignpat-20&camp=1789&creative=9325&linkCode=as2&creativeASIN=032154420X&linkId=94f9516e747ac2b449a959d5b096c73c) From 8982392feaf0e65777fe615936345600ab238294 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Wed, 22 Jul 2020 20:31:56 +0300 Subject: [PATCH 048/211] #590 add explanation for Throttling --- throttling/README.md | 163 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) diff --git a/throttling/README.md b/throttling/README.md index 12090c5e3..f3ef43c17 100644 --- a/throttling/README.md +++ b/throttling/README.md @@ -11,6 +11,164 @@ tags: ## Intent Ensure that a given client is not able to access service resources more than the assigned limit. +## Explanation +Real world example + +> A large multinational corporation offers API to its customers. The API is rate-limited and each customer can only make certain amount of calls per second. + +In plain words + +> Throttling pattern is used to rate-limit access to a resource. + +[Microsoft documentation](https://docs.microsoft.com/en-us/azure/architecture/patterns/throttling) says + +> Control the consumption of resources used by an instance of an application, an individual tenant, or an entire service. This can allow the system to continue to function and meet service level agreements, even when an increase in demand places an extreme load on resources. + +**Programmatic Example** + +Tenant class presents the clients of the API. CallsCount tracks the number of API calls per tenant. + +```java +public class Tenant { + + private String name; + private int allowedCallsPerSecond; + + public Tenant(String name, int allowedCallsPerSecond, CallsCount callsCount) { + if (allowedCallsPerSecond < 0) { + throw new InvalidParameterException("Number of calls less than 0 not allowed"); + } + this.name = name; + this.allowedCallsPerSecond = allowedCallsPerSecond; + callsCount.addTenant(name); + } + + public String getName() { + return name; + } + + public int getAllowedCallsPerSecond() { + return allowedCallsPerSecond; + } +} + +public final class CallsCount { + + private static final Logger LOGGER = LoggerFactory.getLogger(CallsCount.class); + private Map tenantCallsCount = new ConcurrentHashMap<>(); + + public void addTenant(String tenantName) { + tenantCallsCount.putIfAbsent(tenantName, new AtomicLong(0)); + } + + public void incrementCount(String tenantName) { + tenantCallsCount.get(tenantName).incrementAndGet(); + } + + public long getCount(String tenantName) { + return tenantCallsCount.get(tenantName).get(); + } + + public void reset() { + LOGGER.debug("Resetting the map."); + tenantCallsCount.replaceAll((k, v) -> new AtomicLong(0)); + } +} +``` + +Next we introduce the service that the tenants are calling. To track the call count we use the throttler timer. + +```java +public interface Throttler { + + void start(); +} + +public class ThrottleTimerImpl implements Throttler { + + private final int throttlePeriod; + private final CallsCount callsCount; + + public ThrottleTimerImpl(int throttlePeriod, CallsCount callsCount) { + this.throttlePeriod = throttlePeriod; + this.callsCount = callsCount; + } + + @Override + public void start() { + new Timer(true).schedule(new TimerTask() { + @Override + public void run() { + callsCount.reset(); + } + }, 0, throttlePeriod); + } +} + +class B2BService { + + private static final Logger LOGGER = LoggerFactory.getLogger(B2BService.class); + private final CallsCount callsCount; + + public B2BService(Throttler timer, CallsCount callsCount) { + this.callsCount = callsCount; + timer.start(); + } + + public int dummyCustomerApi(Tenant tenant) { + var tenantName = tenant.getName(); + var count = callsCount.getCount(tenantName); + LOGGER.debug("Counter for {} : {} ", tenant.getName(), count); + if (count >= tenant.getAllowedCallsPerSecond()) { + LOGGER.error("API access per second limit reached for: {}", tenantName); + return -1; + } + callsCount.incrementCount(tenantName); + return getRandomCustomerId(); + } + + private int getRandomCustomerId() { + return ThreadLocalRandom.current().nextInt(1, 10000); + } +} +``` + +Now we are ready to see the full example in action. Tenant Adidas is rate-limited to 5 calls per second and Nike to 6. + +```java + public static void main(String[] args) { + var callsCount = new CallsCount(); + var adidas = new Tenant("Adidas", 5, callsCount); + var nike = new Tenant("Nike", 6, callsCount); + + var executorService = Executors.newFixedThreadPool(2); + executorService.execute(() -> makeServiceCalls(adidas, callsCount)); + executorService.execute(() -> makeServiceCalls(nike, callsCount)); + executorService.shutdown(); + + try { + executorService.awaitTermination(10, TimeUnit.SECONDS); + } catch (InterruptedException e) { + LOGGER.error("Executor Service terminated: {}", e.getMessage()); + } + } + + private static void makeServiceCalls(Tenant tenant, CallsCount callsCount) { + var timer = new ThrottleTimerImpl(10, callsCount); + var service = new B2BService(timer, callsCount); + // Sleep is introduced to keep the output in check and easy to view and analyze the results. + IntStream.range(0, 20).forEach(i -> { + service.dummyCustomerApi(tenant); + try { + Thread.sleep(1); + } catch (InterruptedException e) { + LOGGER.error("Thread interrupted: {}", e.getMessage()); + } + }); + } +``` + + ## Class diagram ![alt text](./etc/throttling-pattern.png "Throttling pattern class diagram") @@ -19,3 +177,8 @@ The Throttling pattern should be used: * When a service access needs to be restricted to not have high impacts on the performance of the service. * When multiple clients are consuming the same service resources and restriction has to be made according to the usage per client. + +## Credits + +* [Throttling pattern](https://docs.microsoft.com/en-us/azure/architecture/patterns/throttling) +* [Cloud Design Patterns: Prescriptive Architecture Guidance for Cloud Applications (Microsoft patterns & practices)](https://www.amazon.com/gp/product/B00ITGHBBS/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=B00ITGHBBS&linkId=12aacdd0cec04f372e7152689525631a) From 9db997d0aee466000b26c2cd56e2f19e0a6db8f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Wed, 22 Jul 2020 20:59:14 +0300 Subject: [PATCH 049/211] #590 add explanation for Thread Pool --- thread-pool/README.md | 145 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) diff --git a/thread-pool/README.md b/thread-pool/README.md index 0e125176d..62a2a3339 100644 --- a/thread-pool/README.md +++ b/thread-pool/README.md @@ -15,6 +15,146 @@ the system spend more time creating and destroying the threads than executing the actual tasks. Thread Pool solves this problem by reusing existing threads and eliminating the latency of creating new threads. +## Explanation +Real world example + +> We have a large number of relatively short tasks at hand. We need to peel huge amounts of potatoes and serve mighty amount of coffee cups. Creating a new thread for each task would be a waste so we establish a thread pool. + +In plain words + +> Thread Pool is a concurrency pattern where threads are allocated once and reused between tasks. + +Wikipedia says + +> In computer programming, a thread pool is a software design pattern for achieving concurrency of execution in a computer program. Often also called a replicated workers or worker-crew model, a thread pool maintains multiple threads waiting for tasks to be allocated for concurrent execution by the supervising program. By maintaining a pool of threads, the model increases performance and avoids latency in execution due to frequent creation and destruction of threads for short-lived tasks. The number of available threads is tuned to the computing resources available to the program, such as a parallel task queue after completion of execution. + +**Programmatic Example** + +Let's first look at our task hierarchy. We have a base class and then concrete CoffeeMakingTask and PotatoPeelingTask. + +```java +public abstract class Task { + + private static final AtomicInteger ID_GENERATOR = new AtomicInteger(); + + private final int id; + private final int timeMs; + + public Task(final int timeMs) { + this.id = ID_GENERATOR.incrementAndGet(); + this.timeMs = timeMs; + } + + public int getId() { + return id; + } + + public int getTimeMs() { + return timeMs; + } + + @Override + public String toString() { + return String.format("id=%d timeMs=%d", id, timeMs); + } +} + +public class CoffeeMakingTask extends Task { + + private static final int TIME_PER_CUP = 100; + + public CoffeeMakingTask(int numCups) { + super(numCups * TIME_PER_CUP); + } + + @Override + public String toString() { + return String.format("%s %s", this.getClass().getSimpleName(), super.toString()); + } +} + +public class PotatoPeelingTask extends Task { + + private static final int TIME_PER_POTATO = 200; + + public PotatoPeelingTask(int numPotatoes) { + super(numPotatoes * TIME_PER_POTATO); + } + + @Override + public String toString() { + return String.format("%s %s", this.getClass().getSimpleName(), super.toString()); + } +} +``` + +Next we present a runnable Worker class that the thread pool will utilize to handle all the potato peeling and coffee +making. + +```java +public class Worker implements Runnable { + + private static final Logger LOGGER = LoggerFactory.getLogger(Worker.class); + + private final Task task; + + public Worker(final Task task) { + this.task = task; + } + + @Override + public void run() { + LOGGER.info("{} processing {}", Thread.currentThread().getName(), task.toString()); + try { + Thread.sleep(task.getTimeMs()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} +``` + +Now we are ready to show the full example in action. + +```java + LOGGER.info("Program started"); + + // Create a list of tasks to be executed + var tasks = List.of( + new PotatoPeelingTask(3), + new PotatoPeelingTask(6), + new CoffeeMakingTask(2), + new CoffeeMakingTask(6), + new PotatoPeelingTask(4), + new CoffeeMakingTask(2), + new PotatoPeelingTask(4), + new CoffeeMakingTask(9), + new PotatoPeelingTask(3), + new CoffeeMakingTask(2), + new PotatoPeelingTask(4), + new CoffeeMakingTask(2), + new CoffeeMakingTask(7), + new PotatoPeelingTask(4), + new PotatoPeelingTask(5)); + + // Creates a thread pool that reuses a fixed number of threads operating off a shared + // unbounded queue. At any point, at most nThreads threads will be active processing + // tasks. If additional tasks are submitted when all threads are active, they will wait + // in the queue until a thread is available. + var executor = Executors.newFixedThreadPool(3); + + // Allocate new worker for each task + // The worker is executed when a thread becomes + // available in the thread pool + tasks.stream().map(Worker::new).forEach(executor::execute); + // All tasks were executed, now shutdown + executor.shutdown(); + while (!executor.isTerminated()) { + Thread.yield(); + } + LOGGER.info("Program finished"); +``` + ## Class diagram ![alt text](./etc/thread-pool.png "Thread Pool") @@ -22,3 +162,8 @@ and eliminating the latency of creating new threads. Use the Thread Pool pattern when * You have a large number of short-lived tasks to be executed in parallel + +## Credits + +* [Effective Java](https://www.amazon.com/gp/product/0134685997/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=0134685997&linkId=e1b9ddd5e669591642c4f30d40cd9f6b) +* [Java Concurrency in Practice](https://www.amazon.com/gp/product/0321349601/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=0321349601&linkId=fbedb3bad3c6cbead5afa56eea39ed59) From 1886a6f969b03dbc56c2bc9907b6e41a6c1cfdd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Wed, 22 Jul 2020 21:34:44 +0300 Subject: [PATCH 050/211] #590 add explanation for Game Loop --- game-loop/README.md | 216 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 205 insertions(+), 11 deletions(-) diff --git a/game-loop/README.md b/game-loop/README.md index f0a7eeebb..5f2cd9653 100644 --- a/game-loop/README.md +++ b/game-loop/README.md @@ -9,33 +9,227 @@ tags: --- ## Intent -A game loop runs continuously during gameplay. Each turn of the loop, it processes user input without blocking, updates the game state, and renders the game. It tracks the passage of time to control the rate of gameplay. +A game loop runs continuously during gameplay. Each turn of the loop, it processes user input without blocking, updates +the game state, and renders the game. It tracks the passage of time to control the rate of gameplay. -This pattern decouple the progression of game time from user input and processor speed. +This pattern decouples progression of game time from user input and processor speed. ## Applicability This pattern is used in every game engine. ## Explanation -Game loop is the main process of all the game rendering threads. It drives input process, internal status update, rendering, AI and all the other processes. +Real world example -There are a lot of implementations of game loop: +> Game loop is the main process of all the game rendering threads. It's present in all modern games. It drives input process, internal status update, rendering, AI and all the other processes. -- Frame-based game loop +In plain words -Frame-based game loop is the easiest implementation. The loop always keeps spinning for the following three processes: processInput, update and render. The problem with it is you have no control over how fast the game runs. On a fast machine, that loop will spin so fast users won’t be able to see what’s going on. On a slow machine, the game will crawl. If you have a part of the game that’s content-heavy or does more AI or physics, the game will actually play slower there. +> Game Loop pattern ensures that game time progresses in equal speed in all different hardware setups. -- Variable-step game loop +Wikipedia says -The variable-step game loop chooses a time step to advance based on how much real time passed since the last frame. The longer the frame takes, the bigger steps the game takes. It always keeps up with real time because it will take bigger and bigger steps to get there. +> The central component of any game, from a programming standpoint, is the game loop. The game loop allows the game to run smoothly regardless of a user's input or lack thereof. -- Fixed-step game loop +**Programmatic Example** -For fixed-step game loop, a certain amount of real time has elapsed since the last turn of the game loop. This is how much game time need to be simulated for the game’s “now” to catch up with the player’s. +Let's start with something simple. Here's a bullet that will move in our game. For demonstration it's enough that it has 1-dimensional position. + +```java +public class Bullet { + + private float position; + + public Bullet() { + position = 0.0f; + } + + public float getPosition() { + return position; + } + + public void setPosition(float position) { + this.position = position; + } +} +``` + +GameController is responsible for moving objects in the game. Including the aforementioned bullet. + +```java +public class GameController { + + protected final Bullet bullet; + + public GameController() { + bullet = new Bullet(); + } + + public void moveBullet(float offset) { + var currentPosition = bullet.getPosition(); + bullet.setPosition(currentPosition + offset); + } + + public float getBulletPosition() { + return bullet.getPosition(); + } +} +``` + +Now we introduce the game loop. Or actually in this demo we have 3 different game loops. + +```java +public enum GameStatus { + + RUNNING, STOPPED +} + +public abstract class GameLoop { + + protected final Logger logger = LoggerFactory.getLogger(this.getClass()); + + protected volatile GameStatus status; + + protected GameController controller; + + private Thread gameThread; + + public GameLoop() { + controller = new GameController(); + status = GameStatus.STOPPED; + } + + public void run() { + status = GameStatus.RUNNING; + gameThread = new Thread(() -> processGameLoop()); + gameThread.start(); + } + + public void stop() { + status = GameStatus.STOPPED; + } + + public boolean isGameRunning() { + return status == GameStatus.RUNNING; + } + + protected void processInput() { + try { + var lag = new Random().nextInt(200) + 50; + Thread.sleep(lag); + } catch (InterruptedException e) { + logger.error(e.getMessage()); + } + } + + protected void render() { + var position = controller.getBulletPosition(); + logger.info("Current bullet position: " + position); + } + + protected abstract void processGameLoop(); +} + +public class FrameBasedGameLoop extends GameLoop { + + @Override + protected void processGameLoop() { + while (isGameRunning()) { + processInput(); + update(); + render(); + } + } + + protected void update() { + controller.moveBullet(0.5f); + } +} + +public class VariableStepGameLoop extends GameLoop { + + @Override + protected void processGameLoop() { + var lastFrameTime = System.currentTimeMillis(); + while (isGameRunning()) { + processInput(); + var currentFrameTime = System.currentTimeMillis(); + var elapsedTime = currentFrameTime - lastFrameTime; + update(elapsedTime); + lastFrameTime = currentFrameTime; + render(); + } + } + + protected void update(Long elapsedTime) { + controller.moveBullet(0.5f * elapsedTime / 1000); + } +} + +public class FixedStepGameLoop extends GameLoop { + + private static final long MS_PER_FRAME = 20; + + @Override + protected void processGameLoop() { + var previousTime = System.currentTimeMillis(); + var lag = 0L; + while (isGameRunning()) { + var currentTime = System.currentTimeMillis(); + var elapsedTime = currentTime - previousTime; + previousTime = currentTime; + lag += elapsedTime; + + processInput(); + + while (lag >= MS_PER_FRAME) { + update(); + lag -= MS_PER_FRAME; + } + + render(); + } + } + + protected void update() { + controller.moveBullet(0.5f * MS_PER_FRAME / 1000); + } +} +``` + +Finally we can show all these game loops in action. + +```java + try { + LOGGER.info("Start frame-based game loop:"); + var frameBasedGameLoop = new FrameBasedGameLoop(); + frameBasedGameLoop.run(); + Thread.sleep(GAME_LOOP_DURATION_TIME); + frameBasedGameLoop.stop(); + LOGGER.info("Stop frame-based game loop."); + + LOGGER.info("Start variable-step game loop:"); + var variableStepGameLoop = new VariableStepGameLoop(); + variableStepGameLoop.run(); + Thread.sleep(GAME_LOOP_DURATION_TIME); + variableStepGameLoop.stop(); + LOGGER.info("Stop variable-step game loop."); + + LOGGER.info("Start fixed-step game loop:"); + var fixedStepGameLoop = new FixedStepGameLoop(); + fixedStepGameLoop.run(); + Thread.sleep(GAME_LOOP_DURATION_TIME); + fixedStepGameLoop.stop(); + LOGGER.info("Stop variable-step game loop."); + + } catch (InterruptedException e) { + LOGGER.error(e.getMessage()); + } +``` ## Class diagram ![alt text](./etc/game-loop.urm.png "Game Loop pattern class diagram") ## Credits - * [Game Programming Patterns - Game Loop](http://gameprogrammingpatterns.com/game-loop.html) +* [Game Programming Patterns](https://www.amazon.com/gp/product/0990582906/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=0990582906&linkId=1289749a703b3fe0e24cd8d604d7c40b) +* [Game Engine Architecture, Third Edition](https://www.amazon.com/gp/product/1138035459/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=1138035459&linkId=94502746617211bc40e0ef49d29333ac) From 645fb20730bd7d9381813773abdb269ad95703a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Thu, 23 Jul 2020 17:50:20 +0300 Subject: [PATCH 051/211] #590 improve Retry explanation --- retry/README.md | 61 ++++++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 29 deletions(-) diff --git a/retry/README.md b/retry/README.md index 0f8345412..fa56c1240 100644 --- a/retry/README.md +++ b/retry/README.md @@ -8,16 +8,12 @@ tags: - Performance --- -## Retry / resiliency -Enables an application to handle transient failures from external resources. - ## Intent -Transparently retry certain operations that involve communication with external -resources, particularly over the network, isolating calling code from the -retry implementation details. +Transparently retry certain operations that involve communication with external resources, particularly over the +network, isolating calling code from the retry implementation details. ## Explanation -The `Retry` pattern consists retrying operations on remote resources over the +Retry pattern consists retrying operations on remote resources over the network a set number of times. It closely depends on both business and technical requirements: how much time will the business allow the end user to wait while the operation finishes? What are the performance characteristics of the @@ -30,11 +26,7 @@ Another concern is the impact on the calling code by implementing the retry mechanism. The retry mechanics should ideally be completely transparent to the calling code (service interface remains unaltered). There are two general approaches to this problem: from an enterprise architecture standpoint -(**strategic**), and a shared library standpoint (**tactical**). - -*(As an aside, one interesting property is that, since implementations tend to -be configurable at runtime, daily monitoring and operation of this capability -is shifted over to operations support instead of the developers themselves.)* +(strategic), and a shared library standpoint (tactical). From a strategic point of view, this would be solved by having requests be redirected to a separate intermediary system, traditionally an @@ -42,11 +34,26 @@ be redirected to a separate intermediary system, traditionally an a [Service Mesh](https://medium.com/microservices-in-practice/service-mesh-for-microservices-2953109a3c9a). From a tactical point of view, this would be solved by reusing shared libraries -like [Hystrix](https://github.com/Netflix/Hystrix)[1]. This is the type of -solution showcased in the simple example that accompanies this *README*. +like [Hystrix](https://github.com/Netflix/Hystrix) (please note that *Hystrix* is a complete implementation of +the [Circuit Breaker](https://java-design-patterns.com/patterns/circuit-breaker/) pattern, of which the Retry pattern +can be considered a subset of.). This is the type of solution showcased in the simple example that accompanies this +*README*. -In our hypothetical application, we have a generic interface for all -operations on remote interfaces: +Real world example + +> Our application uses a service providing customer information. Once in a while the service seems to be flaky and can return errors or sometimes it just times out. To circumvent these problems we apply the retry pattern. + +In plain words + +> Retry pattern transparently retries failed operations over network. + +[Microsoft documentation](https://docs.microsoft.com/en-us/azure/architecture/patterns/retry) says + +> Enable an application to handle transient failures when it tries to connect to a service or network resource, by transparently retrying a failed operation. This can improve the stability of the application. + +**Programmatic Example** + +In our hypothetical application, we have a generic interface for all operations on remote interfaces. ```java public interface BusinessOperation { @@ -54,8 +61,7 @@ public interface BusinessOperation { } ``` -And we have an implementation of this interface that finds our customers -by looking up a database: +And we have an implementation of this interface that finds our customers by looking up a database. ```java public final class FindCustomer implements BusinessOperation { @@ -122,20 +128,12 @@ more importantly we did *not* instruct our `Retry` to ignore, then the operation would have failed immediately upon receiving the error, not matter how many attempts were left. -

- -[1] Please note that *Hystrix* is a complete implementation of the *Circuit -Breaker* pattern, of which the *Retry* pattern can be considered a subset of. - ## Class diagram ![alt text](./etc/retry.png "Retry") ## Applicability -Whenever an application needs to communicate with an external resource, -particularly in a cloud environment, and if the business requirements allow it. - -## Presentations -You can view Microsoft's article [here](https://docs.microsoft.com/en-us/azure/architecture/patterns/retry). +Whenever an application needs to communicate with an external resource, particularly in a cloud environment, and if +the business requirements allow it. ## Consequences **Pros:** @@ -150,4 +148,9 @@ You can view Microsoft's article [here](https://docs.microsoft.com/en-us/azure/a ## Related Patterns -* [Circuit Breaker](https://martinfowler.com/bliki/CircuitBreaker.html) +* [Circuit Breaker](https://java-design-patterns.com/patterns/circuit-breaker/) + +## Credits + +* [Retry pattern](https://docs.microsoft.com/en-us/azure/architecture/patterns/retry) +* [Cloud Design Patterns: Prescriptive Architecture Guidance for Cloud Applications](https://www.amazon.com/gp/product/1621140369/ref=as_li_tl?ie=UTF8&tag=javadesignpat-20&camp=1789&creative=9325&linkCode=as2&creativeASIN=1621140369&linkId=3e3f686af5e60a7a453b48adb286797b) From 9deb587c52175b0e340a5213b3db08c983e0c798 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Thu, 23 Jul 2020 18:27:00 +0300 Subject: [PATCH 052/211] #590 add explanation for Fluent Interface --- fluentinterface/README.md | 136 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 131 insertions(+), 5 deletions(-) diff --git a/fluentinterface/README.md b/fluentinterface/README.md index 3068468b9..61c5f2eb5 100644 --- a/fluentinterface/README.md +++ b/fluentinterface/README.md @@ -9,26 +9,151 @@ tags: --- ## Intent -A fluent interface provides an easy-readable, flowing interface, that often mimics a domain specific language. Using this pattern results in code that can be read nearly as human language. +A fluent interface provides an easy-readable, flowing interface, that often mimics a domain specific language. Using +this pattern results in code that can be read nearly as human language. -## Implementation +## Explanation +The Fluent Interface pattern is useful when you want to provide an easy readable, flowing API. Those interfaces tend +to mimic domain specific languages, so they can nearly be read as human languages. + A fluent interface can be implemented using any of * Method Chaining - calling a method returns some object on which further methods can be called. * Static Factory Methods and Imports * Named parameters - can be simulated in Java using static factory methods. +Real world example + +> We need to select numbers based on different criteria from the list. It's a great chance to utilize fluent interface pattern to provide readable easy-to-use developer experience. + +In plain words + +> Fluent Interface pattern provides easily readable flowing interface to code. + +Wikipedia says + +> In software engineering, a fluent interface is an object-oriented API whose design relies extensively on method chaining. Its goal is to increase code legibility by creating a domain-specific language (DSL). + +**Programmatic Example** + +In this example two implementations of a `FluentIterable` interface are given. + +```java +public interface FluentIterable extends Iterable { + + FluentIterable filter(Predicate predicate); + + Optional first(); + + FluentIterable first(int count); + + Optional last(); + + FluentIterable last(int count); + + FluentIterable map(Function function); + + List asList(); + + static List copyToList(Iterable iterable) { + var copy = new ArrayList(); + iterable.forEach(copy::add); + return copy; + } +} +``` + +The `SimpleFluentIterable` evaluates eagerly and would be too costly for real world applications. + +```java +public class SimpleFluentIterable implements FluentIterable { + ... +} +``` + +The `LazyFluentIterable` is evaluated on termination. + +```java +public class LazyFluentIterable implements FluentIterable { + ... +} +``` + +Their usage is demonstrated with a simple number list that is filtered, transformed and collected. The +result is printed afterwards. + +```java + var integerList = List.of(1, -61, 14, -22, 18, -87, 6, 64, -82, 26, -98, 97, 45, 23, 2, -68); + + prettyPrint("The initial list contains: ", integerList); + + var firstFiveNegatives = SimpleFluentIterable + .fromCopyOf(integerList) + .filter(negatives()) + .first(3) + .asList(); + prettyPrint("The first three negative values are: ", firstFiveNegatives); + + + var lastTwoPositives = SimpleFluentIterable + .fromCopyOf(integerList) + .filter(positives()) + .last(2) + .asList(); + prettyPrint("The last two positive values are: ", lastTwoPositives); + + SimpleFluentIterable + .fromCopyOf(integerList) + .filter(number -> number % 2 == 0) + .first() + .ifPresent(evenNumber -> LOGGER.info("The first even number is: {}", evenNumber)); + + + var transformedList = SimpleFluentIterable + .fromCopyOf(integerList) + .filter(negatives()) + .map(transformToString()) + .asList(); + prettyPrint("A string-mapped list of negative numbers contains: ", transformedList); + + + var lastTwoOfFirstFourStringMapped = LazyFluentIterable + .from(integerList) + .filter(positives()) + .first(4) + .last(2) + .map(number -> "String[" + valueOf(number) + "]") + .asList(); + prettyPrint("The lazy list contains the last two of the first four positive numbers " + + "mapped to Strings: ", lastTwoOfFirstFourStringMapped); + + LazyFluentIterable + .from(integerList) + .filter(negatives()) + .first(2) + .last() + .ifPresent(number -> LOGGER.info("Last amongst first two negatives: {}", number)); + + // The initial list contains: 1, -61, 14, -22, 18, -87, 6, 64, -82, 26, -98, 97, 45, 23, 2, -68. + // The first three negative values are: -61, -22, -87. + // The last two positive values are: 23, 2. + // The first even number is: 14 + // A string-mapped list of negative numbers contains: String[-61], String[-22], String[-87], String[-82], String[-98], String[-68]. + // The lazy list contains the last two of the first four positive numbers mapped to Strings: String[18], String[6]. + // Last amongst first two negatives: -22 +``` + ## Class diagram ![Fluent Interface](./etc/fluentinterface.png "Fluent Interface") ## Applicability Use the Fluent Interface pattern when -* you provide an API that would benefit from a DSL-like usage -* you have objects that are difficult to configure or use +* You provide an API that would benefit from a DSL-like usage +* You have objects that are difficult to configure or use -## Real world examples +## Known uses * [Java 8 Stream API](http://www.oracle.com/technetwork/articles/java/ma14-java-se-8-streams-2177646.html) * [Google Guava FluentInterable](https://github.com/google/guava/wiki/FunctionalExplained) @@ -41,3 +166,4 @@ Use the Fluent Interface pattern when * [Fluent Interface - Martin Fowler](http://www.martinfowler.com/bliki/FluentInterface.html) * [Evolutionary architecture and emergent design: Fluent interfaces - Neal Ford](http://www.ibm.com/developerworks/library/j-eaed14/) * [Internal DSL](http://www.infoq.com/articles/internal-dsls-java) +* [Domain Specific Languages](https://www.amazon.com/gp/product/0321712943/ref=as_li_tl?ie=UTF8&tag=javadesignpat-20&camp=1789&creative=9325&linkCode=as2&creativeASIN=0321712943&linkId=ad8351d6f5be7d8b7ecdb650731f85df) From 689486267d975dd9d40932d1f431e85ee73c4dd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Thu, 23 Jul 2020 18:53:47 +0300 Subject: [PATCH 053/211] #590 add explanation to Pipeline --- pipeline/README.md | 88 +++++++++++++++++-- .../main/java/com/iluwatar/pipeline/App.java | 3 +- 2 files changed, 84 insertions(+), 7 deletions(-) diff --git a/pipeline/README.md b/pipeline/README.md index bc8f9399a..fd03cd7b9 100644 --- a/pipeline/README.md +++ b/pipeline/README.md @@ -9,7 +9,83 @@ tags: --- ## Intent -Allows processing of data in a series of stages by giving in an initial input and passing the processed output to be used by the next stages. +Allows processing of data in a series of stages by giving in an initial input and passing the processed output to be +used by the next stages. + +## Explanation + +The Pipeline pattern uses ordered stages to process a sequence of input values. Each implemented task is represented by +a stage of the pipeline. You can think of pipelines as similar to assembly lines in a factory, where each item in the +assembly line is constructed in stages. The partially assembled item is passed from one assembly stage to another. The +outputs of the assembly line occur in the same order as that of the inputs. + +Real world example + +> Suppose we wanted to pass through a string to a series of filtering stages and convert it as a char array on the last stage. + +In plain words + +> Pipeline pattern is an assembly line where partial results are passed from one stage to another. + +Wikipedia says + +> In software engineering, a pipeline consists of a chain of processing elements (processes, threads, coroutines, functions, etc.), arranged so that the output of each element is the input of the next; the name is by analogy to a physical pipeline. + +**Programmatic Example** + +The stages of our pipeline are called `Handler`s. + +```java +interface Handler { + O process(I input); +} +``` + +In our string processing example we have 3 different concrete `Handler`s. + +```java +class RemoveAlphabetsHandler implements Handler { + ... +} + +class RemoveDigitsHandler implements Handler { + ... +} + +class ConvertToCharArrayHandler implements Handler { + ... +} +``` + +Here is the `Pipeline` that will gather and execute the handlers one by one. + +```java +class Pipeline { + + private final Handler currentHandler; + + Pipeline(Handler currentHandler) { + this.currentHandler = currentHandler; + } + + Pipeline addHandler(Handler newHandler) { + return new Pipeline<>(input -> newHandler.process(currentHandler.process(input))); + } + + O execute(I input) { + return currentHandler.process(input); + } +} +``` + +And here's the `Pipeline` in action processing the string. + +```java + var filters = new Pipeline<>(new RemoveAlphabetsHandler()) + .addHandler(new RemoveDigitsHandler()) + .addHandler(new ConvertToCharArrayHandler()); + filters.execute("GoYankees123!"); +``` ## Class diagram ![alt text](./etc/pipeline.urm.png "Pipeline pattern class diagram") @@ -21,16 +97,16 @@ Use the Pipeline pattern when you want to * Add readability to complex sequence of operations by providing a fluent builder as an interface * Improve testability of code since stages will most likely be doing a single thing, complying to the [Single Responsibility Principle (SRP)](https://java-design-patterns.com/principles/#single-responsibility-principle) -## Typical Use Case - -* Implement stages and execute them in an ordered manner - -## Real world examples +## Known uses * [java.util.Stream](https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html) * [Maven Build Lifecycle](http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html) * [Functional Java](https://github.com/functionaljava/functionaljava) +## Related patterns + +* [Chain of Responsibility](https://java-design-patterns.com/patterns/chain/) + ## Credits * [The Pipeline Pattern — for fun and profit](https://medium.com/@aaronweatherall/the-pipeline-pattern-for-fun-and-profit-9b5f43a98130) diff --git a/pipeline/src/main/java/com/iluwatar/pipeline/App.java b/pipeline/src/main/java/com/iluwatar/pipeline/App.java index 1b1e443e6..cfbcbafc2 100644 --- a/pipeline/src/main/java/com/iluwatar/pipeline/App.java +++ b/pipeline/src/main/java/com/iluwatar/pipeline/App.java @@ -59,8 +59,9 @@ public class App { then is expected to receive an input of char[] array since that is the type being returned by the previous handler, ConvertToCharArrayHandler. */ - new Pipeline<>(new RemoveAlphabetsHandler()) + var filters = new Pipeline<>(new RemoveAlphabetsHandler()) .addHandler(new RemoveDigitsHandler()) .addHandler(new ConvertToCharArrayHandler()); + filters.execute("GoYankees123!"); } } From 205b87cd9352f303c3ba9165f32286cfc9aef244 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Fri, 24 Jul 2020 16:45:28 +0300 Subject: [PATCH 054/211] Improve Prototype description --- prototype/README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/prototype/README.md b/prototype/README.md index c51f5c9bc..472e8330c 100644 --- a/prototype/README.md +++ b/prototype/README.md @@ -10,10 +10,13 @@ tags: --- ## Intent -Specify the kinds of objects to create using a prototypical -instance, and create new objects by copying this prototype. +Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype. ## Explanation + +First it should be noted that Prototype pattern is not used to gain performance benefits. It's only used for creating +new objects from prototype instance. + Real world example > Remember Dolly? The sheep that was cloned! Lets not get into the details but the key point here is that it is all about cloning. From d9ed8a52b50feaa3be97ae991060171adb418650 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sat, 25 Jul 2020 14:28:43 +0300 Subject: [PATCH 055/211] Update readme --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 53c9cd7a5..2eabb5e82 100644 --- a/README.md +++ b/README.md @@ -31,19 +31,20 @@ programming tutorials how to implement a specific pattern. We use the most popular battle-proven open source Java technologies. Before you dive into the material, you should be familiar with various -software design principles. +[Software Design Principles](https://java-design-patterns.com/principles/). All designs should be as simple as possible. You should start with KISS, YAGNI, and Do The Simplest Thing That Could Possibly Work principles. Complexity and patterns should only be introduced when they are needed for practical extensibility. -Once you are familiar with these concepts you can start drilling down into -patterns by any of the following approaches +Once you are familiar with these concepts you can start drilling down into the +[available design patterns](https://java-design-patterns.com/patterns/) by any +of the following approaches - - Using difficulty tags, `Difficulty-Beginner`, `Difficulty-Intermediate` & `Difficulty-Expert`. + - Search for a specific pattern by name. Can't find one? Please report a new pattern [here](https://github.com/iluwatar/java-design-patterns/issues). + - Using tags such as `Performance`, `Gang of Four` or `Data access`. - Using pattern categories, `Creational`, `Behavioral`, and others. - - Search for a specific pattern. Can't find one? Please report a new pattern [here](https://github.com/iluwatar/java-design-patterns/issues). Hopefully you find the object oriented solutions presented on this site useful in your architectures and have as much fun learning them as we had developing them. From 2ee5789c7739ecb676f57348320c0d845c1a99af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sat, 25 Jul 2020 15:48:21 +0300 Subject: [PATCH 056/211] #590 explanation for Trampoline --- trampoline/README.md | 129 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 112 insertions(+), 17 deletions(-) diff --git a/trampoline/README.md b/trampoline/README.md index 2356e8715..8831f41e1 100644 --- a/trampoline/README.md +++ b/trampoline/README.md @@ -9,14 +9,111 @@ tags: --- ## Intent -Trampoline pattern is used for implementing algorithms recursively in Java without blowing the stack -and to interleave the execution of functions without hard coding them together -It is possible by representing a computation in one of 2 states : done | more -(completed with result, or a reference to the reminder of the computation, -something like the way a java.util.Supplier does). + +Trampoline pattern is used for implementing algorithms recursively in Java without blowing the stack and to interleave +the execution of functions without hard coding them together. ## Explanation -Trampoline pattern allows to define recursive algorithms by iterative loop. + +Recursion is a frequently adopted technique for solving algorithmic problems in a divide and conquer +style. For example calculating fibonacci accumulating sum and factorials. In these kinds of problems recursion is +more straightforward than their loop counterpart. Furthermore recursion may need less code and looks more concise. +There is a saying that every recursion problem can be solved using a loop with the cost of writing code that is more +difficult to understand. + +However recursion type solutions have one big caveat. For each recursive call it typically needs an intermediate value +stored and there is a limited amount of stack memory available. Running out of stack memory creates a stack overflow +error and halts the program execution. + +Trampoline pattern is a trick that allows us define recursive algorithms in Java without blowing the stack. + +Real world example + +> A recursive Fibonacci calculation without the stack overflow problem using the Trampoline pattern. + +In plain words + +> Trampoline pattern allows recursion without running out of stack memory. + +Wikipedia says + +> In Java, trampoline refers to using reflection to avoid using inner classes, for example in event listeners. The time overhead of a reflection call is traded for the space overhead of an inner class. Trampolines in Java usually involve the creation of a GenericListener to pass events to an outer class. + +**Programmatic Example** + +Here's the `Trampoline` implementation in Java. + +When `get` is called on the returned Trampoline, internally it will iterate calling `jump` on the returned `Trampoline` +as long as the concrete instance returned is `Trampoline`, stopping once the returned instance is `done`. + +```java +public interface Trampoline { + + T get(); + + default Trampoline jump() { + return this; + } + + default T result() { + return get(); + } + + default boolean complete() { + return true; + } + + static Trampoline done(final T result) { + return () -> result; + } + + static Trampoline more(final Trampoline> trampoline) { + return new Trampoline() { + @Override + public boolean complete() { + return false; + } + + @Override + public Trampoline jump() { + return trampoline.result(); + } + + @Override + public T get() { + return trampoline(this); + } + + T trampoline(final Trampoline trampoline) { + return Stream.iterate(trampoline, Trampoline::jump) + .filter(Trampoline::complete) + .findFirst() + .map(Trampoline::result) + .orElseThrow(); + } + }; + } +} +``` + +Using the `Trampoline` to get Fibonacci values. + +```java + public static Trampoline loop(int times, int prod) { + if (times == 0) { + return Trampoline.done(prod); + } else { + return Trampoline.more(() -> loop(times - 1, prod * times)); + } + } + + log.info("start pattern"); + var result = loop(10, 1).result(); + log.info("result {}", result); + + // start pattern + // result 3628800 +``` ## Class diagram ![alt text](./etc/trampoline.urm.png "Trampoline pattern class diagram") @@ -27,18 +124,16 @@ Use the Trampoline pattern when * For implementing tail recursive function. This pattern allows to switch on a stackless operation. * For interleaving the execution of two or more functions on the same thread. -## Known uses(real world examples) +## Known uses -* Trampoline refers to using reflection to avoid using inner classes, for example in event listeners. -The time overhead of a reflection call is traded for the space overhead of an inner class. -Trampolines in Java usually involve the creation of a GenericListener to pass events to an outer class. - - -## Tutorials - -* [Trampolining: a practical guide for awesome Java Developers](https://medium.com/@johnmcclean/trampolining-a-practical-guide-for-awesome-java-developers-4b657d9c3076) -* [Trampoline in java ](http://mindprod.com/jgloss/trampoline.html) +* [cyclops-react](https://github.com/aol/cyclops-react) ## Credits -* [library 'cyclops-react' uses the pattern](https://github.com/aol/cyclops-react) +* [Trampolining: a practical guide for awesome Java Developers](https://medium.com/@johnmcclean/trampolining-a-practical-guide-for-awesome-java-developers-4b657d9c3076) +* [Trampoline in java ](http://mindprod.com/jgloss/trampoline.html) +* [Laziness, trampolines, monoids and other functional amenities: this is not your father's Java](https://www.slideshare.net/mariofusco/lazine) +* [Trampoline implementation](https://github.com/bodar/totallylazy/blob/master/src/com/googlecode/totallylazy/Trampoline.java) +* [What is a trampoline function?](https://stackoverflow.com/questions/189725/what-is-a-trampoline-function) +* [Modern Java in Action: Lambdas, streams, functional and reactive programming](https://www.amazon.com/gp/product/1617293563/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=1617293563&linkId=ad53ae6f9f7c0982e759c3527bd2595c) +* [Java 8 in Action: Lambdas, Streams, and functional-style programming](https://www.amazon.com/gp/product/1617291994/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=1617291994&linkId=e3e5665b0732c59c9d884896ffe54f4f) From 1eafb46b6160ec36a2f09d5ef2e866e3728b47f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 26 Jul 2020 11:30:42 +0300 Subject: [PATCH 057/211] Update links and tags --- ambassador/README.md | 6 +++--- caching/README.md | 5 +++-- circuit-breaker/README.md | 7 ++++--- cqrs/README.md | 11 ++++++----- event-sourcing/README.md | 4 +++- leader-election/README.md | 2 +- priority-queue/README.md | 8 ++++---- queue-load-leveling/README.md | 3 ++- retry/README.md | 1 + saga/README.md | 1 + sharding/README.md | 2 +- strangler/README.md | 5 ++--- throttling/README.md | 1 + 13 files changed, 32 insertions(+), 24 deletions(-) diff --git a/ambassador/README.md b/ambassador/README.md index 78b3a8856..11abfaf88 100644 --- a/ambassador/README.md +++ b/ambassador/README.md @@ -5,7 +5,8 @@ folder: ambassador permalink: /patterns/ambassador/ categories: Structural tags: - - Decoupling + - Decoupling + - Cloud distributed --- ## Intent @@ -22,8 +23,7 @@ In plain words Microsoft documentation states -> An ambassador service can be thought of as an out-of-process proxy that is co-located with the client. - This pattern can be useful for offloading common client connectivity tasks such as monitoring, logging, routing, security (such as TLS), and resiliency patterns in a language agnostic way. It is often used with legacy applications, or other applications that are difficult to modify, in order to extend their networking capabilities. It can also enable a specialized team to implement those features. +> An ambassador service can be thought of as an out-of-process proxy that is co-located with the client. This pattern can be useful for offloading common client connectivity tasks such as monitoring, logging, routing, security (such as TLS), and resiliency patterns in a language agnostic way. It is often used with legacy applications, or other applications that are difficult to modify, in order to extend their networking capabilities. It can also enable a specialized team to implement those features. **Programmatic Example** diff --git a/caching/README.md b/caching/README.md index 4172cc72a..912f1d218 100644 --- a/caching/README.md +++ b/caching/README.md @@ -5,7 +5,8 @@ folder: caching permalink: /patterns/caching/ categories: Behavioral tags: - - Performance + - Performance + - Cloud distributed --- ## Intent @@ -25,4 +26,4 @@ Use the Caching pattern(s) when * [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) -* [Cache-Aside](https://msdn.microsoft.com/en-us/library/dn589799.aspx) +* [Cache-Aside pattern](https://docs.microsoft.com/en-us/azure/architecture/patterns/cache-aside) diff --git a/circuit-breaker/README.md b/circuit-breaker/README.md index e0ef7d1fb..ce280a570 100644 --- a/circuit-breaker/README.md +++ b/circuit-breaker/README.md @@ -5,8 +5,9 @@ folder: circuit-breaker permalink: /patterns/circuit-breaker/ categories: Behavioral tags: - - Performance - - Decoupling + - Performance + - Decoupling + - Cloud distributed --- ## Intent @@ -187,4 +188,4 @@ Use the Circuit Breaker pattern when * [Understanding Circuit Breaker Pattern](https://itnext.io/understand-circuitbreaker-design-pattern-with-simple-practical-example-92a752615b42) * [Martin Fowler on Circuit Breaker](https://martinfowler.com/bliki/CircuitBreaker.html) * [Fault tolerance in a high volume, distributed system](https://medium.com/netflix-techblog/fault-tolerance-in-a-high-volume-distributed-system-91ab4faae74a) -* [Microsoft docs](https://docs.microsoft.com/en-us/azure/architecture/patterns/circuit-breaker) +* [Circuit Breaker pattern](https://docs.microsoft.com/en-us/azure/architecture/patterns/circuit-breaker) diff --git a/cqrs/README.md b/cqrs/README.md index 431ae6279..017e0a003 100644 --- a/cqrs/README.md +++ b/cqrs/README.md @@ -5,8 +5,8 @@ folder: cqrs permalink: /patterns/cqrs/ categories: Architectural tags: - - Performance - - Cloud distributed + - Performance + - Cloud distributed --- ## Intent @@ -18,12 +18,13 @@ CQRS Command Query Responsibility Segregation - Separate the query side from the ## Applicability Use the CQRS pattern when -* you want to scale the queries and commands independently. -* you want to use different data models for queries and commands. Useful when dealing with complex domains. -* you want to use architectures like event sourcing or task based UI. +* You want to scale the queries and commands independently. +* You want to use different data models for queries and commands. Useful when dealing with complex domains. +* You want to use architectures like event sourcing or task based UI. ## Credits * [Greg Young - CQRS, Task Based UIs, Event Sourcing agh!](http://codebetter.com/gregyoung/2010/02/16/cqrs-task-based-uis-event-sourcing-agh/) * [Martin Fowler - CQRS](https://martinfowler.com/bliki/CQRS.html) * [Oliver Wolf - CQRS for Great Good](https://www.youtube.com/watch?v=Ge53swja9Dw) +* [Command and Query Responsibility Segregation (CQRS) pattern](https://docs.microsoft.com/en-us/azure/architecture/patterns/cqrs) diff --git a/event-sourcing/README.md b/event-sourcing/README.md index 5efbbbd02..6d24a40e5 100644 --- a/event-sourcing/README.md +++ b/event-sourcing/README.md @@ -5,7 +5,8 @@ folder: event-sourcing permalink: /patterns/event-sourcing/ categories: Architectural tags: - - Performance + - Performance + - Cloud distributed --- ## Intent @@ -30,3 +31,4 @@ Use the Event Sourcing pattern when * [Martin Fowler - Event Sourcing] (https://martinfowler.com/eaaDev/EventSourcing.html) * [Event Sourcing | Microsoft Docs] (https://docs.microsoft.com/en-us/azure/architecture/patterns/event-sourcing) * [Reference 3: Introducing Event Sourcing] (https://msdn.microsoft.com/en-us/library/jj591559.aspx) +* [Event Sourcing pattern](https://docs.microsoft.com/en-us/azure/architecture/patterns/event-sourcing) diff --git a/leader-election/README.md b/leader-election/README.md index 3cfa7a662..85943d5b4 100644 --- a/leader-election/README.md +++ b/leader-election/README.md @@ -30,4 +30,4 @@ Do not use this pattern when ## Credits -* [ Cloud Design Patterns: Prescriptive Architecture Guidance for Cloud Applications](https://docs.microsoft.com/en-us/previous-versions/msp-n-p/dn568104(v=pandp.10)) +* [Leader Election pattern](https://docs.microsoft.com/en-us/azure/architecture/patterns/leader-election) diff --git a/priority-queue/README.md b/priority-queue/README.md index c8d1f7773..924d7169f 100644 --- a/priority-queue/README.md +++ b/priority-queue/README.md @@ -6,6 +6,7 @@ permalink: /patterns/priority-queue/ categories: Behavioral tags: - Decoupling + - Cloud distributed --- ## Intent @@ -18,12 +19,11 @@ Applications may delegate specific tasks to other services; for example, to perf ![alt text](./etc/priority-queue.urm.png "Priority Queue pattern class diagram") ## Applicability -Use the Property pattern when +Use the Priority Queue pattern when * The system must handle multiple tasks that might have different priorities. * Different users or tenants should be served with different priority.. -## Real world examples +## Credits -* [ Priority Queue Pattern](https://docs.microsoft.com/en-us/previous-versions/msp-n-p/dn589794(v=pandp.10)) -Microsoft Azure does not provide a queuing mechanism that natively support automatic prioritization of messages through sorting. However, it does provide Azure Service Bus topics and subscriptions, which support a queuing mechanism that provides message filtering, together with a wide range of flexible capabilities that make it ideal for use in almost all priority queue implementations. +* [Priority Queue pattern](https://docs.microsoft.com/en-us/azure/architecture/patterns/priority-queue) diff --git a/queue-load-leveling/README.md b/queue-load-leveling/README.md index 3674e7413..5cad88636 100644 --- a/queue-load-leveling/README.md +++ b/queue-load-leveling/README.md @@ -7,6 +7,7 @@ categories: Concurrency tags: - Decoupling - Performance + - Cloud distributed --- ## Intent @@ -32,4 +33,4 @@ for both the task and the service. ## Credits -* [Microsoft Cloud Design Patterns: Queue-Based Load Leveling Pattern](https://msdn.microsoft.com/en-us/library/dn589783.aspx) +* [Queue-Based Load Leveling pattern](https://docs.microsoft.com/en-us/azure/architecture/patterns/queue-based-load-leveling) diff --git a/retry/README.md b/retry/README.md index fa56c1240..056674a18 100644 --- a/retry/README.md +++ b/retry/README.md @@ -6,6 +6,7 @@ permalink: /patterns/retry/ categories: Behavioral tags: - Performance + - Cloud distributed --- ## Intent diff --git a/saga/README.md b/saga/README.md index 50aeb7d73..394398f99 100644 --- a/saga/README.md +++ b/saga/README.md @@ -46,3 +46,4 @@ Use the Saga pattern, if: ## Credits - [Pattern: Saga](https://microservices.io/patterns/data/saga.html) +- [Saga distributed transactions pattern](https://docs.microsoft.com/en-us/azure/architecture/reference-architectures/saga/saga) diff --git a/sharding/README.md b/sharding/README.md index 2ee465401..cc2121bb5 100644 --- a/sharding/README.md +++ b/sharding/README.md @@ -26,4 +26,4 @@ This pattern offers the following benefits: ## Credits -* [Cloud Design Patterns: Prescriptive Architecture Guidance for Cloud Applications - Sharding Pattern](https://docs.microsoft.com/en-us/previous-versions/msp-n-p/dn589797(v=pandp.10)?redirectedfrom=MSDN) +* [Sharding pattern](https://docs.microsoft.com/en-us/azure/architecture/patterns/sharding) diff --git a/strangler/README.md b/strangler/README.md index 2f157f1d2..667940798 100644 --- a/strangler/README.md +++ b/strangler/README.md @@ -6,6 +6,7 @@ permalink: /patterns/strangler/ categories: Structural tags: - Extensibility + - Cloud distributed --- ## Intent @@ -25,7 +26,5 @@ so usually use it when the system is not so simple. ## Credits -* [Strangler pattern](https://docs.microsoft.com/en-us/azure/architecture/patterns/strangler#context-and-problem) +* [Strangler pattern](https://docs.microsoft.com/en-us/azure/architecture/patterns/strangler) * [Legacy Application Strangulation : Case Studies](https://paulhammant.com/2013/07/14/legacy-application-strangulation-case-studies/) - - diff --git a/throttling/README.md b/throttling/README.md index f3ef43c17..48e1b1c78 100644 --- a/throttling/README.md +++ b/throttling/README.md @@ -6,6 +6,7 @@ permalink: /patterns/throttling/ categories: Behavioral tags: - Performance + - Cloud distributed --- ## Intent From 0a35cdfbe4b9a3ac90a3b39b7da809c390de1207 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 26 Jul 2020 12:10:48 +0300 Subject: [PATCH 058/211] #590 explanation for Unit of Work --- unit-of-work/README.md | 165 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 163 insertions(+), 2 deletions(-) diff --git a/unit-of-work/README.md b/unit-of-work/README.md index 94ef784f5..1f6c7c5b2 100644 --- a/unit-of-work/README.md +++ b/unit-of-work/README.md @@ -7,11 +7,167 @@ permalink: /patterns/unit-of-work/ categories: Architectural tags: - Data access + - Performance --- ## Intent -When a business transaction is completed, all the these updates are sent as one - big unit of work to be persisted in a database in one go so as to minimize database trips. +When a business transaction is completed, all the the updates are sent as one big unit of work to be persisted +in one go to minimize database round-trips. + +## Explanation +Real world example + +> We have a database containing student information. Administrators all over the country are constantly updating this information and it causes high load on the database server. To make the load more manageable we apply to Unit of Work pattern to send many small updates in batches. + +In plain words + +> Unit of Work merges many small database updates in single batch to optimize the number of round-trips. + +[MartinFowler.com](https://martinfowler.com/eaaCatalog/unitOfWork.html) says + +> Maintains a list of objects affected by a business transaction and coordinates the writing out of changes and the resolution of concurrency problems. + +**Programmatic Example** + +Here's the `Student` entity that is being persisted to the database. + +```java +public class Student { + private final Integer id; + private final String name; + private final String address; + + public Student(Integer id, String name, String address) { + this.id = id; + this.name = name; + this.address = address; + } + + public String getName() { + return name; + } + + public Integer getId() { + return id; + } + + public String getAddress() { + return address; + } +} +``` + +The essence of the implementation is the `StudentRepository` implementing the Unit of Work pattern. It maintains a map +of database operations (`context`) that need to be done and when `commit` is called it applies them in single batch. + +```java +public interface IUnitOfWork { + + String INSERT = "INSERT"; + String DELETE = "DELETE"; + String MODIFY = "MODIFY"; + + void registerNew(T entity); + + void registerModified(T entity); + + void registerDeleted(T entity); + + void commit(); +} + +public class StudentRepository implements IUnitOfWork { + private static final Logger LOGGER = LoggerFactory.getLogger(StudentRepository.class); + + private Map> context; + private StudentDatabase studentDatabase; + + public StudentRepository(Map> context, StudentDatabase studentDatabase) { + this.context = context; + this.studentDatabase = studentDatabase; + } + + @Override + public void registerNew(Student student) { + LOGGER.info("Registering {} for insert in context.", student.getName()); + register(student, IUnitOfWork.INSERT); + } + + @Override + public void registerModified(Student student) { + LOGGER.info("Registering {} for modify in context.", student.getName()); + register(student, IUnitOfWork.MODIFY); + + } + + @Override + public void registerDeleted(Student student) { + LOGGER.info("Registering {} for delete in context.", student.getName()); + register(student, IUnitOfWork.DELETE); + } + + private void register(Student student, String operation) { + var studentsToOperate = context.get(operation); + if (studentsToOperate == null) { + studentsToOperate = new ArrayList<>(); + } + studentsToOperate.add(student); + context.put(operation, studentsToOperate); + } + + @Override + public void commit() { + if (context == null || context.size() == 0) { + return; + } + LOGGER.info("Commit started"); + if (context.containsKey(IUnitOfWork.INSERT)) { + commitInsert(); + } + + if (context.containsKey(IUnitOfWork.MODIFY)) { + commitModify(); + } + if (context.containsKey(IUnitOfWork.DELETE)) { + commitDelete(); + } + LOGGER.info("Commit finished."); + } + + private void commitInsert() { + var studentsToBeInserted = context.get(IUnitOfWork.INSERT); + for (var student : studentsToBeInserted) { + LOGGER.info("Saving {} to database.", student.getName()); + studentDatabase.insert(student); + } + } + + private void commitModify() { + var modifiedStudents = context.get(IUnitOfWork.MODIFY); + for (var student : modifiedStudents) { + LOGGER.info("Modifying {} to database.", student.getName()); + studentDatabase.modify(student); + } + } + + private void commitDelete() { + var deletedStudents = context.get(IUnitOfWork.DELETE); + for (var student : deletedStudents) { + LOGGER.info("Deleting {} to database.", student.getName()); + studentDatabase.delete(student); + } + } +} +``` + +Finally here's how we use the `StudentRepository` and `commit` the transaction. + +```java + studentRepository.registerNew(ram); + studentRepository.registerModified(shyam); + studentRepository.registerDeleted(gopi); + studentRepository.commit(); +``` ## Class diagram ![alt text](etc/unit-of-work.urm.png "unit-of-work") @@ -23,6 +179,11 @@ Use the Unit Of Work pattern when * To send changes to database as a unit of work which ensures atomicity of the transaction. * To reduce number of database calls. +## Tutorials + +* [Repository and Unit of Work Pattern](https://www.programmingwithwolfgang.com/repository-and-unit-of-work-pattern/) +* [Unit of Work - a Design Pattern](https://mono.software/2017/01/13/unit-of-work-a-design-pattern/) + ## Credits * [Design Pattern - Unit Of Work Pattern](https://www.codeproject.com/Articles/581487/Unit-of-Work-Design-Pattern) From 3e1a83e29d6242e000c2ec73a2de2db26d749bdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 26 Jul 2020 15:53:48 +0300 Subject: [PATCH 059/211] #590 explanation for API Gateway --- api-gateway/README.md | 141 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 135 insertions(+), 6 deletions(-) diff --git a/api-gateway/README.md b/api-gateway/README.md index 3a4f13e35..0d67b8d9b 100644 --- a/api-gateway/README.md +++ b/api-gateway/README.md @@ -5,14 +5,142 @@ folder: api-gateway permalink: /patterns/api-gateway/ categories: Architectural tags: -- Cloud distributed -- Decoupling + - Cloud distributed + - Decoupling + - Microservices --- ## 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. +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. + +## Explanation + +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. + +Real world example + +> We are implementing microservices and API Gateway pattern for an e-commerce site. In this system the API Gateway makes +calls to the Image and Price microservices. + +In plain words + +> For a system implemented using microservices architecture, API Gateway is the single entry point that aggregates the +calls to the individual microservices. + +Wikipedia says + +> API Gateway is a server that acts as an API front-end, receives API requests, enforces throttling and security +policies, passes requests to the back-end service and then passes the response back to the requester. A gateway often +includes a transformation engine to orchestrate and modify the requests and responses on the fly. A gateway can also +provide functionality such as collecting analytics data and providing caching. The gateway can provide functionality to +support authentication, authorization, security, audit and regulatory compliance. + +**Programmatic Example** + +This implementation shows what the API Gateway pattern could look like for an e-commerce site. The `ApiGateway` makes +calls to the Image and Price microservices using the `ImageClientImpl` and `PriceClientImpl` respectively. Customers +viewing the site on a desktop device can see both price information and an image of a product, so the `ApiGateway` calls +both of the microservices and aggregates the data in the `DesktopProduct` model. However, mobile users only see price +information; they do not see a product image. For mobile users, the `ApiGateway` only retrieves price information, which +it uses to populate the `MobileProduct`. + +Here's the Image microservice implementation. + +```java +public interface ImageClient { + String getImagePath(); +} + +public class ImageClientImpl implements ImageClient { + + @Override + public String getImagePath() { + var httpClient = HttpClient.newHttpClient(); + var httpGet = HttpRequest.newBuilder() + .GET() + .uri(URI.create("http://localhost:50005/image-path")) + .build(); + + try { + var httpResponse = httpClient.send(httpGet, BodyHandlers.ofString()); + return httpResponse.body(); + } catch (IOException | InterruptedException e) { + e.printStackTrace(); + } + + return null; + } +} +``` + +Here's the Price microservice implementation. + +```java +public interface PriceClient { + String getPrice(); +} + +public class PriceClientImpl implements PriceClient { + + @Override + public String getPrice() { + var httpClient = HttpClient.newHttpClient(); + var httpGet = HttpRequest.newBuilder() + .GET() + .uri(URI.create("http://localhost:50006/price")) + .build(); + + try { + var httpResponse = httpClient.send(httpGet, BodyHandlers.ofString()); + return httpResponse.body(); + } catch (IOException | InterruptedException e) { + e.printStackTrace(); + } + + return null; + } +} +``` + +And here we can see how API Gateway maps the requests to the microservices. + +```java +public class ApiGateway { + + @Resource + private ImageClient imageClient; + + @Resource + private PriceClient priceClient; + + @RequestMapping(path = "/desktop", method = RequestMethod.GET) + public DesktopProduct getProductDesktop() { + var desktopProduct = new DesktopProduct(); + desktopProduct.setImagePath(imageClient.getImagePath()); + desktopProduct.setPrice(priceClient.getPrice()); + return desktopProduct; + } + + @RequestMapping(path = "/mobile", method = RequestMethod.GET) + public MobileProduct getProductMobile() { + var mobileProduct = new MobileProduct(); + mobileProduct.setPrice(priceClient.getPrice()); + return mobileProduct; + } +} +``` ## Class diagram ![alt text](./etc/api-gateway.png "API Gateway") @@ -21,10 +149,11 @@ call to the API Gateway, and the API Gateway then calls each relevant microservi Use the API Gateway pattern when -* you're also using the Microservices pattern and need a single point of aggregation for your -microservice calls +* You're using microservices architecture 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/) +* [Microservices Patterns: With examples in Java](https://www.amazon.com/gp/product/1617294543/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=1617294543&linkId=ac7b6a57f866ac006a309d9086e8cfbd) +* [Building Microservices: Designing Fine-Grained Systems](https://www.amazon.com/gp/product/1491950358/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=1491950358&linkId=4c95ca9831e05e3f0dadb08841d77bf1) From f37d697a606a4d37465cb4959459bffc3d019b0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 26 Jul 2020 19:25:25 +0300 Subject: [PATCH 060/211] #590 explanation for Service Layer --- service-layer/README.md | 210 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 204 insertions(+), 6 deletions(-) diff --git a/service-layer/README.md b/service-layer/README.md index 3feaf8395..910eaeaea 100644 --- a/service-layer/README.md +++ b/service-layer/README.md @@ -9,12 +9,210 @@ tags: --- ## Intent -Service Layer is an abstraction over domain logic. Typically -applications require multiple kinds of interfaces to the data they store and -logic they implement: data loaders, user interfaces, integration gateways, and -others. Despite their different purposes, these interfaces often need common -interactions with the application to access and manipulate its data and invoke -its business logic. The Service Layer fulfills this role. + +Service Layer is an abstraction over domain logic. It defines application's boundary with a layer of services that +establishes a set of available operations and coordinates the application's response in each operation. + +## Explanation + +Typically applications require different kinds of interfaces to the data they store and the logic they implement. +Despite their different purposes, these interfaces often need common interactions with the application to access and +manipulate its data and invoke its business logic. Encoding the logic of the interactions separately in each module +causes a lot of duplication. It's better to centralize building the business logic inside single Service Layer to avoid +these pitfalls. + +Real world example + +> We are writing an application that tracks wizards, spellbooks and spells. Wizards may have spellbooks and spellbooks +may have spells. + +In plain words + +> Service Layer is an abstraction over application's business logic. + +Wikipedia says + +> Service layer is an architectural pattern, applied within the service-orientation design paradigm, which aims to +organize the services, within a service inventory, into a set of logical layers. Services that are categorized into +a particular layer share functionality. This helps to reduce the conceptual overhead related to managing the service +inventory, as the services belonging to the same layer address a smaller set of activities. + +**Programmatic Example** + +The example application demonstrates interactions between a client `App` and a service `MagicService` that allows +interaction between wizards, spellbooks and spells. The service is implemented with 3-layer architecture +(entity, dao, service). + +For this explanation we are looking at one vertical slice of the system. Let's start from the entity layer and look at +`Wizard` class. Other entities not shown here are `Spellbook` and `Spell`. + +```java +@Entity +@Table(name = "WIZARD") +public class Wizard extends BaseEntity { + + @Id + @GeneratedValue + @Column(name = "WIZARD_ID") + private Long id; + + private String name; + + @ManyToMany(cascade = CascadeType.ALL) + private Set spellbooks; + + public Wizard() { + spellbooks = new HashSet<>(); + } + + public Wizard(String name) { + this(); + this.name = name; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Set getSpellbooks() { + return spellbooks; + } + + public void setSpellbooks(Set spellbooks) { + this.spellbooks = spellbooks; + } + + public void addSpellbook(Spellbook spellbook) { + spellbook.getWizards().add(this); + spellbooks.add(spellbook); + } + + @Override + public String toString() { + return name; + } +} +``` + +Above the entity layer we have DAOs. For `Wizard` the DAO layer looks as follows. + +```java +public interface WizardDao extends Dao { + + Wizard findByName(String name); +} + +public class WizardDaoImpl extends DaoBaseImpl implements WizardDao { + + @Override + public Wizard findByName(String name) { + Transaction tx = null; + Wizard result; + try (var session = getSessionFactory().openSession()) { + tx = session.beginTransaction(); + var criteria = session.createCriteria(persistentClass); + criteria.add(Restrictions.eq("name", name)); + result = (Wizard) criteria.uniqueResult(); + tx.commit(); + } catch (Exception e) { + if (tx != null) { + tx.rollback(); + } + throw e; + } + return result; + } +} +``` + +Next we can look at the Service Layer, which in our case consists of a single `MagicService`. + +```java +public interface MagicService { + + List findAllWizards(); + + List findAllSpellbooks(); + + List findAllSpells(); + + List findWizardsWithSpellbook(String name); + + List findWizardsWithSpell(String name); +} + +public class MagicServiceImpl implements MagicService { + + private WizardDao wizardDao; + private SpellbookDao spellbookDao; + private SpellDao spellDao; + + public MagicServiceImpl(WizardDao wizardDao, SpellbookDao spellbookDao, SpellDao spellDao) { + this.wizardDao = wizardDao; + this.spellbookDao = spellbookDao; + this.spellDao = spellDao; + } + + @Override + public List findAllWizards() { + return wizardDao.findAll(); + } + + @Override + public List findAllSpellbooks() { + return spellbookDao.findAll(); + } + + @Override + public List findAllSpells() { + return spellDao.findAll(); + } + + @Override + public List findWizardsWithSpellbook(String name) { + var spellbook = spellbookDao.findByName(name); + return new ArrayList<>(spellbook.getWizards()); + } + + @Override + public List findWizardsWithSpell(String name) { + var spell = spellDao.findByName(name); + var spellbook = spell.getSpellbook(); + return new ArrayList<>(spellbook.getWizards()); + } +} +``` + +And finally we can show how the client `App` interacts with `MagicService` in the Service Layer. + +```java + var service = new MagicServiceImpl(wizardDao, spellbookDao, spellDao); + LOGGER.info("Enumerating all wizards"); + service.findAllWizards().stream().map(Wizard::getName).forEach(LOGGER::info); + LOGGER.info("Enumerating all spellbooks"); + service.findAllSpellbooks().stream().map(Spellbook::getName).forEach(LOGGER::info); + LOGGER.info("Enumerating all spells"); + service.findAllSpells().stream().map(Spell::getName).forEach(LOGGER::info); + LOGGER.info("Find wizards with spellbook 'Book of Idores'"); + var wizardsWithSpellbook = service.findWizardsWithSpellbook("Book of Idores"); + wizardsWithSpellbook.forEach(w -> LOGGER.info("{} has 'Book of Idores'", w.getName())); + LOGGER.info("Find wizards with spell 'Fireball'"); + var wizardsWithSpell = service.findWizardsWithSpell("Fireball"); + wizardsWithSpell.forEach(w -> LOGGER.info("{} has 'Fireball'", w.getName())); +``` + ## Class diagram ![alt text](./etc/service-layer.png "Service Layer") From 2fdd7a11e93c38d0a3496f09232fa10c51de3f21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 26 Jul 2020 22:40:42 +0300 Subject: [PATCH 061/211] SonarQube check runs only in master branch (workaround for https://jira.sonarsource.com/browse/MMF-1371) --- .github/workflows/maven.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 53460c97d..01caaab67 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -46,7 +46,13 @@ jobs: # Some tests need screen access - name: Install xvfb run: sudo apt-get install xvfb + # SonarQube scan does not work for forked repositories + # See https://jira.sonarsource.com/browse/MMF-1371 - name: Build with Maven + if: github.ref != ‘refs/heads/master’ + run: xvfb-run mvn clean verify + - name: Build with Maven and run SonarQube analysis + if: github.ref == ‘refs/heads/master’ run: xvfb-run mvn clean verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar env: # These two env variables are needed for sonar analysis From eee409f2840d6276826f8577fd5408afa52e7a40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 26 Jul 2020 22:44:54 +0300 Subject: [PATCH 062/211] Fix syntax --- .github/workflows/maven.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 01caaab67..336c103d6 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -49,10 +49,10 @@ jobs: # SonarQube scan does not work for forked repositories # See https://jira.sonarsource.com/browse/MMF-1371 - name: Build with Maven - if: github.ref != ‘refs/heads/master’ + if: "github.ref != ‘refs/heads/master’" run: xvfb-run mvn clean verify - name: Build with Maven and run SonarQube analysis - if: github.ref == ‘refs/heads/master’ + if: "github.ref == ‘refs/heads/master’" run: xvfb-run mvn clean verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar env: # These two env variables are needed for sonar analysis From 4b88214baef78c362806311d88f96bebb0cd4d21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 26 Jul 2020 22:47:33 +0300 Subject: [PATCH 063/211] Fix syntax --- .github/workflows/maven.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 336c103d6..d18cad280 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -49,10 +49,10 @@ jobs: # SonarQube scan does not work for forked repositories # See https://jira.sonarsource.com/browse/MMF-1371 - name: Build with Maven - if: "github.ref != ‘refs/heads/master’" + if: github.ref != 'refs/heads/master' run: xvfb-run mvn clean verify - name: Build with Maven and run SonarQube analysis - if: "github.ref == ‘refs/heads/master’" + if: github.ref == 'refs/heads/master' run: xvfb-run mvn clean verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar env: # These two env variables are needed for sonar analysis From 54c0b1725c522666e7dbdcb973719cefb7a9daed Mon Sep 17 00:00:00 2001 From: amit1307 Date: Mon, 27 Jul 2020 14:50:32 +0100 Subject: [PATCH 064/211] Fix broken logging in service layer (#1342) --- service-layer/src/main/resources/logback.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/service-layer/src/main/resources/logback.xml b/service-layer/src/main/resources/logback.xml index 47fe42236..e6678aff2 100644 --- a/service-layer/src/main/resources/logback.xml +++ b/service-layer/src/main/resources/logback.xml @@ -43,6 +43,7 @@ + From b62bed7e433591af1585aa13ca8b7aecd1842e7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Mon, 27 Jul 2020 18:28:12 +0300 Subject: [PATCH 065/211] #590 explanation for Promise --- promise/README.md | 278 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 272 insertions(+), 6 deletions(-) diff --git a/promise/README.md b/promise/README.md index cf3d96c88..993d29a9f 100644 --- a/promise/README.md +++ b/promise/README.md @@ -9,18 +9,277 @@ tags: --- ## Also known as + CompletableFuture ## Intent -A Promise represents a proxy for a value not necessarily known when the promise is created. It -allows you to associate dependent promises to an asynchronous action's eventual success value or -failure reason. Promises are a way to write async code that still appears as though it is executing -in a synchronous way. + +A Promise represents a proxy for a value not necessarily known when the promise is created. It allows you to associate +dependent promises to an asynchronous action's eventual success value or failure reason. Promises are a way to write +async code that still appears as though it is executing in a synchronous way. + +## Explanation + +The Promise object is used for asynchronous computations. A Promise represents an operation that hasn't completed yet, +but is expected in the future. + +Promises provide a few advantages over callback objects: + * Functional composition and error handling + * Prevents callback hell and provides callback aggregation + +Real world example + +> We are developing a software solution that downloads files and calculates the number of lines and character +frequencies in those files. Promise is an ideal solution to make the code concise and easy to understand. + +In plain words + +> Promise is a placeholder for an asynchronous operation that is ongoing. + +Wikipedia says + +> In computer science, future, promise, delay, and deferred refer to constructs used for synchronizing program +execution in some concurrent programming languages. They describe an object that acts as a proxy for a result that is +initially unknown, usually because the computation of its value is not yet complete. + +**Programmatic Example** + +In the example a file is downloaded and its line count is calculated. The calculated line count is then consumed and +printed on console. + +Let's first introduce a support class we need for implementation. Here's `PromiseSupport`. + +```java +class PromiseSupport implements Future { + + private static final Logger LOGGER = LoggerFactory.getLogger(PromiseSupport.class); + + private static final int RUNNING = 1; + private static final int FAILED = 2; + private static final int COMPLETED = 3; + + private final Object lock; + + private volatile int state = RUNNING; + private T value; + private Exception exception; + + PromiseSupport() { + this.lock = new Object(); + } + + void fulfill(T value) { + this.value = value; + this.state = COMPLETED; + synchronized (lock) { + lock.notifyAll(); + } + } + + void fulfillExceptionally(Exception exception) { + this.exception = exception; + this.state = FAILED; + synchronized (lock) { + lock.notifyAll(); + } + } + + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + return false; + } + + @Override + public boolean isCancelled() { + return false; + } + + @Override + public boolean isDone() { + return state > RUNNING; + } + + @Override + public T get() throws InterruptedException, ExecutionException { + synchronized (lock) { + while (state == RUNNING) { + lock.wait(); + } + } + if (state == COMPLETED) { + return value; + } + throw new ExecutionException(exception); + } + + @Override + public T get(long timeout, TimeUnit unit) throws ExecutionException { + synchronized (lock) { + while (state == RUNNING) { + try { + lock.wait(unit.toMillis(timeout)); + } catch (InterruptedException e) { + LOGGER.warn("Interrupted!", e); + Thread.currentThread().interrupt(); + } + } + } + + if (state == COMPLETED) { + return value; + } + throw new ExecutionException(exception); + } +} +``` + +With `PromiseSupport` in place we can implement the actual `Promise`. + +```java +public class Promise extends PromiseSupport { + + private Runnable fulfillmentAction; + private Consumer exceptionHandler; + + public Promise() { + } + + @Override + public void fulfill(T value) { + super.fulfill(value); + postFulfillment(); + } + + @Override + public void fulfillExceptionally(Exception exception) { + super.fulfillExceptionally(exception); + handleException(exception); + postFulfillment(); + } + + private void handleException(Exception exception) { + if (exceptionHandler == null) { + return; + } + exceptionHandler.accept(exception); + } + + private void postFulfillment() { + if (fulfillmentAction == null) { + return; + } + fulfillmentAction.run(); + } + + public Promise fulfillInAsync(final Callable task, Executor executor) { + executor.execute(() -> { + try { + fulfill(task.call()); + } catch (Exception ex) { + fulfillExceptionally(ex); + } + }); + return this; + } + + public Promise thenAccept(Consumer action) { + var dest = new Promise(); + fulfillmentAction = new ConsumeAction(this, dest, action); + return dest; + } + + public Promise onError(Consumer exceptionHandler) { + this.exceptionHandler = exceptionHandler; + return this; + } + + public Promise thenApply(Function func) { + Promise dest = new Promise<>(); + fulfillmentAction = new TransformAction(this, dest, func); + return dest; + } + + private class ConsumeAction implements Runnable { + + private final Promise src; + private final Promise dest; + private final Consumer action; + + private ConsumeAction(Promise src, Promise dest, Consumer action) { + this.src = src; + this.dest = dest; + this.action = action; + } + + @Override + public void run() { + try { + action.accept(src.get()); + dest.fulfill(null); + } catch (Throwable throwable) { + dest.fulfillExceptionally((Exception) throwable.getCause()); + } + } + } + + private class TransformAction implements Runnable { + + private final Promise src; + private final Promise dest; + private final Function func; + + private TransformAction(Promise src, Promise dest, Function func) { + this.src = src; + this.dest = dest; + this.func = func; + } + + @Override + public void run() { + try { + dest.fulfill(func.apply(src.get())); + } catch (Throwable throwable) { + dest.fulfillExceptionally((Exception) throwable.getCause()); + } + } + } +} +``` + +Now we can show the full example in action. Here's how to download and count the number of lines in a file using +`Promise`. + +```java + countLines().thenAccept( + count -> { + LOGGER.info("Line count is: {}", count); + taskCompleted(); + } + ); + + private Promise countLines() { + return download(DEFAULT_URL).thenApply(Utility::countLines); + } + + private Promise download(String urlString) { + return new Promise() + .fulfillInAsync( + () -> Utility.downloadFile(urlString), executor) + .onError( + throwable -> { + throwable.printStackTrace(); + taskCompleted(); + } + ); + } +``` ## Class diagram + ![alt text](./etc/promise.png "Promise") ## Applicability + Promise pattern is applicable in concurrent programming when some work needs to be done asynchronously and: @@ -35,10 +294,17 @@ and: * [Guava ListenableFuture](https://github.com/google/guava/wiki/ListenableFutureExplained) ## Related Patterns - * Async Method Invocation - * Callback + + * [Async Method Invocation](https://java-design-patterns.com/patterns/async-method-invocation/) + * [Callback](https://java-design-patterns.com/patterns/callback/) + +## Tutorials + +* [Guide To CompletableFuture](https://www.baeldung.com/java-completablefuture) ## Credits * [You are missing the point to Promises](https://gist.github.com/domenic/3889970) * [Functional style callbacks using CompletableFuture](https://www.infoq.com/articles/Functional-Style-Callbacks-Using-CompletableFuture) +* [Java 8 in Action: Lambdas, Streams, and functional-style programming](https://www.amazon.com/gp/product/1617291994/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=1617291994&linkId=995af46887bb7b65e6c788a23eaf7146) +* [Modern Java in Action: Lambdas, streams, functional and reactive programming](https://www.amazon.com/gp/product/1617293563/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=1617293563&linkId=f70fe0d3e1efaff89554a6479c53759c) From ef4de30310fa46c95c562612c3863ddd1200db92 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 27 Jul 2020 20:59:08 +0300 Subject: [PATCH 066/211] docs: add iluwatar as a contributor (#1343) * docs: update README.md [skip ci] * docs: create .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 24 ++++++++++++++++++++++++ README.md | 22 ++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 .all-contributorsrc diff --git a/.all-contributorsrc b/.all-contributorsrc new file mode 100644 index 000000000..4e92d6568 --- /dev/null +++ b/.all-contributorsrc @@ -0,0 +1,24 @@ +{ + "files": [ + "README.md" + ], + "imageSize": 100, + "commit": false, + "contributors": [ + { + "login": "iluwatar", + "name": "Ilkka Seppälä", + "avatar_url": "https://avatars1.githubusercontent.com/u/582346?v=4", + "profile": "https://github.com/iluwatar", + "contributions": [ + "code" + ] + } + ], + "contributorsPerLine": 7, + "projectName": "java-design-patterns", + "projectOwner": "iluwatar", + "repoType": "github", + "repoHost": "https://github.com", + "skipCi": true +} diff --git a/README.md b/README.md index 2eabb5e82..533eec47e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,7 @@ +[![All Contributors](https://img.shields.io/badge/all_contributors-1-orange.svg?style=flat-square)](#contributors-) + that smart and dearly wants an empty line before a heading to be able to display it as such, e.g. website) --> @@ -58,3 +61,22 @@ you and answer your questions in the [Gitter chatroom](https://gitter.im/iluwata # License This project is licensed under the terms of the MIT license. + +## Contributors ✨ + +Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)): + + + + + + + + +

Ilkka Seppälä

💻
+ + + + + +This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! \ No newline at end of file From 93c11fdf233e19f75b8a39afa7e7dbd8c2d87157 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Mon, 27 Jul 2020 21:01:48 +0300 Subject: [PATCH 067/211] Update README.md --- README.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 533eec47e..d7148dde7 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,4 @@ -[![All Contributors](https://img.shields.io/badge/all_contributors-1-orange.svg?style=flat-square)](#contributors-) - that smart and dearly wants an empty line before a heading to be able to display it as such, e.g. website) --> @@ -11,6 +8,9 @@ [![License MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/iluwatar/java-design-patterns/master/LICENSE.md) [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) + +[![All Contributors](https://img.shields.io/badge/all_contributors-1-orange.svg?style=flat-square)](#contributors-) + # Introduction @@ -62,9 +62,7 @@ you and answer your questions in the [Gitter chatroom](https://gitter.im/iluwata This project is licensed under the terms of the MIT license. -## Contributors ✨ - -Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)): +# Contributors @@ -79,4 +77,4 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d -This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! \ No newline at end of file +This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! From b7d122f6146c3ae36750a9eaef0083649749800d Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 27 Jul 2020 21:13:13 +0300 Subject: [PATCH 068/211] docs: add iluwatar as a contributor (#1344) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: create .all-contributorsrc [skip ci] * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 3 ++- README.md | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 4e92d6568..80d7f54b4 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -11,7 +11,8 @@ "avatar_url": "https://avatars1.githubusercontent.com/u/582346?v=4", "profile": "https://github.com/iluwatar", "contributions": [ - "code" + "code", + "projectManagement" ] } ], diff --git a/README.md b/README.md index d7148dde7..55f11e702 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ This project is licensed under the terms of the MIT license. - +

Ilkka Seppälä

💻

Ilkka Seppälä

💻 📆
From ae7a0b8a4a331ccf96d6dbd956c4fd1c541888ed Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 27 Jul 2020 21:17:52 +0300 Subject: [PATCH 069/211] docs: add amit1307 as a contributor (#1345) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 80d7f54b4..d919371f1 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -14,6 +14,15 @@ "code", "projectManagement" ] + }, + { + "login": "amit1307", + "name": "amit1307", + "avatar_url": "https://avatars0.githubusercontent.com/u/23420222?v=4", + "profile": "https://github.com/amit1307", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 55f11e702..04ddf6372 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-1-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-2-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -70,6 +70,7 @@ This project is licensed under the terms of the MIT license. +

Ilkka Seppälä

💻 📆

amit1307

💻
From 76f634ff7a10f4a9f1840680938318bd02af2738 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 27 Jul 2020 21:50:31 +0300 Subject: [PATCH 070/211] docs: add iluwatar as a contributor (#1346) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: create .all-contributorsrc [skip ci] * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 8 ++++++++ README.md | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index d919371f1..dbf65aeb8 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -12,6 +12,14 @@ "profile": "https://github.com/iluwatar", "contributions": [ "code", + "projectManagement", + "maintenance", + "blog", + "content", + "doc", + "ideas", + "infra", + "review" "projectManagement" ] }, diff --git a/README.md b/README.md index 04ddf6372..279f02028 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ This project is licensed under the terms of the MIT license. - +

Ilkka Seppälä

💻 📆

Ilkka Seppälä

💻 📆 🚧 📝 🖋 📖 🤔 🚇 👀

amit1307

💻
From 02b6aba6ae25aae1c23823c0b458782d859f1e04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Mon, 27 Jul 2020 22:38:07 +0300 Subject: [PATCH 071/211] fix config syntax --- .all-contributorsrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index dbf65aeb8..9c7f063a7 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -19,7 +19,7 @@ "doc", "ideas", "infra", - "review" + "review", "projectManagement" ] }, From 211d7903ae480e05cef03795779a00115050b216 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 27 Jul 2020 22:40:20 +0300 Subject: [PATCH 072/211] docs: add npathai as a contributor (#1347) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 13 +++++++++++++ README.md | 5 +++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 9c7f063a7..90490c998 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -31,6 +31,19 @@ "contributions": [ "code" ] + }, + { + "login": "npathai", + "name": "Narendra Pathai", + "avatar_url": "https://avatars2.githubusercontent.com/u/1792515?v=4", + "profile": "https://github.com/npathai", + "contributions": [ + "code", + "ideas", + "maintenance", + "question", + "review" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 279f02028..bce11a908 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-2-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-3-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -69,8 +69,9 @@ This project is licensed under the terms of the MIT license. - + +

Ilkka Seppälä

💻 📆 🚧 📝 🖋 📖 🤔 🚇 👀

Ilkka Seppälä

💻 📆 🚧 📝 🖋 📖 🤔 🚇 👀 📆

amit1307

💻

Narendra Pathai

💻 🤔 🚧 💬 👀
From aea90ab115039ac008194e2743b365f2e2da3df4 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 27 Jul 2020 22:48:15 +0300 Subject: [PATCH 073/211] docs: add fluxw42 as a contributor (#1348) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 90490c998..25335e77a 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -44,6 +44,15 @@ "question", "review" ] + }, + { + "login": "fluxw42", + "name": "Jeroen Meulemeester", + "avatar_url": "https://avatars1.githubusercontent.com/u/1545460?v=4", + "profile": "https://github.com/fluxw42", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index bce11a908..7525ddb43 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-3-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-4-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -72,6 +72,7 @@ This project is licensed under the terms of the MIT license.

Ilkka Seppälä

💻 📆 🚧 📝 🖋 📖 🤔 🚇 👀 📆
amit1307

💻
Narendra Pathai

💻 🤔 🚧 💬 👀 +
Jeroen Meulemeester

💻 From 2c8535e839223a445220bef981b5591da12e4c4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Mon, 27 Jul 2020 23:07:58 +0300 Subject: [PATCH 074/211] max 3 contribution types per person --- .all-contributorsrc | 11 +---------- README.md | 4 ++-- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 25335e77a..8e44fd9e2 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -11,16 +11,9 @@ "avatar_url": "https://avatars1.githubusercontent.com/u/582346?v=4", "profile": "https://github.com/iluwatar", "contributions": [ - "code", "projectManagement", "maintenance", - "blog", - "content", - "doc", - "ideas", - "infra", - "review", - "projectManagement" + "content" ] }, { @@ -40,8 +33,6 @@ "contributions": [ "code", "ideas", - "maintenance", - "question", "review" ] }, diff --git a/README.md b/README.md index 7525ddb43..ba9fd307e 100644 --- a/README.md +++ b/README.md @@ -69,9 +69,9 @@ This project is licensed under the terms of the MIT license. - + - +

Ilkka Seppälä

💻 📆 🚧 📝 🖋 📖 🤔 🚇 👀 📆

Ilkka Seppälä

📆 🚧 🖋

amit1307

💻

Narendra Pathai

💻 🤔 🚧 💬 👀

Narendra Pathai

💻 🤔 👀

Jeroen Meulemeester

💻
From 05dfd31fb7e55e185499f7fa3a2944b2690853c9 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 27 Jul 2020 23:14:34 +0300 Subject: [PATCH 075/211] docs: add mikulucky as a contributor (#1349) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 5 +++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 8e44fd9e2..cecc9e2dc 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -44,6 +44,15 @@ "contributions": [ "code" ] + }, + { + "login": "mikulucky", + "name": "Joseph McCarthy", + "avatar_url": "https://avatars0.githubusercontent.com/u/4526195?v=4", + "profile": "http://www.joemccarthy.co.uk", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index ba9fd307e..743017959 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-4-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-5-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -69,10 +69,11 @@ This project is licensed under the terms of the MIT license. - + +

Ilkka Seppälä

📆 🚧 🖋

Ilkka Seppälä

📆 🚧 🖋

amit1307

💻

Narendra Pathai

💻 🤔 👀

Jeroen Meulemeester

💻

Joseph McCarthy

💻
From 64eff5eb93da95bf55ce48222d1f41200424e785 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 27 Jul 2020 23:18:02 +0300 Subject: [PATCH 076/211] docs: add thomasoss as a contributor (#1350) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index cecc9e2dc..68751f4a7 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -53,6 +53,15 @@ "contributions": [ "code" ] + }, + { + "login": "thomasoss", + "name": "Thomas", + "avatar_url": "https://avatars1.githubusercontent.com/u/22516154?v=4", + "profile": "https://github.com/thomasoss", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 743017959..08f10e096 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-5-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-6-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -74,6 +74,7 @@ This project is licensed under the terms of the MIT license.
Narendra Pathai

💻 🤔 👀
Jeroen Meulemeester

💻
Joseph McCarthy

💻 +
Thomas

💻 From 09dd0bee30519c7b4e0539744b2cb7a2f222fe97 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 27 Jul 2020 23:20:44 +0300 Subject: [PATCH 077/211] docs: add anuragagarwal561994 as a contributor (#1351) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 68751f4a7..a3ed0c8f2 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -62,6 +62,15 @@ "contributions": [ "code" ] + }, + { + "login": "anuragagarwal561994", + "name": "Anurag Agarwal", + "avatar_url": "https://avatars1.githubusercontent.com/u/6075379?v=4", + "profile": "https://github.com/anuragagarwal561994", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 08f10e096..d8231ef7e 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-6-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-7-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -75,6 +75,7 @@ This project is licensed under the terms of the MIT license.
Jeroen Meulemeester

💻
Joseph McCarthy

💻
Thomas

💻 +
Anurag Agarwal

💻 From d609f3eec69488e021b3bd34c9c08114b11f9c95 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 17:26:03 +0300 Subject: [PATCH 078/211] docs: add markusmo3 as a contributor (#1352) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 11 +++++++++++ README.md | 5 ++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index a3ed0c8f2..4fda28295 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -71,6 +71,17 @@ "contributions": [ "code" ] + }, + { + "login": "markusmo3", + "name": "Markus Moser", + "avatar_url": "https://avatars1.githubusercontent.com/u/3317416?v=4", + "profile": "https://markusmo3.github.io", + "contributions": [ + "design", + "code", + "ideas" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index d8231ef7e..d8f9f5e7a 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-7-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-8-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -77,6 +77,9 @@ This project is licensed under the terms of the MIT license.
Thomas

💻
Anurag Agarwal

💻 + +
Markus Moser

🎨 💻 🤔 + From b3eb6ccea424c54bf7cfab8c2ac36b8c467dd53e Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 17:28:35 +0300 Subject: [PATCH 079/211] docs: add isabiq as a contributor (#1353) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 4fda28295..113d84373 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -82,6 +82,15 @@ "code", "ideas" ] + }, + { + "login": "isabiq", + "name": "Sabiq Ihab", + "avatar_url": "https://avatars1.githubusercontent.com/u/19510920?v=4", + "profile": "https://twitter.com/i_sabiq", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index d8f9f5e7a..c3aa4249e 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-8-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-9-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -79,6 +79,7 @@ This project is licensed under the terms of the MIT license.
Markus Moser

🎨 💻 🤔 +
Sabiq Ihab

💻 From 960adfc37a3fd30bdf33f2c75256c79e8ce1d7ca Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 17:30:42 +0300 Subject: [PATCH 080/211] docs: add inbravo as a contributor (#1354) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 113d84373..8bcf19fb5 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -91,6 +91,15 @@ "contributions": [ "code" ] + }, + { + "login": "inbravo", + "name": "Amit Dixit", + "avatar_url": "https://avatars3.githubusercontent.com/u/5253764?v=4", + "profile": "http://inbravo.github.io", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index c3aa4249e..4dee660b8 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-9-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-10-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -80,6 +80,7 @@ This project is licensed under the terms of the MIT license.
Markus Moser

🎨 💻 🤔
Sabiq Ihab

💻 +
Amit Dixit

💻 From 781a7c8b52af7ff3edde4bb89ceb4456ed3b897c Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 17:32:58 +0300 Subject: [PATCH 081/211] docs: add piyushchaudhari04 as a contributor (#1355) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 8bcf19fb5..1b3b280e2 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -100,6 +100,15 @@ "contributions": [ "code" ] + }, + { + "login": "piyushchaudhari04", + "name": "Piyush Kailash Chaudhari", + "avatar_url": "https://avatars3.githubusercontent.com/u/10268029?v=4", + "profile": "https://github.com/piyushchaudhari04", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 4dee660b8..4f5c8b5b7 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-10-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-11-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -81,6 +81,7 @@ This project is licensed under the terms of the MIT license.
Markus Moser

🎨 💻 🤔
Sabiq Ihab

💻
Amit Dixit

💻 +
Piyush Kailash Chaudhari

💻 From d6edeee326d03e8d85a246889afb6ef41e3f5d50 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 17:35:49 +0300 Subject: [PATCH 082/211] docs: add joshzambales as a contributor (#1356) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 1b3b280e2..bd011b233 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -109,6 +109,15 @@ "contributions": [ "code" ] + }, + { + "login": "joshzambales", + "name": "joshzambales", + "avatar_url": "https://avatars1.githubusercontent.com/u/8704552?v=4", + "profile": "https://github.com/joshzambales", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 4f5c8b5b7..5c559363f 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-11-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-12-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -82,6 +82,7 @@ This project is licensed under the terms of the MIT license.
Sabiq Ihab

💻
Amit Dixit

💻
Piyush Kailash Chaudhari

💻 +
joshzambales

💻 From 1cb9c2bcde9c8a1c32e453bf4ab273b25b878e97 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 17:37:56 +0300 Subject: [PATCH 083/211] docs: add Crossy147 as a contributor (#1357) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index bd011b233..fdd99c31c 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -118,6 +118,15 @@ "contributions": [ "code" ] + }, + { + "login": "Crossy147", + "name": "Kamil Pietruszka", + "avatar_url": "https://avatars2.githubusercontent.com/u/7272996?v=4", + "profile": "https://github.com/Crossy147", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 5c559363f..d21e9a476 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-12-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-13-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -83,6 +83,7 @@ This project is licensed under the terms of the MIT license.
Amit Dixit

💻
Piyush Kailash Chaudhari

💻
joshzambales

💻 +
Kamil Pietruszka

💻 From 8ba111fe60ffe21d6155cc98c82a7907814ba752 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 17:40:28 +0300 Subject: [PATCH 084/211] docs: add zafarella as a contributor (#1358) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 10 ++++++++++ README.md | 3 ++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index fdd99c31c..eb77506ca 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -127,6 +127,16 @@ "contributions": [ "code" ] + }, + { + "login": "zafarella", + "name": "Zafar Khaydarov", + "avatar_url": "https://avatars2.githubusercontent.com/u/660742?v=4", + "profile": "http://cs.joensuu.fi/~zkhayda", + "contributions": [ + "code", + "doc" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index d21e9a476..cee9e18bc 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-13-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-14-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -84,6 +84,7 @@ This project is licensed under the terms of the MIT license.
Piyush Kailash Chaudhari

💻
joshzambales

💻
Kamil Pietruszka

💻 +
Zafar Khaydarov

💻 📖 From 80605283f55a0abe33b01f4d337304d0107b64e2 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 17:42:27 +0300 Subject: [PATCH 085/211] docs: add kemitix as a contributor (#1359) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 5 ++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index eb77506ca..387c34849 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -137,6 +137,15 @@ "code", "doc" ] + }, + { + "login": "kemitix", + "name": "Paul Campbell", + "avatar_url": "https://avatars1.githubusercontent.com/u/1147749?v=4", + "profile": "https://kemitix.github.io/", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index cee9e18bc..95d2724e6 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-14-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-15-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -86,6 +86,9 @@ This project is licensed under the terms of the MIT license.
Kamil Pietruszka

💻
Zafar Khaydarov

💻 📖 + +
Paul Campbell

💻 + From cf8e366e2518af8354f1879d3caf690ff0b93194 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 17:44:46 +0300 Subject: [PATCH 086/211] docs: add Argyro-Sioziou as a contributor (#1360) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 387c34849..a07d447af 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -146,6 +146,15 @@ "contributions": [ "code" ] + }, + { + "login": "Argyro-Sioziou", + "name": "Argyro Sioziou", + "avatar_url": "https://avatars0.githubusercontent.com/u/22822639?v=4", + "profile": "https://github.com/Argyro-Sioziou", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 95d2724e6..d1ca6e8bc 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-15-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-16-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -88,6 +88,7 @@ This project is licensed under the terms of the MIT license.
Paul Campbell

💻 +
Argyro Sioziou

💻 From a77e9620b5274321e1753de42c3945d14b2bc2fd Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 17:46:41 +0300 Subject: [PATCH 087/211] docs: add TylerMcConville as a contributor (#1361) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index a07d447af..eb1b24798 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -155,6 +155,15 @@ "contributions": [ "code" ] + }, + { + "login": "TylerMcConville", + "name": "TylerMcConville", + "avatar_url": "https://avatars0.githubusercontent.com/u/4946449?v=4", + "profile": "https://github.com/TylerMcConville", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index d1ca6e8bc..b73859360 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-16-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-17-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -89,6 +89,7 @@ This project is licensed under the terms of the MIT license.
Paul Campbell

💻
Argyro Sioziou

💻 +
TylerMcConville

💻 From f360b64877fb459666c597fc0985408c49481af7 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 17:48:50 +0300 Subject: [PATCH 088/211] docs: add saksham93 as a contributor (#1362) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index eb1b24798..81e67d559 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -164,6 +164,15 @@ "contributions": [ "code" ] + }, + { + "login": "saksham93", + "name": "saksham93", + "avatar_url": "https://avatars1.githubusercontent.com/u/37399540?v=4", + "profile": "https://github.com/saksham93", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index b73859360..833d65eae 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-17-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-18-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -90,6 +90,7 @@ This project is licensed under the terms of the MIT license.
Paul Campbell

💻
Argyro Sioziou

💻
TylerMcConville

💻 +
saksham93

💻 From c85d764e397029aedd3148a8338fabebf2956f88 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 17:50:39 +0300 Subject: [PATCH 089/211] docs: add nikhilbarar as a contributor (#1363) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 81e67d559..61f88d89a 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -173,6 +173,15 @@ "contributions": [ "code" ] + }, + { + "login": "nikhilbarar", + "name": "nikhilbarar", + "avatar_url": "https://avatars2.githubusercontent.com/u/37332144?v=4", + "profile": "https://github.com/nikhilbarar", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 833d65eae..ccfa6e4ff 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-18-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-19-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -91,6 +91,7 @@ This project is licensed under the terms of the MIT license.
Argyro Sioziou

💻
TylerMcConville

💻
saksham93

💻 +
nikhilbarar

💻 From 4c766b9e71fe927e2fd39003d7f44c2a70c7b024 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 17:52:39 +0300 Subject: [PATCH 090/211] docs: add colinbut as a contributor (#1364) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 61f88d89a..c90df750f 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -182,6 +182,15 @@ "contributions": [ "code" ] + }, + { + "login": "colinbut", + "name": "Colin But", + "avatar_url": "https://avatars2.githubusercontent.com/u/10725674?v=4", + "profile": "http://colinbut.com", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index ccfa6e4ff..5fa2d303e 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-19-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-20-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -92,6 +92,7 @@ This project is licensed under the terms of the MIT license.
TylerMcConville

💻
saksham93

💻
nikhilbarar

💻 +
Colin But

💻 From d8f12529f2703845cd58c253ba7886c379ec9630 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 17:55:47 +0300 Subject: [PATCH 091/211] docs: add ruslanpa as a contributor (#1365) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index c90df750f..28abe71da 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -191,6 +191,15 @@ "contributions": [ "code" ] + }, + { + "login": "ruslanpa", + "name": "Ruslan", + "avatar_url": "https://avatars2.githubusercontent.com/u/1503411?v=4", + "profile": "https://github.com/ruslanpa", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 5fa2d303e..559f2a69c 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-20-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-21-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -93,6 +93,7 @@ This project is licensed under the terms of the MIT license.
saksham93

💻
nikhilbarar

💻
Colin But

💻 +
Ruslan

💻 From 97adc13a1bcf09bf45d4a1a37b1384caa1de9b7a Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 17:57:26 +0300 Subject: [PATCH 092/211] docs: add JuhoKang as a contributor (#1366) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 5 ++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 28abe71da..d532a2baf 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -200,6 +200,15 @@ "contributions": [ "code" ] + }, + { + "login": "JuhoKang", + "name": "Juho Kang", + "avatar_url": "https://avatars1.githubusercontent.com/u/4745294?v=4", + "profile": "https://github.com/JuhoKang", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 559f2a69c..eab98e6c0 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-21-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-22-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -95,6 +95,9 @@ This project is licensed under the terms of the MIT license.
Colin But

💻
Ruslan

💻 + +
Juho Kang

💻 + From a5ff32c13ea3d66794bda314bc542a93eafa08aa Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 18:02:49 +0300 Subject: [PATCH 093/211] docs: add dheeraj-mummareddy as a contributor (#1367) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index d532a2baf..5f5df0ed5 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -209,6 +209,15 @@ "contributions": [ "code" ] + }, + { + "login": "dheeraj-mummareddy", + "name": "Dheeraj Mummareddy", + "avatar_url": "https://avatars2.githubusercontent.com/u/7002230?v=4", + "profile": "https://github.com/dheeraj-mummareddy", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index eab98e6c0..912cc1b25 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-22-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-23-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -97,6 +97,7 @@ This project is licensed under the terms of the MIT license.
Juho Kang

💻 +
Dheeraj Mummareddy

💻 From 0563ac7645484ea12382d1c7240873c7607dbbc9 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 18:08:01 +0300 Subject: [PATCH 094/211] docs: add bernardosulzbach as a contributor (#1368) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 5f5df0ed5..512859f34 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -218,6 +218,15 @@ "contributions": [ "code" ] + }, + { + "login": "bernardosulzbach", + "name": "Bernardo Sulzbach", + "avatar_url": "https://avatars0.githubusercontent.com/u/8271090?v=4", + "profile": "https://www.bernardosulzbach.com", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 912cc1b25..bb324ec26 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-23-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-24-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -98,6 +98,7 @@ This project is licensed under the terms of the MIT license.
Juho Kang

💻
Dheeraj Mummareddy

💻 +
Bernardo Sulzbach

💻 From 5b269d5af1e7dd3eaf7b0e9e5b4363faedbb5abd Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 18:09:43 +0300 Subject: [PATCH 095/211] docs: add 4lexis as a contributor (#1369) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 512859f34..3d129d1a1 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -227,6 +227,15 @@ "contributions": [ "code" ] + }, + { + "login": "4lexis", + "name": "Aleksandar Dudukovic", + "avatar_url": "https://avatars0.githubusercontent.com/u/19871727?v=4", + "profile": "https://github.com/4lexis", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index bb324ec26..8da13c04e 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-24-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-25-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -99,6 +99,7 @@ This project is licensed under the terms of the MIT license.
Juho Kang

💻
Dheeraj Mummareddy

💻
Bernardo Sulzbach

💻 +
Aleksandar Dudukovic

💻 From 03ebd5f353edcb6becfc0e6c1ca1944e131c689d Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 18:11:29 +0300 Subject: [PATCH 096/211] docs: add yusufaytas as a contributor (#1370) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 3d129d1a1..2d1a8c2ab 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -236,6 +236,15 @@ "contributions": [ "code" ] + }, + { + "login": "yusufaytas", + "name": "Yusuf Aytaş", + "avatar_url": "https://avatars2.githubusercontent.com/u/1049483?v=4", + "profile": "https://www.yusufaytas.com", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 8da13c04e..d3485ec5c 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-25-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-26-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -100,6 +100,7 @@ This project is licensed under the terms of the MIT license.
Dheeraj Mummareddy

💻
Bernardo Sulzbach

💻
Aleksandar Dudukovic

💻 +
Yusuf Aytaş

💻 From 2706c8fc37037d7a5fa7bca319038112d3addc3b Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 18:13:03 +0300 Subject: [PATCH 097/211] docs: add qpi as a contributor (#1371) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 2d1a8c2ab..d51e82608 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -245,6 +245,15 @@ "contributions": [ "code" ] + }, + { + "login": "qpi", + "name": "Mihály Kuprivecz", + "avatar_url": "https://avatars2.githubusercontent.com/u/1001491?v=4", + "profile": "http://futurehomes.hu", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index d3485ec5c..2646704d8 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-26-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-27-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -101,6 +101,7 @@ This project is licensed under the terms of the MIT license.
Bernardo Sulzbach

💻
Aleksandar Dudukovic

💻
Yusuf Aytaş

💻 +
Mihály Kuprivecz

💻 From 452981669b5b95a0b3c78453a456eaf22f4cc2e7 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 18:14:37 +0300 Subject: [PATCH 098/211] docs: add kapinuss as a contributor (#1372) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index d51e82608..42d3fd6ce 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -254,6 +254,15 @@ "contributions": [ "code" ] + }, + { + "login": "kapinuss", + "name": "Stanislav Kapinus", + "avatar_url": "https://avatars0.githubusercontent.com/u/17639945?v=4", + "profile": "https://github.com/kapinuss", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 2646704d8..b8ea48ef0 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-27-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-28-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -102,6 +102,7 @@ This project is licensed under the terms of the MIT license.
Aleksandar Dudukovic

💻
Yusuf Aytaş

💻
Mihály Kuprivecz

💻 +
Stanislav Kapinus

💻 From 0cff538c271ffdae6eb6adadc9ac4fde7f7fe2fc Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 18:16:14 +0300 Subject: [PATCH 099/211] docs: add gvsharma as a contributor (#1373) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 5 ++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 42d3fd6ce..ceefb272f 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -263,6 +263,15 @@ "contributions": [ "code" ] + }, + { + "login": "gvsharma", + "name": "GVSharma", + "avatar_url": "https://avatars1.githubusercontent.com/u/6648152?v=4", + "profile": "https://github.com/gvsharma", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index b8ea48ef0..3ec2bcbab 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-28-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-29-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -104,6 +104,9 @@ This project is licensed under the terms of the MIT license.
Mihály Kuprivecz

💻
Stanislav Kapinus

💻 + +
GVSharma

💻 + From b805a7526eb7b741933a041992f0b610b50d0390 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 18:17:42 +0300 Subject: [PATCH 100/211] docs: add SrdjanPaunovic as a contributor (#1374) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index ceefb272f..7c71a2167 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -272,6 +272,15 @@ "contributions": [ "code" ] + }, + { + "login": "SrdjanPaunovic", + "name": "Srđan Paunović", + "avatar_url": "https://avatars1.githubusercontent.com/u/22815104?v=4", + "profile": "https://github.com/SrdjanPaunovic", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 3ec2bcbab..514df2349 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-29-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-30-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -106,6 +106,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻 +
Srđan Paunović

💻 From d94199f5fff6cf83604d3aaa8b2b130315e2f5a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Tue, 28 Jul 2020 18:23:47 +0300 Subject: [PATCH 101/211] update readme --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 514df2349..eafae6ef5 100644 --- a/README.md +++ b/README.md @@ -113,5 +113,3 @@ This project is licensed under the terms of the MIT license. - -This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! From 0bc3756250ef110a1c6adfd910cc1ecf0ededefd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Tue, 28 Jul 2020 18:49:46 +0300 Subject: [PATCH 102/211] update all-contributors config --- .all-contributorsrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 7c71a2167..bdd7dfdaa 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -283,7 +283,7 @@ ] } ], - "contributorsPerLine": 7, + "contributorsPerLine": 4, "projectName": "java-design-patterns", "projectOwner": "iluwatar", "repoType": "github", From 96344142e9064e5afd08c3c8450b38419ca3528b Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 18:52:31 +0300 Subject: [PATCH 103/211] docs: add sideris as a contributor (#1375) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 17 ++++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index bdd7dfdaa..1d6b1aabc 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -281,6 +281,15 @@ "contributions": [ "code" ] + }, + { + "login": "sideris", + "name": "Petros G. Sideris", + "avatar_url": "https://avatars3.githubusercontent.com/u/5484694?v=4", + "profile": "https://sideris.xyz/", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 4, diff --git a/README.md b/README.md index eafae6ef5..55e167ef8 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-30-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-31-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -73,32 +73,38 @@ This project is licensed under the terms of the MIT license.
amit1307

💻
Narendra Pathai

💻 🤔 👀
Jeroen Meulemeester

💻 + +
Joseph McCarthy

💻
Thomas

💻
Anurag Agarwal

💻 +
Markus Moser

🎨 💻 🤔 -
Markus Moser

🎨 💻 🤔
Sabiq Ihab

💻
Amit Dixit

💻
Piyush Kailash Chaudhari

💻
joshzambales

💻 -
Kamil Pietruszka

💻 -
Zafar Khaydarov

💻 📖 +
Kamil Pietruszka

💻 +
Zafar Khaydarov

💻 📖
Paul Campbell

💻
Argyro Sioziou

💻 + +
TylerMcConville

💻
saksham93

💻
nikhilbarar

💻
Colin But

💻 -
Ruslan

💻 +
Ruslan

💻
Juho Kang

💻
Dheeraj Mummareddy

💻
Bernardo Sulzbach

💻 + +
Aleksandar Dudukovic

💻
Yusuf Aytaş

💻
Mihály Kuprivecz

💻 @@ -107,6 +113,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻 +
Petros G. Sideris

💻 From c0d2c7fdb04a239488db9457197d095173fc1b79 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 20:23:30 +0300 Subject: [PATCH 104/211] docs: add robertt240 as a contributor (#1376) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 1d6b1aabc..f5238558b 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -290,6 +290,15 @@ "contributions": [ "code" ] + }, + { + "login": "robertt240", + "name": "Robert Kasperczyk", + "avatar_url": "https://avatars1.githubusercontent.com/u/9137432?v=4", + "profile": "https://github.com/robertt240", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 4, diff --git a/README.md b/README.md index 55e167ef8..026ba94e3 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-31-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-32-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -114,6 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 +
Robert Kasperczyk

💻 From cfba28f9a4a0017d22506a7655e97c648413a79b Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 20:33:05 +0300 Subject: [PATCH 105/211] docs: add okinskas as a contributor (#1377) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index f5238558b..9780bbbf8 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "okinskas", + "name": "Ovidijus Okinskas", + "avatar_url": "https://avatars0.githubusercontent.com/u/20372387?v=4", + "profile": "https://www.linkedin.com/in/ovidijus-okinskas/", + "contributions": [ + "code" + ] + }, { "login": "robertt240", "name": "Robert Kasperczyk", diff --git a/README.md b/README.md index 026ba94e3..4e931dca2 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 +
Ovidijus Okinskas

💻
Robert Kasperczyk

💻 From 2b095bec283932368a7111463ae0082836c0afdf Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 20:37:11 +0300 Subject: [PATCH 106/211] docs: add ankurkaushal as a contributor (#1378) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 9780bbbf8..724d5e0d7 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "ankurkaushal", + "name": "Ankur Kaushal", + "avatar_url": "https://avatars2.githubusercontent.com/u/2236616?v=4", + "profile": "https://github.com/ankurkaushal", + "contributions": [ + "code" + ] + }, { "login": "okinskas", "name": "Ovidijus Okinskas", diff --git a/README.md b/README.md index 4e931dca2..7e71b1e62 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 +
Ankur Kaushal

💻
Ovidijus Okinskas

💻
Robert Kasperczyk

💻 From f85e4db0bed8b96864375028d90ee31bf05f9ccc Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 20:40:11 +0300 Subject: [PATCH 107/211] docs: add Tschis as a contributor (#1379) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 724d5e0d7..cfc3cdfc5 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "Tschis", + "name": "Rodolfo Forte", + "avatar_url": "https://avatars1.githubusercontent.com/u/20662669?v=4", + "profile": "http://tschis.github.io", + "contributions": [ + "content" + ] + }, { "login": "ankurkaushal", "name": "Ankur Kaushal", diff --git a/README.md b/README.md index 7e71b1e62..506948ca9 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 +
Rodolfo Forte

🖋
Ankur Kaushal

💻
Ovidijus Okinskas

💻
Robert Kasperczyk

💻 From 60ab9fa3ceb61e63acf8267507a502a8433ded70 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 20:43:09 +0300 Subject: [PATCH 108/211] docs: add qza as a contributor (#1380) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index cfc3cdfc5..9b817c42d 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "qza", + "name": "qza", + "avatar_url": "https://avatars3.githubusercontent.com/u/233149?v=4", + "profile": "https://github.com/qza", + "contributions": [ + "code" + ] + }, { "login": "Tschis", "name": "Rodolfo Forte", diff --git a/README.md b/README.md index 506948ca9..ad0a2fa5d 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 +
qza

💻
Rodolfo Forte

🖋
Ankur Kaushal

💻
Ovidijus Okinskas

💻 From 023865ad4c5b63f85bf1b6d001636543ff354f0e Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 20:45:59 +0300 Subject: [PATCH 109/211] docs: add pitsios-s as a contributor (#1381) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 9b817c42d..df2e3e857 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "pitsios-s", + "name": "Stamatis Pitsios", + "avatar_url": "https://avatars1.githubusercontent.com/u/6773603?v=4", + "profile": "https://twitter.com/StPitsios", + "contributions": [ + "code" + ] + }, { "login": "qza", "name": "qza", diff --git a/README.md b/README.md index ad0a2fa5d..94615bf9c 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 +
Stamatis Pitsios

💻
qza

💻
Rodolfo Forte

🖋
Ankur Kaushal

💻 From 0358fcec4c1f35c84d631e214c81bb6b96e2c74b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Tue, 28 Jul 2020 20:53:31 +0300 Subject: [PATCH 110/211] update readme --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 94615bf9c..97e3111cf 100644 --- a/README.md +++ b/README.md @@ -115,10 +115,14 @@ This project is licensed under the terms of the MIT license.
Srđan Paunović

💻
Petros G. Sideris

💻
Stamatis Pitsios

💻 + +
qza

💻
Rodolfo Forte

🖋
Ankur Kaushal

💻
Ovidijus Okinskas

💻 + +
Robert Kasperczyk

💻 From eb8ddde98ffd9d63dce24ddd8f76a00649520889 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 17:36:32 +0300 Subject: [PATCH 111/211] docs: add llitfkitfk as a contributor (#1382) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index df2e3e857..3d7e4065e 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "llitfkitfk", + "name": "田浩", + "avatar_url": "https://avatars1.githubusercontent.com/u/2404785?v=4", + "profile": "https://t.me/paul_docker", + "contributions": [ + "content" + ] + }, { "login": "pitsios-s", "name": "Stamatis Pitsios", diff --git a/README.md b/README.md index 97e3111cf..79f9b34ff 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 -
Stamatis Pitsios

💻 +
田浩

🖋
qza

💻 @@ -123,6 +123,7 @@ This project is licensed under the terms of the MIT license.
Ovidijus Okinskas

💻 +
Stamatis Pitsios

💻
Robert Kasperczyk

💻 From 8d6791490b63dbbfab8c093378c730eeee805bcd Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 17:39:11 +0300 Subject: [PATCH 112/211] docs: add gwildor28 as a contributor (#1383) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 3d7e4065e..f37d603e5 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "gwildor28", + "name": "gwildor28", + "avatar_url": "https://avatars0.githubusercontent.com/u/16000365?v=4", + "profile": "https://github.com/gwildor28", + "contributions": [ + "content" + ] + }, { "login": "llitfkitfk", "name": "田浩", diff --git a/README.md b/README.md index 79f9b34ff..104d7afa2 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 -
田浩

🖋 +
gwildor28

💻
qza

💻 @@ -125,6 +125,7 @@ This project is licensed under the terms of the MIT license.
Stamatis Pitsios

💻
Robert Kasperczyk

💻 +
田浩

🖋 From 39e5436ed5ed13c1ff81487a08cd5b2d30eca0a5 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 17:41:35 +0300 Subject: [PATCH 113/211] docs: add amit2103 as a contributor (#1384) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index f37d603e5..c9c27ed6b 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "amit2103", + "name": "Amit Pandey", + "avatar_url": "https://avatars3.githubusercontent.com/u/7566692?v=4", + "profile": "https://github.com/amit2103", + "contributions": [ + "code" + ] + }, { "login": "gwildor28", "name": "gwildor28", diff --git a/README.md b/README.md index 104d7afa2..1417b68d3 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 -
gwildor28

💻 +
Amit Pandey

💻
qza

💻 @@ -126,6 +126,7 @@ This project is licensed under the terms of the MIT license.
Stamatis Pitsios

💻
Robert Kasperczyk

💻
田浩

🖋 +
gwildor28

💻 From 81824057968557335d4812093ddc70ec7c12e73c Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 17:44:05 +0300 Subject: [PATCH 114/211] docs: add hoswey as a contributor (#1385) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 5 ++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index c9c27ed6b..ef533e802 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "hoswey", + "name": "Hoswey", + "avatar_url": "https://avatars3.githubusercontent.com/u/3689445?v=4", + "profile": "https://github.com/hoswey", + "contributions": [ + "code" + ] + }, { "login": "amit2103", "name": "Amit Pandey", diff --git a/README.md b/README.md index 1417b68d3..e9cb72003 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 -
Amit Pandey

💻 +
Hoswey

💻
qza

💻 @@ -128,6 +128,9 @@ This project is licensed under the terms of the MIT license.
田浩

🖋
gwildor28

💻 + +
Amit Pandey

💻 + From 37bffb4a99865f4ca34a4d4ac6816a52e8b79b9f Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 17:47:06 +0300 Subject: [PATCH 115/211] docs: add gopinath-langote as a contributor (#1386) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index ef533e802..21d993c64 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "gopinath-langote", + "name": "Gopinath Langote", + "avatar_url": "https://avatars2.githubusercontent.com/u/10210778?v=4", + "profile": "https://www.linkedin.com/in/gopinathlangote/", + "contributions": [ + "code" + ] + }, { "login": "hoswey", "name": "Hoswey", diff --git a/README.md b/README.md index e9cb72003..d9fba1e99 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 -
Hoswey

💻 +
Gopinath Langote

💻
qza

💻 @@ -130,6 +130,7 @@ This project is licensed under the terms of the MIT license.
Amit Pandey

💻 +
Hoswey

💻 From 8c21809dad7caf2d42d19e32c1eead5c6fc6de8e Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 17:49:00 +0300 Subject: [PATCH 116/211] docs: add ThatGuyWithTheHat as a contributor (#1387) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 21d993c64..edef8c2c5 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "ThatGuyWithTheHat", + "name": "Matt", + "avatar_url": "https://avatars0.githubusercontent.com/u/24470582?v=4", + "profile": "https://github.com/ThatGuyWithTheHat", + "contributions": [ + "content" + ] + }, { "login": "gopinath-langote", "name": "Gopinath Langote", diff --git a/README.md b/README.md index d9fba1e99..5d9b81ca7 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 -
Gopinath Langote

💻 +
Matt

🖋
qza

💻 @@ -131,6 +131,7 @@ This project is licensed under the terms of the MIT license.
Amit Pandey

💻
Hoswey

💻 +
Gopinath Langote

💻 From 5a23fab795d1588a2cada9e923eb8856ff2398a0 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 17:50:53 +0300 Subject: [PATCH 117/211] docs: add vehpsr as a contributor (#1389) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index edef8c2c5..e1b8032cb 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "vehpsr", + "name": "gans", + "avatar_url": "https://avatars2.githubusercontent.com/u/3133265?v=4", + "profile": "https://github.com/vehpsr", + "contributions": [ + "code" + ] + }, { "login": "ThatGuyWithTheHat", "name": "Matt", diff --git a/README.md b/README.md index 5d9b81ca7..62c70ae2f 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 -
Matt

🖋 +
gans

💻
qza

💻 @@ -132,6 +132,7 @@ This project is licensed under the terms of the MIT license.
Amit Pandey

💻
Hoswey

💻
Gopinath Langote

💻 +
Matt

🖋 From c0d7c8922e82eb02cbeff2b331dc8b1ed30924b8 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 17:53:30 +0300 Subject: [PATCH 118/211] docs: add Azureyjt as a contributor (#1388) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 5 ++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index e1b8032cb..7a1681230 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "Azureyjt", + "name": "Azureyjt", + "avatar_url": "https://avatars2.githubusercontent.com/u/18476317?v=4", + "profile": "https://github.com/Azureyjt", + "contributions": [ + "code" + ] + }, { "login": "vehpsr", "name": "gans", diff --git a/README.md b/README.md index 62c70ae2f..6b90e2df8 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 -
gans

💻 +
Azureyjt

💻
qza

💻 @@ -134,6 +134,9 @@ This project is licensed under the terms of the MIT license.
Gopinath Langote

💻
Matt

🖋 + +
gans

💻 + From 7968615ad466c86b9d68cd25eee5d9a53a27f682 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 17:55:53 +0300 Subject: [PATCH 119/211] docs: add mookkiah as a contributor (#1390) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 7a1681230..ec24b3888 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "mookkiah", + "name": "Mahendran Mookkiah", + "avatar_url": "https://avatars1.githubusercontent.com/u/8975264?v=4", + "profile": "https://github.com/mookkiah", + "contributions": [ + "code" + ] + }, { "login": "Azureyjt", "name": "Azureyjt", diff --git a/README.md b/README.md index 6b90e2df8..ac8ab189a 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 -
Azureyjt

💻 +
Mahendran Mookkiah

💻
qza

💻 @@ -136,6 +136,7 @@ This project is licensed under the terms of the MIT license.
gans

💻 +
Azureyjt

💻 From c5479cc882d3a1ff8c52fedd8ec8d6371bb64368 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 17:58:00 +0300 Subject: [PATCH 120/211] docs: add llorllale as a contributor (#1391) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index ec24b3888..02b8d2f37 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "llorllale", + "name": "George Aristy", + "avatar_url": "https://avatars1.githubusercontent.com/u/2019896?v=4", + "profile": "https://llorllale.github.io/", + "contributions": [ + "code" + ] + }, { "login": "mookkiah", "name": "Mahendran Mookkiah", diff --git a/README.md b/README.md index ac8ab189a..8869d6e26 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 -
Mahendran Mookkiah

💻 +
George Aristy

💻
qza

💻 @@ -137,6 +137,7 @@ This project is licensed under the terms of the MIT license.
gans

💻
Azureyjt

💻 +
Mahendran Mookkiah

💻 From c2fb5917496f001fc4293e2a4f7beb3a2af5542c Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:00:07 +0300 Subject: [PATCH 121/211] docs: add igeligel as a contributor (#1392) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 02b8d2f37..71677e31f 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "igeligel", + "name": "Kevin Peters", + "avatar_url": "https://avatars1.githubusercontent.com/u/12736734?v=4", + "profile": "https://www.kevinpeters.net/about/", + "contributions": [ + "code" + ] + }, { "login": "llorllale", "name": "George Aristy", diff --git a/README.md b/README.md index 8869d6e26..f8d66532b 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 -
George Aristy

💻 +
Kevin Peters

💻
qza

💻 @@ -138,6 +138,7 @@ This project is licensed under the terms of the MIT license.
gans

💻
Azureyjt

💻
Mahendran Mookkiah

💻 +
George Aristy

💻 From d1de4657801a2f4715673f79102cbf181e89e819 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:02:13 +0300 Subject: [PATCH 122/211] docs: add hbothra15 as a contributor (#1393) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 5 ++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 71677e31f..c7cef5bea 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "hbothra15", + "name": "Hemant Bothra", + "avatar_url": "https://avatars1.githubusercontent.com/u/7418012?v=4", + "profile": "https://github.com/hbothra15", + "contributions": [ + "code" + ] + }, { "login": "igeligel", "name": "Kevin Peters", diff --git a/README.md b/README.md index f8d66532b..1b57fa8ab 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 -
Kevin Peters

💻 +
Hemant Bothra

💻
qza

💻 @@ -140,6 +140,9 @@ This project is licensed under the terms of the MIT license.
Mahendran Mookkiah

💻
George Aristy

💻 + +
Kevin Peters

💻 + From ec80402fe50b81cc651946a48c7aa0b0f5b9e224 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:05:22 +0300 Subject: [PATCH 123/211] docs: add giorgosmav21 as a contributor (#1394) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index c7cef5bea..9518ede79 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "giorgosmav21", + "name": "George Mavroeidis", + "avatar_url": "https://avatars2.githubusercontent.com/u/22855493?v=4", + "profile": "https://github.com/giorgosmav21", + "contributions": [ + "code" + ] + }, { "login": "hbothra15", "name": "Hemant Bothra", diff --git a/README.md b/README.md index 1b57fa8ab..12ba1a7e4 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 -
Hemant Bothra

💻 +
George Mavroeidis

💻
qza

💻 @@ -142,6 +142,7 @@ This project is licensed under the terms of the MIT license.
Kevin Peters

💻 +
Hemant Bothra

💻 From be54dc1c7e24e71d6fdae7069811e6eddf4f06c5 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:07:15 +0300 Subject: [PATCH 124/211] docs: add oconnelc as a contributor (#1395) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 9518ede79..25192ed78 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "oconnelc", + "name": "Christopher O'Connell", + "avatar_url": "https://avatars0.githubusercontent.com/u/1112973?v=4", + "profile": "https://github.com/oconnelc", + "contributions": [ + "code" + ] + }, { "login": "giorgosmav21", "name": "George Mavroeidis", diff --git a/README.md b/README.md index 12ba1a7e4..d1cbd2f1c 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 -
George Mavroeidis

💻 +
Christopher O'Connell

💻
qza

💻 @@ -143,6 +143,7 @@ This project is licensed under the terms of the MIT license.
Kevin Peters

💻
Hemant Bothra

💻 +
George Mavroeidis

💻 From ba485e2c3efb6669cece11164f93fb9bd4186316 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:09:00 +0300 Subject: [PATCH 125/211] docs: add npczwh as a contributor (#1396) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 25192ed78..17c9bc3d6 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "npczwh", + "name": "Zhang WH", + "avatar_url": "https://avatars0.githubusercontent.com/u/14066422?v=4", + "profile": "https://github.com/npczwh", + "contributions": [ + "code" + ] + }, { "login": "oconnelc", "name": "Christopher O'Connell", diff --git a/README.md b/README.md index d1cbd2f1c..227c62c60 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 -
Christopher O'Connell

💻 +
Zhang WH

💻
qza

💻 @@ -144,6 +144,7 @@ This project is licensed under the terms of the MIT license.
Kevin Peters

💻
Hemant Bothra

💻
George Mavroeidis

💻 +
Christopher O'Connell

💻 From d791c785014b200b38c95d07859cabf9f8a16b8b Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:11:09 +0300 Subject: [PATCH 126/211] docs: add leogtzr as a contributor (#1397) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 3 +++ 2 files changed, 12 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 17c9bc3d6..985bd474f 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "leogtzr", + "name": "Leo Gutiérrez Ramírez", + "avatar_url": "https://avatars0.githubusercontent.com/u/1211969?v=4", + "profile": "https://github.com/leogtzr", + "contributions": [ + "code" + ] + }, { "login": "npczwh", "name": "Zhang WH", diff --git a/README.md b/README.md index 227c62c60..7e2ffc3d3 100644 --- a/README.md +++ b/README.md @@ -146,6 +146,9 @@ This project is licensed under the terms of the MIT license.
George Mavroeidis

💻
Christopher O'Connell

💻 + +
Leo Gutiérrez Ramírez

💻 + From e924c9399ad236da1db94edd049147a3975fa007 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:12:47 +0300 Subject: [PATCH 127/211] docs: add hannespernpeintner as a contributor (#1398) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 985bd474f..69a4de8f3 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "hannespernpeintner", + "name": "Hannes", + "avatar_url": "https://avatars3.githubusercontent.com/u/1679437?v=4", + "profile": "https://bitbucket.org/hannespernpeintner/", + "contributions": [ + "code" + ] + }, { "login": "leogtzr", "name": "Leo Gutiérrez Ramírez", diff --git a/README.md b/README.md index 7e2ffc3d3..9ceb86f80 100644 --- a/README.md +++ b/README.md @@ -148,6 +148,7 @@ This project is licensed under the terms of the MIT license.
Leo Gutiérrez Ramírez

💻 +
Hannes

💻 From 8137609e2f4a3ff7a9d43615c2707f634d699f70 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:14:30 +0300 Subject: [PATCH 128/211] docs: add dgruntz as a contributor (#1399) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 69a4de8f3..c36df4855 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "dgruntz", + "name": "Dominik Gruntz", + "avatar_url": "https://avatars0.githubusercontent.com/u/1516800?v=4", + "profile": "https://github.com/dgruntz", + "contributions": [ + "code" + ] + }, { "login": "hannespernpeintner", "name": "Hannes", diff --git a/README.md b/README.md index 9ceb86f80..fef0bf614 100644 --- a/README.md +++ b/README.md @@ -149,6 +149,7 @@ This project is licensed under the terms of the MIT license.
Leo Gutiérrez Ramírez

💻
Hannes

💻 +
Dominik Gruntz

💻 From 46fdc5a54f0b4ec741f4dae395acf5d9ffe35eaf Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:16:12 +0300 Subject: [PATCH 129/211] docs: add christofferh as a contributor (#1400) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index c36df4855..8e0e6d13a 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "christofferh", + "name": "Christoffer Hamberg", + "avatar_url": "https://avatars1.githubusercontent.com/u/767643?v=4", + "profile": "https://christofferh.com", + "contributions": [ + "code" + ] + }, { "login": "dgruntz", "name": "Dominik Gruntz", diff --git a/README.md b/README.md index fef0bf614..9720fbad5 100644 --- a/README.md +++ b/README.md @@ -150,6 +150,7 @@ This project is licensed under the terms of the MIT license.
Leo Gutiérrez Ramírez

💻
Hannes

💻
Dominik Gruntz

💻 +
Christoffer Hamberg

💻 From a727a1d05b79b17ca2dd1a926d67cf8e651dcc52 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:18:07 +0300 Subject: [PATCH 130/211] docs: add AnaghaSasikumar as a contributor (#1401) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 3 +++ 2 files changed, 12 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 8e0e6d13a..ca442aa6e 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "AnaghaSasikumar", + "name": "AnaghaSasikumar", + "avatar_url": "https://avatars2.githubusercontent.com/u/42939261?v=4", + "profile": "https://github.com/AnaghaSasikumar", + "contributions": [ + "code" + ] + }, { "login": "christofferh", "name": "Christoffer Hamberg", diff --git a/README.md b/README.md index 9720fbad5..508a1dbef 100644 --- a/README.md +++ b/README.md @@ -152,6 +152,9 @@ This project is licensed under the terms of the MIT license.
Dominik Gruntz

💻
Christoffer Hamberg

💻 + +
AnaghaSasikumar

💻 + From 96bfb8bd9f1c293634828c0fd8e5ef074a4821f8 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:19:53 +0300 Subject: [PATCH 131/211] docs: add waisuan as a contributor (#1402) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index ca442aa6e..94158246d 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "waisuan", + "name": "Evan Sia Wai Suan", + "avatar_url": "https://avatars2.githubusercontent.com/u/10975700?v=4", + "profile": "https://github.com/waisuan", + "contributions": [ + "code" + ] + }, { "login": "AnaghaSasikumar", "name": "AnaghaSasikumar", diff --git a/README.md b/README.md index 508a1dbef..6a091ea20 100644 --- a/README.md +++ b/README.md @@ -154,6 +154,7 @@ This project is licensed under the terms of the MIT license.
AnaghaSasikumar

💻 +
Evan Sia Wai Suan

💻 From 09880e3850277b372975089725a7d3cdf8754a37 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:21:41 +0300 Subject: [PATCH 132/211] docs: add perwramdemark as a contributor (#1403) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 94158246d..a2cfd2a03 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "perwramdemark", + "name": "Per Wramdemark", + "avatar_url": "https://avatars2.githubusercontent.com/u/7052193?v=4", + "profile": "http://www.wramdemark.se", + "contributions": [ + "code" + ] + }, { "login": "waisuan", "name": "Evan Sia Wai Suan", diff --git a/README.md b/README.md index 6a091ea20..51c774275 100644 --- a/README.md +++ b/README.md @@ -155,6 +155,7 @@ This project is licensed under the terms of the MIT license.
AnaghaSasikumar

💻
Evan Sia Wai Suan

💻 +
Per Wramdemark

💻 From 19929d9e7215223eddc03b5f1e950b7ec164297d Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:23:23 +0300 Subject: [PATCH 133/211] docs: add leonmak as a contributor (#1404) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 3 +++ 2 files changed, 12 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index a2cfd2a03..fa19cf391 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "leonmak", + "name": "Leon Mak", + "avatar_url": "https://avatars3.githubusercontent.com/u/13071508?v=4", + "profile": "http://leonmak.me", + "contributions": [ + "code" + ] + }, { "login": "perwramdemark", "name": "Per Wramdemark", diff --git a/README.md b/README.md index 51c774275..abea00951 100644 --- a/README.md +++ b/README.md @@ -156,6 +156,9 @@ This project is licensed under the terms of the MIT license.
AnaghaSasikumar

💻
Evan Sia Wai Suan

💻
Per Wramdemark

💻 +
Leon Mak

💻 + + From a70213f8521cadab757ed874183e7d4c43e6ac50 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:25:03 +0300 Subject: [PATCH 134/211] docs: add kanwarpreet25 as a contributor (#1405) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index fa19cf391..7b91a7aa5 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "kanwarpreet25", + "name": "kanwarpreet25", + "avatar_url": "https://avatars0.githubusercontent.com/u/39183641?v=4", + "profile": "https://github.com/kanwarpreet25", + "contributions": [ + "code" + ] + }, { "login": "leonmak", "name": "Leon Mak", diff --git a/README.md b/README.md index abea00951..53f0fedbb 100644 --- a/README.md +++ b/README.md @@ -159,6 +159,7 @@ This project is licensed under the terms of the MIT license.
Leon Mak

💻 +
kanwarpreet25

💻 From 54bb02f69131cccd0b6655e19de3df3e314e6ea8 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:26:34 +0300 Subject: [PATCH 135/211] docs: add MSaifAsif as a contributor (#1406) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 7b91a7aa5..1fadb0530 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "MSaifAsif", + "name": "M Saif Asif", + "avatar_url": "https://avatars1.githubusercontent.com/u/6280554?v=4", + "profile": "https://github.com/MSaifAsif", + "contributions": [ + "code" + ] + }, { "login": "kanwarpreet25", "name": "kanwarpreet25", diff --git a/README.md b/README.md index 53f0fedbb..708a62ca6 100644 --- a/README.md +++ b/README.md @@ -160,6 +160,7 @@ This project is licensed under the terms of the MIT license.
kanwarpreet25

💻 +
M Saif Asif

💻 From e2a42b0051f4818908936aee5627329e1309cbfe Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:28:10 +0300 Subject: [PATCH 136/211] docs: add Alwayswithme as a contributor (#1407) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 1fadb0530..782955f0c 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "Alwayswithme", + "name": "PhoenixYip", + "avatar_url": "https://avatars3.githubusercontent.com/u/3234786?v=4", + "profile": "https://alwayswithme.github.io", + "contributions": [ + "code" + ] + }, { "login": "MSaifAsif", "name": "M Saif Asif", diff --git a/README.md b/README.md index 708a62ca6..173485073 100644 --- a/README.md +++ b/README.md @@ -161,6 +161,7 @@ This project is licensed under the terms of the MIT license.
kanwarpreet25

💻
M Saif Asif

💻 +
PhoenixYip

💻 From fe2f8f74a1d1126d5de4e3fa5c598038ec9b7a8d Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:29:41 +0300 Subject: [PATCH 137/211] docs: add ranjeet-floyd as a contributor (#1408) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 782955f0c..27e8872d7 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "ranjeet-floyd", + "name": "Ranjeet", + "avatar_url": "https://avatars0.githubusercontent.com/u/1992972?v=4", + "profile": "https://ranjeet-floyd.github.io", + "contributions": [ + "code" + ] + }, { "login": "Alwayswithme", "name": "PhoenixYip", diff --git a/README.md b/README.md index 173485073..46a1443e7 100644 --- a/README.md +++ b/README.md @@ -162,6 +162,7 @@ This project is licensed under the terms of the MIT license.
kanwarpreet25

💻
M Saif Asif

💻
PhoenixYip

💻 +
Ranjeet

💻 From 8e268cf261cd23f5de815f32da2d9c2b417d5c1a Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:32:59 +0300 Subject: [PATCH 138/211] docs: add mitchellirvin as a contributor (#1409) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 11 +++++++++++ 2 files changed, 20 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 27e8872d7..4b9a0dd1a 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "mitchellirvin", + "name": "Mitchell Irvin", + "avatar_url": "https://avatars0.githubusercontent.com/u/16233245?v=4", + "profile": "http://mitchell-irvin.com", + "contributions": [ + "code" + ] + }, { "login": "ranjeet-floyd", "name": "Ranjeet", diff --git a/README.md b/README.md index 46a1443e7..d587771d1 100644 --- a/README.md +++ b/README.md @@ -164,6 +164,17 @@ This project is licensed under the terms of the MIT license.
PhoenixYip

💻
Ranjeet

💻 +
Mitchell Irvin

💻 + + + + + + + + + + From 9b5ae765fccfaac7be5fec221a48b0f0dde9ad54 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:34:45 +0300 Subject: [PATCH 139/211] docs: add kirill-vlasov as a contributor (#1410) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 4b9a0dd1a..6d3a4741f 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "kirill-vlasov", + "name": "Kirill Vlasov", + "avatar_url": "https://avatars3.githubusercontent.com/u/16112495?v=4", + "profile": "https://github.com/kirill-vlasov", + "contributions": [ + "code" + ] + }, { "login": "mitchellirvin", "name": "Mitchell Irvin", diff --git a/README.md b/README.md index d587771d1..f12fcb9ab 100644 --- a/README.md +++ b/README.md @@ -166,6 +166,7 @@ This project is licensed under the terms of the MIT license.
Mitchell Irvin

💻 +
Kirill Vlasov

💻 From 1bc77a80f2b8fcafc52e611af600f9a77d77c744 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:36:27 +0300 Subject: [PATCH 140/211] docs: add joningiwork as a contributor (#1411) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 6d3a4741f..7352e906e 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "joningiwork", + "name": "Jón Ingi Sveinbjörnsson", + "avatar_url": "https://avatars2.githubusercontent.com/u/6115148?v=4", + "profile": "http://joningi.net", + "contributions": [ + "code" + ] + }, { "login": "kirill-vlasov", "name": "Kirill Vlasov", diff --git a/README.md b/README.md index f12fcb9ab..655c71e26 100644 --- a/README.md +++ b/README.md @@ -167,6 +167,7 @@ This project is licensed under the terms of the MIT license.
Mitchell Irvin

💻
Kirill Vlasov

💻 +
Jón Ingi Sveinbjörnsson

💻 From a475df845bf44163ce49c9289371d08436d27bb5 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:38:07 +0300 Subject: [PATCH 141/211] docs: add jarpit96 as a contributor (#1412) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 7352e906e..ffe698d84 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "jarpit96", + "name": "Arpit Jain", + "avatar_url": "https://avatars2.githubusercontent.com/u/10098713?v=4", + "profile": "https://github.com/jarpit96", + "contributions": [ + "code" + ] + }, { "login": "joningiwork", "name": "Jón Ingi Sveinbjörnsson", diff --git a/README.md b/README.md index 655c71e26..c59bfac02 100644 --- a/README.md +++ b/README.md @@ -165,6 +165,7 @@ This project is licensed under the terms of the MIT license.
Ranjeet

💻
Mitchell Irvin

💻 +
Arpit Jain

💻
Kirill Vlasov

💻
Jón Ingi Sveinbjörnsson

💻 From 2a66fec6fe509a2b3a96d086d3e7265aebf823b1 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:41:17 +0300 Subject: [PATCH 142/211] docs: add hoangnam2261 as a contributor (#1413) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index ffe698d84..ca9e4c8e0 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "hoangnam2261", + "name": "hoangnam2261", + "avatar_url": "https://avatars2.githubusercontent.com/u/31692990?v=4", + "profile": "https://github.com/hoangnam2261", + "contributions": [ + "code" + ] + }, { "login": "jarpit96", "name": "Arpit Jain", diff --git a/README.md b/README.md index c59bfac02..b10ea2a59 100644 --- a/README.md +++ b/README.md @@ -166,6 +166,7 @@ This project is licensed under the terms of the MIT license.
Mitchell Irvin

💻
Arpit Jain

💻 +
hoangnam2261

💻
Kirill Vlasov

💻
Jón Ingi Sveinbjörnsson

💻 From d11b2f06ea91219a2952ca0ea578faef13384ab8 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:42:55 +0300 Subject: [PATCH 143/211] docs: add fanofxiaofeng as a contributor (#1414) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index ca9e4c8e0..76018eb5a 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "fanofxiaofeng", + "name": "靳阳", + "avatar_url": "https://avatars0.githubusercontent.com/u/3983683?v=4", + "profile": "https://github.com/fanofxiaofeng", + "contributions": [ + "code" + ] + }, { "login": "hoangnam2261", "name": "hoangnam2261", diff --git a/README.md b/README.md index b10ea2a59..9d2c2fb91 100644 --- a/README.md +++ b/README.md @@ -167,6 +167,7 @@ This project is licensed under the terms of the MIT license.
Mitchell Irvin

💻
Arpit Jain

💻
hoangnam2261

💻 +
靳阳

💻
Kirill Vlasov

💻
Jón Ingi Sveinbjörnsson

💻 From 1bbae5fd5a63a6c56e4b576ce4b6cd0abbc59855 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:44:29 +0300 Subject: [PATCH 144/211] docs: add dmitraver as a contributor (#1415) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 76018eb5a..c04339058 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "dmitraver", + "name": "Dmitry Avershin", + "avatar_url": "https://avatars3.githubusercontent.com/u/1798156?v=4", + "profile": "https://github.com/dmitraver", + "contributions": [ + "code" + ] + }, { "login": "fanofxiaofeng", "name": "靳阳", diff --git a/README.md b/README.md index 9d2c2fb91..04721d214 100644 --- a/README.md +++ b/README.md @@ -171,6 +171,7 @@ This project is licensed under the terms of the MIT license.
Kirill Vlasov

💻
Jón Ingi Sveinbjörnsson

💻 +
Dmitry Avershin

💻 From b67a019c48c185e824acf3936b917a0b06764715 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:45:53 +0300 Subject: [PATCH 145/211] docs: add besok as a contributor (#1416) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index c04339058..f30ec4f26 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "besok", + "name": "Boris", + "avatar_url": "https://avatars2.githubusercontent.com/u/29834592?v=4", + "profile": "https://github.com/besok", + "contributions": [ + "code" + ] + }, { "login": "dmitraver", "name": "Dmitry Avershin", diff --git a/README.md b/README.md index 04721d214..4407d4f36 100644 --- a/README.md +++ b/README.md @@ -172,6 +172,7 @@ This project is licensed under the terms of the MIT license.
Kirill Vlasov

💻
Jón Ingi Sveinbjörnsson

💻
Dmitry Avershin

💻 +
Boris

💻 From b4e4cf9cfe4633ebc35e0f91836ce20bd671e11c Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:48:09 +0300 Subject: [PATCH 146/211] docs: add baislsl as a contributor (#1417) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 3 +++ 2 files changed, 12 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index f30ec4f26..39babdca5 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "baislsl", + "name": "Shengli Bai", + "avatar_url": "https://avatars0.githubusercontent.com/u/17060584?v=4", + "profile": "https://github.com/baislsl", + "contributions": [ + "code" + ] + }, { "login": "besok", "name": "Boris", diff --git a/README.md b/README.md index 4407d4f36..cc5d3a99e 100644 --- a/README.md +++ b/README.md @@ -164,10 +164,12 @@ This project is licensed under the terms of the MIT license.
PhoenixYip

💻
Ranjeet

💻 +
Mitchell Irvin

💻
Arpit Jain

💻
hoangnam2261

💻
靳阳

💻 +
Kirill Vlasov

💻
Jón Ingi Sveinbjörnsson

💻 @@ -175,6 +177,7 @@ This project is licensed under the terms of the MIT license.
Boris

💻 +
Shengli Bai

💻 From 65d627b2ed11a5d8fdbeae32266bf2cf3dbfcdd8 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:49:46 +0300 Subject: [PATCH 147/211] docs: add akrystian as a contributor (#1418) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 39babdca5..92b26c57e 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "akrystian", + "name": "adamski.pro", + "avatar_url": "https://avatars1.githubusercontent.com/u/6537430?v=4", + "profile": "http://adamski.pro", + "contributions": [ + "code" + ] + }, { "login": "baislsl", "name": "Shengli Bai", diff --git a/README.md b/README.md index cc5d3a99e..0d91ed28f 100644 --- a/README.md +++ b/README.md @@ -178,6 +178,7 @@ This project is licensed under the terms of the MIT license.
Shengli Bai

💻 +
adamski.pro

💻 From 47acedaaf7e733d131df78126c3968df40ad4072 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:10:44 +0300 Subject: [PATCH 148/211] docs: add Rzeposlaw as a contributor (#1419) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 92b26c57e..8ff68a0b8 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "Rzeposlaw", + "name": "Katarzyna Rzepecka", + "avatar_url": "https://avatars2.githubusercontent.com/u/18425745?v=4", + "profile": "https://github.com/Rzeposlaw", + "contributions": [ + "code" + ] + }, { "login": "akrystian", "name": "adamski.pro", diff --git a/README.md b/README.md index 0d91ed28f..8e02e8749 100644 --- a/README.md +++ b/README.md @@ -179,6 +179,7 @@ This project is licensed under the terms of the MIT license.
Shengli Bai

💻
adamski.pro

💻 +
Katarzyna Rzepecka

💻 From ae57ec75f3dbe269113e40691d7fbab038735035 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:12:46 +0300 Subject: [PATCH 149/211] docs: add LuigiCortese as a contributor (#1420) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 8ff68a0b8..98f1a8eba 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "LuigiCortese", + "name": "Luigi Cortese", + "avatar_url": "https://avatars0.githubusercontent.com/u/9956006?v=4", + "profile": "http://www.devsedge.net/", + "contributions": [ + "code" + ] + }, { "login": "Rzeposlaw", "name": "Katarzyna Rzepecka", diff --git a/README.md b/README.md index 8e02e8749..182219262 100644 --- a/README.md +++ b/README.md @@ -180,6 +180,7 @@ This project is licensed under the terms of the MIT license.
Shengli Bai

💻
adamski.pro

💻
Katarzyna Rzepecka

💻 +
Luigi Cortese

💻 From efd8c8156e9f6ce3ab5714e971973ec35360d683 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:14:26 +0300 Subject: [PATCH 150/211] docs: add Juaanma as a contributor (#1421) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 98f1a8eba..df021acbe 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "Juaanma", + "name": "Juan Manuel Suárez", + "avatar_url": "https://avatars3.githubusercontent.com/u/7390500?v=4", + "profile": "https://github.com/Juaanma", + "contributions": [ + "code" + ] + }, { "login": "LuigiCortese", "name": "Luigi Cortese", diff --git a/README.md b/README.md index 182219262..33df95b87 100644 --- a/README.md +++ b/README.md @@ -183,6 +183,7 @@ This project is licensed under the terms of the MIT license.
Luigi Cortese

💻 +
Juan Manuel Suárez

💻 From 325f0d93b24d9779109391cb7a5c876eaf048aa1 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:16:02 +0300 Subject: [PATCH 151/211] docs: add 7agustibm as a contributor (#1422) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index df021acbe..c7d6637a9 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "7agustibm", + "name": "Agustí Becerra Milà", + "avatar_url": "https://avatars0.githubusercontent.com/u/8149332?v=4", + "profile": "https://github.com/7agustibm", + "contributions": [ + "code" + ] + }, { "login": "Juaanma", "name": "Juan Manuel Suárez", diff --git a/README.md b/README.md index 33df95b87..c9429805b 100644 --- a/README.md +++ b/README.md @@ -184,6 +184,7 @@ This project is licensed under the terms of the MIT license.
Juan Manuel Suárez

💻 +
Agustí Becerra Milà

💻 From 1841fba8319af0e7a12a0ea04320311702b4b950 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:17:45 +0300 Subject: [PATCH 152/211] docs: add yosfik as a contributor (#1423) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index c7d6637a9..1e49b8d91 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "yosfik", + "name": "Yosfik Alqadri", + "avatar_url": "https://avatars3.githubusercontent.com/u/4850270?v=4", + "profile": "https://github.com/yosfik", + "contributions": [ + "code" + ] + }, { "login": "7agustibm", "name": "Agustí Becerra Milà", diff --git a/README.md b/README.md index c9429805b..74c9220bc 100644 --- a/README.md +++ b/README.md @@ -185,6 +185,7 @@ This project is licensed under the terms of the MIT license.
Juan Manuel Suárez

💻
Agustí Becerra Milà

💻 +
Yosfik Alqadri

💻 From ecb7b44f970c3701ef04db47575f11078c45fa8c Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:19:24 +0300 Subject: [PATCH 153/211] docs: add vanogrid as a contributor (#1424) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 1e49b8d91..8d9026820 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "vanogrid", + "name": "Alexander Ivanov", + "avatar_url": "https://avatars0.githubusercontent.com/u/4307918?v=4", + "profile": "https://www.vanogrid.com", + "contributions": [ + "code" + ] + }, { "login": "yosfik", "name": "Yosfik Alqadri", diff --git a/README.md b/README.md index 74c9220bc..13a649741 100644 --- a/README.md +++ b/README.md @@ -186,6 +186,7 @@ This project is licensed under the terms of the MIT license.
Juan Manuel Suárez

💻
Agustí Becerra Milà

💻
Yosfik Alqadri

💻 +
Alexander Ivanov

💻 From b5fac5cf861df4414dfb76f6b2560cb72f1c9be4 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:21:22 +0300 Subject: [PATCH 154/211] docs: add valdar-hu as a contributor (#1425) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 8d9026820..0087c240e 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "valdar-hu", + "name": "Krisztián Nagy", + "avatar_url": "https://avatars3.githubusercontent.com/u/17962817?v=4", + "profile": "https://github.com/valdar-hu", + "contributions": [ + "code" + ] + }, { "login": "vanogrid", "name": "Alexander Ivanov", diff --git a/README.md b/README.md index 13a649741..4f2b4895c 100644 --- a/README.md +++ b/README.md @@ -189,6 +189,7 @@ This project is licensed under the terms of the MIT license.
Alexander Ivanov

💻 +
Krisztián Nagy

💻 From 652a68b134838ed0f6d7a9fd2f4b29d0e1ad6961 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:23:12 +0300 Subject: [PATCH 155/211] docs: add staillebois as a contributor (#1426) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 0087c240e..fd2186072 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "staillebois", + "name": "staillebois", + "avatar_url": "https://avatars0.githubusercontent.com/u/23701200?v=4", + "profile": "https://github.com/staillebois", + "contributions": [ + "code" + ] + }, { "login": "valdar-hu", "name": "Krisztián Nagy", diff --git a/README.md b/README.md index 4f2b4895c..a93f15b13 100644 --- a/README.md +++ b/README.md @@ -190,6 +190,7 @@ This project is licensed under the terms of the MIT license.
Krisztián Nagy

💻 +
staillebois

💻 From 6f0035e7c23879b19eb514b2907fd392a55680c0 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:25:03 +0300 Subject: [PATCH 156/211] docs: add sankypanhale as a contributor (#1427) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index fd2186072..511466186 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "sankypanhale", + "name": "Sanket Panhale", + "avatar_url": "https://avatars1.githubusercontent.com/u/6478783?v=4", + "profile": "https://github.com/sankypanhale", + "contributions": [ + "content" + ] + }, { "login": "staillebois", "name": "staillebois", diff --git a/README.md b/README.md index a93f15b13..911440c14 100644 --- a/README.md +++ b/README.md @@ -191,6 +191,7 @@ This project is licensed under the terms of the MIT license.
Krisztián Nagy

💻
staillebois

💻 +
Sanket Panhale

🖋 From dafe4956108c9602aed8bd241c80f3cef6247bd0 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:26:38 +0300 Subject: [PATCH 157/211] docs: add prafful1 as a contributor (#1428) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 511466186..591781b1c 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "prafful1", + "name": "Prafful Agarwal", + "avatar_url": "https://avatars0.githubusercontent.com/u/14350274?v=4", + "profile": "https://github.com/prafful1", + "contributions": [ + "content" + ] + }, { "login": "sankypanhale", "name": "Sanket Panhale", diff --git a/README.md b/README.md index 911440c14..7ab4f2b78 100644 --- a/README.md +++ b/README.md @@ -192,6 +192,7 @@ This project is licensed under the terms of the MIT license.
Krisztián Nagy

💻
staillebois

💻
Sanket Panhale

🖋 +
Prafful Agarwal

🖋 From 7fdcd2ec5ab7558ca29227d19acbade450f29cad Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:28:18 +0300 Subject: [PATCH 158/211] docs: add pnowy as a contributor (#1429) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 591781b1c..9edfc2588 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "pnowy", + "name": "Przemek", + "avatar_url": "https://avatars1.githubusercontent.com/u/3254609?v=4", + "profile": "https://przemeknowak.com", + "contributions": [ + "code" + ] + }, { "login": "prafful1", "name": "Prafful Agarwal", diff --git a/README.md b/README.md index 7ab4f2b78..e159ca59f 100644 --- a/README.md +++ b/README.md @@ -195,6 +195,7 @@ This project is licensed under the terms of the MIT license.
Prafful Agarwal

🖋 +
Przemek

💻 From 6c9b912620f1ac84f6b7a61c486c8a400ee6d43d Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:29:55 +0300 Subject: [PATCH 159/211] docs: add lbroman as a contributor (#1430) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 9edfc2588..3a9ed11ac 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "lbroman", + "name": "lbroman", + "avatar_url": "https://avatars1.githubusercontent.com/u/86007?v=4", + "profile": "https://github.com/lbroman", + "contributions": [ + "code" + ] + }, { "login": "pnowy", "name": "Przemek", diff --git a/README.md b/README.md index e159ca59f..03f77ef7d 100644 --- a/README.md +++ b/README.md @@ -196,6 +196,7 @@ This project is licensed under the terms of the MIT license.
Przemek

💻 +
lbroman

💻 From 5d21a03acd97f13e8876686b936f5d48307f2c0a Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:31:35 +0300 Subject: [PATCH 160/211] docs: add kaiwinter as a contributor (#1431) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 3a9ed11ac..ad0a07bff 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "kaiwinter", + "name": "Kai Winter", + "avatar_url": "https://avatars0.githubusercontent.com/u/110982?v=4", + "profile": "http://about.me/kaiwinter", + "contributions": [ + "code" + ] + }, { "login": "lbroman", "name": "lbroman", diff --git a/README.md b/README.md index 03f77ef7d..4a55b3c68 100644 --- a/README.md +++ b/README.md @@ -197,6 +197,7 @@ This project is licensed under the terms of the MIT license.
Przemek

💻
lbroman

💻 +
Kai Winter

💻 From 1f900d164d3b697c29b2e26f17507495e2cd2367 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:33:18 +0300 Subject: [PATCH 161/211] docs: add jjjimenez100 as a contributor (#1432) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index ad0a07bff..e7bc74009 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "jjjimenez100", + "name": "Joshua Jimenez", + "avatar_url": "https://avatars3.githubusercontent.com/u/22243493?v=4", + "profile": "https://github.com/jjjimenez100", + "contributions": [ + "code" + ] + }, { "login": "kaiwinter", "name": "Kai Winter", diff --git a/README.md b/README.md index 4a55b3c68..bbb11f58d 100644 --- a/README.md +++ b/README.md @@ -198,6 +198,7 @@ This project is licensed under the terms of the MIT license.
Przemek

💻
lbroman

💻
Kai Winter

💻 +
Joshua Jimenez

💻 From 73d55afd585106f169da9a3d3275714393073c90 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:34:58 +0300 Subject: [PATCH 162/211] docs: add dzmitryh as a contributor (#1433) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 3 +++ 2 files changed, 12 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index e7bc74009..9913c1e64 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "dzmitryh", + "name": "Dima Gubin", + "avatar_url": "https://avatars2.githubusercontent.com/u/5390492?v=4", + "profile": "https://about.me/dzmitryh", + "contributions": [ + "code" + ] + }, { "login": "jjjimenez100", "name": "Joshua Jimenez", diff --git a/README.md b/README.md index bbb11f58d..b0a836d2a 100644 --- a/README.md +++ b/README.md @@ -200,6 +200,9 @@ This project is licensed under the terms of the MIT license.
Kai Winter

💻
Joshua Jimenez

💻 + +
Dima Gubin

💻 + From 9483888b5eb0fa1c4fe05ad15f0b19b9a6fed043 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:36:36 +0300 Subject: [PATCH 163/211] docs: add christophercolumbusdog as a contributor (#1434) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 9913c1e64..19119645d 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "christophercolumbusdog", + "name": "Christian Cygnus", + "avatar_url": "https://avatars1.githubusercontent.com/u/9342724?v=4", + "profile": "http://ccygnus.com/", + "contributions": [ + "code" + ] + }, { "login": "dzmitryh", "name": "Dima Gubin", diff --git a/README.md b/README.md index b0a836d2a..c188513e2 100644 --- a/README.md +++ b/README.md @@ -202,6 +202,7 @@ This project is licensed under the terms of the MIT license.
Dima Gubin

💻 +
Christian Cygnus

💻 From e222a699648758ae29204ed699d17e809752653e Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:38:23 +0300 Subject: [PATCH 164/211] docs: add anthonycampbell as a contributor (#1435) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 19119645d..b9991fc22 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "anthonycampbell", + "name": "anthony", + "avatar_url": "https://avatars3.githubusercontent.com/u/10249255?v=4", + "profile": "https://github.com/anthonycampbell", + "contributions": [ + "code" + ] + }, { "login": "christophercolumbusdog", "name": "Christian Cygnus", diff --git a/README.md b/README.md index c188513e2..cdb66ef3b 100644 --- a/README.md +++ b/README.md @@ -203,6 +203,7 @@ This project is licensed under the terms of the MIT license.
Dima Gubin

💻
Christian Cygnus

💻 +
anthony

💻 From 706c5092c106420a1942a9d6a63db34b5fa133ab Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:40:00 +0300 Subject: [PATCH 165/211] docs: add amogozov as a contributor (#1436) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index b9991fc22..385e4448c 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "amogozov", + "name": "Artur Mogozov", + "avatar_url": "https://avatars3.githubusercontent.com/u/7372215?v=4", + "profile": "https://github.com/amogozov", + "contributions": [ + "code" + ] + }, { "login": "anthonycampbell", "name": "anthony", diff --git a/README.md b/README.md index cdb66ef3b..e213d97c0 100644 --- a/README.md +++ b/README.md @@ -204,6 +204,7 @@ This project is licensed under the terms of the MIT license.
Dima Gubin

💻
Christian Cygnus

💻
anthony

💻 +
Artur Mogozov

💻 From beffc87deb9a27b46f56fe91b3a69b6b52774fe3 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:41:47 +0300 Subject: [PATCH 166/211] docs: add alexsomai as a contributor (#1437) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 3 +++ 2 files changed, 12 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 385e4448c..dced8bd77 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "alexsomai", + "name": "Alexandru Somai", + "avatar_url": "https://avatars1.githubusercontent.com/u/5720977?v=4", + "profile": "https://alexsomai.com", + "contributions": [ + "code" + ] + }, { "login": "amogozov", "name": "Artur Mogozov", diff --git a/README.md b/README.md index e213d97c0..7405d01c4 100644 --- a/README.md +++ b/README.md @@ -206,6 +206,9 @@ This project is licensed under the terms of the MIT license.
anthony

💻
Artur Mogozov

💻 + +
Alexandru Somai

💻 + From 62ac59afda52a62fca08c7c066d57eae62a8ea74 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:43:26 +0300 Subject: [PATCH 167/211] docs: add MaVdbussche as a contributor (#1438) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index dced8bd77..c6400808a 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "MaVdbussche", + "name": "Martin Vandenbussche", + "avatar_url": "https://avatars1.githubusercontent.com/u/26136934?v=4", + "profile": "https://github.com/MaVdbussche", + "contributions": [ + "code" + ] + }, { "login": "alexsomai", "name": "Alexandru Somai", diff --git a/README.md b/README.md index 7405d01c4..fef3b2712 100644 --- a/README.md +++ b/README.md @@ -208,6 +208,7 @@ This project is licensed under the terms of the MIT license.
Alexandru Somai

💻 +
Martin Vandenbussche

💻 From 34a36cb519b7718d19eb06ed7b088b960f722e3c Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:45:07 +0300 Subject: [PATCH 168/211] docs: add Harshrajsinh as a contributor (#1439) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index c6400808a..f694230e6 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "Harshrajsinh", + "name": "Harshraj Thakor", + "avatar_url": "https://avatars2.githubusercontent.com/u/22811531?v=4", + "profile": "https://github.com/Harshrajsinh", + "contributions": [ + "code" + ] + }, { "login": "MaVdbussche", "name": "Martin Vandenbussche", diff --git a/README.md b/README.md index fef3b2712..985605cd2 100644 --- a/README.md +++ b/README.md @@ -209,6 +209,7 @@ This project is licensed under the terms of the MIT license.
Alexandru Somai

💻
Martin Vandenbussche

💻 +
Harshraj Thakor

💻 From 1d025b70193e361f39a73ed1faf7090f21c1ff16 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:47:29 +0300 Subject: [PATCH 169/211] docs: add Deathnerd as a contributor (#1440) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index f694230e6..7f925d4b8 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "Deathnerd", + "name": "Wes Gilleland", + "avatar_url": "https://avatars0.githubusercontent.com/u/1685953?v=4", + "profile": "http://theerroris.me", + "contributions": [ + "code" + ] + }, { "login": "Harshrajsinh", "name": "Harshraj Thakor", diff --git a/README.md b/README.md index 985605cd2..c879245d4 100644 --- a/README.md +++ b/README.md @@ -210,6 +210,7 @@ This project is licensed under the terms of the MIT license.
Alexandru Somai

💻
Martin Vandenbussche

💻
Harshraj Thakor

💻 +
Wes Gilleland

💻 From 87c2644842bfa5cbbbcd89ce0b2a4c1de3e4c76c Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:49:20 +0300 Subject: [PATCH 170/211] docs: add Anurag870 as a contributor (#1441) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 3 +++ 2 files changed, 12 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 7f925d4b8..60837ff7d 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "Anurag870", + "name": "Anurag870", + "avatar_url": "https://avatars1.githubusercontent.com/u/6295975?v=4", + "profile": "https://github.com/Anurag870", + "contributions": [ + "code" + ] + }, { "login": "Deathnerd", "name": "Wes Gilleland", diff --git a/README.md b/README.md index c879245d4..9f7e24500 100644 --- a/README.md +++ b/README.md @@ -212,6 +212,9 @@ This project is licensed under the terms of the MIT license.
Harshraj Thakor

💻
Wes Gilleland

💻 + +
Anurag870

💻 + From a1b2ab129e6388cb8ac6fd4a10566fe347e8f49d Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:51:03 +0300 Subject: [PATCH 171/211] docs: add Amarnath510 as a contributor (#1442) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 60837ff7d..d2109eea0 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "Amarnath510", + "name": "Amarnath Chandana", + "avatar_url": "https://avatars0.githubusercontent.com/u/4599623?v=4", + "profile": "https://amarnath510.github.io/portfolio", + "contributions": [ + "code" + ] + }, { "login": "Anurag870", "name": "Anurag870", diff --git a/README.md b/README.md index 9f7e24500..319a3760f 100644 --- a/README.md +++ b/README.md @@ -214,6 +214,7 @@ This project is licensed under the terms of the MIT license.
Anurag870

💻 +
Amarnath Chandana

💻 From 69341ff7124debb5c114f680debf81a94da2cb65 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:53:14 +0300 Subject: [PATCH 172/211] docs: add IAmPramod as a contributor (#1443) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index d2109eea0..29549be77 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "IAmPramod", + "name": "Pramod Gupta", + "avatar_url": "https://avatars1.githubusercontent.com/u/2184241?v=4", + "profile": "https://www.linkedin.com/in/pramodgupta3/", + "contributions": [ + "review" + ] + }, { "login": "Amarnath510", "name": "Amarnath Chandana", diff --git a/README.md b/README.md index 319a3760f..8769e4a56 100644 --- a/README.md +++ b/README.md @@ -215,6 +215,7 @@ This project is licensed under the terms of the MIT license.
Anurag870

💻
Amarnath Chandana

💻 +
Pramod Gupta

👀 From 1f0a24cefa9f2c8c3036ccac64acbc8af67ad815 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:59:40 +0300 Subject: [PATCH 173/211] docs: add trautonen as a contributor (#1445) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++ README.md | 139 ++++++++++++++++++++++---------------------- 2 files changed, 79 insertions(+), 69 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 29549be77..57fed1a81 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -902,6 +902,15 @@ "contributions": [ "code" ] + }, + { + "login": "trautonen", + "name": "Tapio Rautonen", + "avatar_url": "https://avatars3.githubusercontent.com/u/1641063?v=4", + "profile": "https://github.com/trautonen", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 4, diff --git a/README.md b/README.md index 8769e4a56..b3c8f964d 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-32-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-100-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -114,108 +114,109 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 -
Zhang WH

💻 +
Pramod Gupta

👀 -
qza

💻 -
Rodolfo Forte

🖋 -
Ankur Kaushal

💻 -
Ovidijus Okinskas

💻 +
Amarnath Chandana

💻 +
Anurag870

💻 +
Wes Gilleland

💻 +
Harshraj Thakor

💻 -
Stamatis Pitsios

💻 -
Robert Kasperczyk

💻 -
田浩

🖋 -
gwildor28

💻 +
Martin Vandenbussche

💻 +
Alexandru Somai

💻 +
Artur Mogozov

💻 +
anthony

💻 -
Amit Pandey

💻 -
Hoswey

💻 -
Gopinath Langote

💻 -
Matt

🖋 +
Christian Cygnus

💻 +
Dima Gubin

💻 +
Joshua Jimenez

💻 +
Kai Winter

💻 -
gans

💻 -
Azureyjt

💻 -
Mahendran Mookkiah

💻 -
George Aristy

💻 +
lbroman

💻 +
Przemek

💻 +
Prafful Agarwal

🖋 +
Sanket Panhale

🖋 -
Kevin Peters

💻 -
Hemant Bothra

💻 -
George Mavroeidis

💻 -
Christopher O'Connell

💻 +
staillebois

💻 +
Krisztián Nagy

💻 +
Alexander Ivanov

💻 +
Yosfik Alqadri

💻 -
Leo Gutiérrez Ramírez

💻 -
Hannes

💻 -
Dominik Gruntz

💻 -
Christoffer Hamberg

💻 +
Agustí Becerra Milà

💻 +
Juan Manuel Suárez

💻 +
Luigi Cortese

💻 +
Katarzyna Rzepecka

💻 -
AnaghaSasikumar

💻 -
Evan Sia Wai Suan

💻 -
Per Wramdemark

💻 -
Leon Mak

💻 +
adamski.pro

💻 +
Shengli Bai

💻 +
Boris

💻 +
Dmitry Avershin

💻 -
kanwarpreet25

💻 -
M Saif Asif

💻 -
PhoenixYip

💻 -
Ranjeet

💻 - - -
Mitchell Irvin

💻 -
Arpit Jain

💻 -
hoangnam2261

💻
靳阳

💻 +
hoangnam2261

💻 +
Arpit Jain

💻 +
Jón Ingi Sveinbjörnsson

💻
Kirill Vlasov

💻 -
Jón Ingi Sveinbjörnsson

💻 -
Dmitry Avershin

💻 -
Boris

💻 +
Mitchell Irvin

💻 +
Ranjeet

💻 +
PhoenixYip

💻 -
Shengli Bai

💻 -
adamski.pro

💻 -
Katarzyna Rzepecka

💻 -
Luigi Cortese

💻 +
M Saif Asif

💻 +
kanwarpreet25

💻 +
Leon Mak

💻 +
Per Wramdemark

💻 -
Juan Manuel Suárez

💻 -
Agustí Becerra Milà

💻 -
Yosfik Alqadri

💻 -
Alexander Ivanov

💻 +
Evan Sia Wai Suan

💻 +
AnaghaSasikumar

💻 +
Christoffer Hamberg

💻 +
Dominik Gruntz

💻 -
Krisztián Nagy

💻 -
staillebois

💻 -
Sanket Panhale

🖋 -
Prafful Agarwal

🖋 +
Hannes

💻 +
Leo Gutiérrez Ramírez

💻 +
Zhang WH

💻 +
Christopher O'Connell

💻 -
Przemek

💻 -
lbroman

💻 -
Kai Winter

💻 -
Joshua Jimenez

💻 +
George Mavroeidis

💻 +
Hemant Bothra

💻 +
Kevin Peters

💻 +
George Aristy

💻 -
Dima Gubin

💻 -
Christian Cygnus

💻 -
anthony

💻 -
Artur Mogozov

💻 +
Mahendran Mookkiah

💻 +
Azureyjt

💻 +
gans

💻 +
Matt

🖋 -
Alexandru Somai

💻 -
Martin Vandenbussche

💻 -
Harshraj Thakor

💻 -
Wes Gilleland

💻 +
Gopinath Langote

💻 +
Hoswey

💻 +
Amit Pandey

💻 +
gwildor28

🖋 -
Anurag870

💻 -
Amarnath Chandana

💻 -
Pramod Gupta

👀 +
田浩

🖋 +
Stamatis Pitsios

💻 +
qza

💻 +
Rodolfo Forte

🖋 + + +
Ankur Kaushal

💻 +
Ovidijus Okinskas

💻 +
Robert Kasperczyk

💻 +
Tapio Rautonen

💻 From 075fbe74332aa7fec0a8420751d86ecca0bc79c0 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 20:04:33 +0300 Subject: [PATCH 174/211] docs: add yorlov as a contributor (#1446) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 5 ++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 57fed1a81..0fb6f83cc 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -911,6 +911,15 @@ "contributions": [ "code" ] + }, + { + "login": "yorlov", + "name": "Yuri Orlov", + "avatar_url": "https://avatars0.githubusercontent.com/u/1595733?v=4", + "profile": "http://vk.com/yuri.orlov", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 4, diff --git a/README.md b/README.md index b3c8f964d..a9889ab9e 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-100-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-101-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -218,6 +218,9 @@ This project is licensed under the terms of the MIT license.
Robert Kasperczyk

💻
Tapio Rautonen

💻 + +
Yuri Orlov

💻 + From 4db3a1cfb2dde15e545ee3ba2d5f6b06b6b46a32 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 20:06:01 +0300 Subject: [PATCH 175/211] docs: add varunu28 as a contributor (#1447) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 0fb6f83cc..17039ce00 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -920,6 +920,15 @@ "contributions": [ "code" ] + }, + { + "login": "varunu28", + "name": "Varun Upadhyay", + "avatar_url": "https://avatars0.githubusercontent.com/u/7676016?v=4", + "profile": "https://www.linkedin.com/in/varunu28/", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 4, diff --git a/README.md b/README.md index a9889ab9e..0a9b45188 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-101-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-102-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -220,6 +220,7 @@ This project is licensed under the terms of the MIT license.
Yuri Orlov

💻 +
Varun Upadhyay

💻 From 047285aed7742a7d93f8b7df33cc4ab170246122 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 20:07:30 +0300 Subject: [PATCH 176/211] docs: add PalAditya as a contributor (#1448) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 17039ce00..3ec5459fb 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -929,6 +929,15 @@ "contributions": [ "code" ] + }, + { + "login": "PalAditya", + "name": "Aditya Pal", + "avatar_url": "https://avatars2.githubusercontent.com/u/25523604?v=4", + "profile": "https://github.com/PalAditya", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 4, diff --git a/README.md b/README.md index 0a9b45188..0801c677c 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-102-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-103-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -221,6 +221,7 @@ This project is licensed under the terms of the MIT license.
Yuri Orlov

💻
Varun Upadhyay

💻 +
Aditya Pal

💻 From 51ef7176b191685edd39a71118dd3e5a6550e269 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 20:08:47 +0300 Subject: [PATCH 177/211] docs: add grzesiekkedzior as a contributor (#1449) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 3ec5459fb..c7a0d5b48 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -938,6 +938,15 @@ "contributions": [ "code" ] + }, + { + "login": "grzesiekkedzior", + "name": "grzesiekkedzior", + "avatar_url": "https://avatars3.githubusercontent.com/u/23739158?v=4", + "profile": "https://github.com/grzesiekkedzior", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 4, diff --git a/README.md b/README.md index 0801c677c..733bb5afb 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-103-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-104-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -222,6 +222,7 @@ This project is licensed under the terms of the MIT license.
Yuri Orlov

💻
Varun Upadhyay

💻
Aditya Pal

💻 +
grzesiekkedzior

💻 From f878bf63aa17e8d618865c9c3bba2bcbeb3ebf17 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 20:11:51 +0300 Subject: [PATCH 178/211] docs: add sivasubramanim as a contributor (#1450) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 5 ++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index c7a0d5b48..3a791df55 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -947,6 +947,15 @@ "contributions": [ "code" ] + }, + { + "login": "sivasubramanim", + "name": "Sivasubramani M", + "avatar_url": "https://avatars2.githubusercontent.com/u/51107434?v=4", + "profile": "https://github.com/sivasubramanim", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 4, diff --git a/README.md b/README.md index 733bb5afb..5ecb3a77e 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-104-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-105-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -224,6 +224,9 @@ This project is licensed under the terms of the MIT license.
Aditya Pal

💻
grzesiekkedzior

💻 + +
Sivasubramani M

💻 + From f49f9a15b6a2a470a16ad9446f459f12ec8b32d8 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 20:13:24 +0300 Subject: [PATCH 179/211] docs: add d4gg4d as a contributor (#1451) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 3a791df55..b49ea6397 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -956,6 +956,15 @@ "contributions": [ "code" ] + }, + { + "login": "d4gg4d", + "name": "Sami Airaksinen", + "avatar_url": "https://avatars2.githubusercontent.com/u/99457?v=4", + "profile": "https://github.com/d4gg4d", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 4, diff --git a/README.md b/README.md index 5ecb3a77e..c4d62eae4 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-105-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-106-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -226,6 +226,7 @@ This project is licensed under the terms of the MIT license.
Sivasubramani M

💻 +
Sami Airaksinen

💻 From c9e30390d36209c58028674d87052a3cc66ba19f Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 20:14:42 +0300 Subject: [PATCH 180/211] docs: add vertti as a contributor (#1452) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index b49ea6397..edc3b8767 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -965,6 +965,15 @@ "contributions": [ "code" ] + }, + { + "login": "vertti", + "name": "Janne Sinivirta", + "avatar_url": "https://avatars0.githubusercontent.com/u/557751?v=4", + "profile": "https://github.com/vertti", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 4, diff --git a/README.md b/README.md index c4d62eae4..e7902e395 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-106-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-107-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -227,6 +227,7 @@ This project is licensed under the terms of the MIT license.
Sivasubramani M

💻
Sami Airaksinen

💻 +
Janne Sinivirta

💻 From f2ac53edcad689ee382c701bd24eb4f736a7c0a2 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 20:16:54 +0300 Subject: [PATCH 181/211] docs: add Bobo1239 as a contributor (#1453) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index edc3b8767..b62e7856c 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -974,6 +974,15 @@ "contributions": [ "code" ] + }, + { + "login": "Bobo1239", + "name": "Boris-Chengbiao Zhou", + "avatar_url": "https://avatars1.githubusercontent.com/u/2302947?v=4", + "profile": "https://github.com/Bobo1239", + "contributions": [ + "content" + ] } ], "contributorsPerLine": 4, diff --git a/README.md b/README.md index e7902e395..65f05e5ba 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-107-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-108-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -228,6 +228,7 @@ This project is licensed under the terms of the MIT license.
Sivasubramani M

💻
Sami Airaksinen

💻
Janne Sinivirta

💻 +
Boris-Chengbiao Zhou

🖋 From de79019ece03d380534f6d21f4230eca81bf4535 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 20:18:15 +0300 Subject: [PATCH 182/211] docs: add Jahhein as a contributor (#1454) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 5 ++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index b62e7856c..7ae53172f 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -983,6 +983,15 @@ "contributions": [ "content" ] + }, + { + "login": "Jahhein", + "name": "Jacob Hein", + "avatar_url": "https://avatars2.githubusercontent.com/u/10779515?v=4", + "profile": "https://jahhein.github.io", + "contributions": [ + "content" + ] } ], "contributorsPerLine": 4, diff --git a/README.md b/README.md index 65f05e5ba..adbc505a3 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-108-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-109-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -230,6 +230,9 @@ This project is licensed under the terms of the MIT license.
Janne Sinivirta

💻
Boris-Chengbiao Zhou

🖋 + +
Jacob Hein

🖋 + From ec7a2025f088e9c08629f7c2bf8b1d2815310946 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 20:19:47 +0300 Subject: [PATCH 183/211] docs: add iamrichardjones as a contributor (#1455) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 7ae53172f..46558d4fa 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -992,6 +992,15 @@ "contributions": [ "content" ] + }, + { + "login": "iamrichardjones", + "name": "Richard Jones", + "avatar_url": "https://avatars3.githubusercontent.com/u/14842151?v=4", + "profile": "https://github.com/iamrichardjones", + "contributions": [ + "content" + ] } ], "contributorsPerLine": 4, diff --git a/README.md b/README.md index adbc505a3..6b601290a 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-109-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-110-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -232,6 +232,7 @@ This project is licensed under the terms of the MIT license.
Jacob Hein

🖋 +
Richard Jones

🖋 From 1e38edec151b59c6aa3c1c3907bf967ba1b3359f Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 20:21:07 +0300 Subject: [PATCH 184/211] docs: add rachelcarmena as a contributor (#1456) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 46558d4fa..e203d5615 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1001,6 +1001,15 @@ "contributions": [ "content" ] + }, + { + "login": "rachelcarmena", + "name": "Rachel M. Carmena", + "avatar_url": "https://avatars0.githubusercontent.com/u/22792183?v=4", + "profile": "https://rachelcarmena.github.io", + "contributions": [ + "content" + ] } ], "contributorsPerLine": 4, diff --git a/README.md b/README.md index 6b601290a..4b128803a 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-110-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-111-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -233,6 +233,7 @@ This project is licensed under the terms of the MIT license.
Jacob Hein

🖋
Richard Jones

🖋 +
Rachel M. Carmena

🖋 From 6a28d09a3c3fe781d1a1f92743c2a46636230309 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 20:22:29 +0300 Subject: [PATCH 185/211] docs: add zd-zero as a contributor (#1457) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index e203d5615..038baf8ec 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1010,6 +1010,15 @@ "contributions": [ "content" ] + }, + { + "login": "zd-zero", + "name": "Zaerald Denze Lungos", + "avatar_url": "https://avatars0.githubusercontent.com/u/21978370?v=4", + "profile": "https://zd-zero.github.io", + "contributions": [ + "content" + ] } ], "contributorsPerLine": 4, diff --git a/README.md b/README.md index 4b128803a..a5b0e8a73 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-111-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-112-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -234,6 +234,7 @@ This project is licensed under the terms of the MIT license.
Jacob Hein

🖋
Richard Jones

🖋
Rachel M. Carmena

🖋 +
Zaerald Denze Lungos

🖋 From 402b753480b517257d26f96de76e445922f4d8e5 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 20:24:01 +0300 Subject: [PATCH 186/211] docs: add webpro as a contributor (#1458) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 5 ++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 038baf8ec..c9e63d0b3 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1019,6 +1019,15 @@ "contributions": [ "content" ] + }, + { + "login": "webpro", + "name": "Lars Kappert", + "avatar_url": "https://avatars1.githubusercontent.com/u/456426?v=4", + "profile": "https://webpro.nl", + "contributions": [ + "content" + ] } ], "contributorsPerLine": 4, diff --git a/README.md b/README.md index a5b0e8a73..731f334f7 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-112-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-113-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -236,6 +236,9 @@ This project is licensed under the terms of the MIT license.
Rachel M. Carmena

🖋
Zaerald Denze Lungos

🖋 + +
Lars Kappert

🖋 + From f95aadc8f54068c87430d7077903126c2b8a4e65 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 20:42:45 +0300 Subject: [PATCH 187/211] docs: add hbothra15 as a contributor (#1459) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] * fix merge Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 3 ++- README.md | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index c9e63d0b3..da6e03b58 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -747,7 +747,8 @@ "avatar_url": "https://avatars1.githubusercontent.com/u/7418012?v=4", "profile": "https://github.com/hbothra15", "contributions": [ - "code" + "code", + "design" ] }, { diff --git a/README.md b/README.md index 731f334f7..96ad7b25c 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 -
Pramod Gupta

👀 +
Hemant Bothra

💻 🎨
Amarnath Chandana

💻 @@ -237,6 +237,7 @@ This project is licensed under the terms of the MIT license.
Zaerald Denze Lungos

🖋 +
Pramod Gupta

👀
Lars Kappert

🖋 From 5381387026365f3800859a4c64118b99e3dcd328 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 21:03:29 +0300 Subject: [PATCH 188/211] docs: add xiaod-dev as a contributor (#1460) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 8 ++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index da6e03b58..9a536d34d 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1029,6 +1029,15 @@ "contributions": [ "content" ] + }, + { + "login": "xiaod-dev", + "name": "Mike Liu", + "avatar_url": "https://avatars2.githubusercontent.com/u/21277644?v=4", + "profile": "https://xiaod.info", + "contributions": [ + "translation" + ] } ], "contributorsPerLine": 4, diff --git a/README.md b/README.md index 96ad7b25c..d3c815cb3 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-113-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-114-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -114,7 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 -
Hemant Bothra

💻 🎨 +
Pramod Gupta

👀
Amarnath Chandana

💻 @@ -190,7 +190,7 @@ This project is licensed under the terms of the MIT license.
George Mavroeidis

💻 -
Hemant Bothra

💻 +
Hemant Bothra

💻 🎨
Kevin Peters

💻
George Aristy

💻 @@ -237,8 +237,8 @@ This project is licensed under the terms of the MIT license.
Zaerald Denze Lungos

🖋 -
Pramod Gupta

👀
Lars Kappert

🖋 +
Mike Liu

🌍 From 417f21ed3dda41d65e7d748c5aff8a168840b788 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Thu, 30 Jul 2020 20:28:47 +0300 Subject: [PATCH 189/211] Code cleanup (#1461) * Code cleanup * Fix flux tests * Fix checkstyle errors * Fix compile error --- .../AbstractDocumentTest.java | 2 +- .../abstractfactory/AbstractFactoryTest.java | 2 +- .../ConfigureForDosVisitorTest.java | 2 +- adapter/README.md | 4 +- .../iluwatar/adapter/FishingBoatAdapter.java | 2 +- .../ambassador/RemoteServiceTest.java | 2 +- .../invocation/ThreadAsyncExecutor.java | 2 +- .../iluwatar/business/delegate/Client.java | 2 +- .../business/delegate/ServiceType.java | 2 +- .../com/iluwatar/bytecode/VirtualMachine.java | 4 +- .../iluwatar/bytecode/VirtualMachineTest.java | 2 +- .../com/iluwatar/caching/CachingPolicy.java | 2 +- chain/README.md | 2 +- .../com/iluwatar/chain/RequestHandler.java | 2 +- .../com/iluwatar/collectionpipeline/Car.java | 5 +- .../iluwatar/collectionpipeline/Person.java | 2 +- .../iluwatar/collectionpipeline/AppTest.java | 2 +- command/README.md | 4 +- .../main/java/com/iluwatar/command/Size.java | 86 ++++---- .../java/com/iluwatar/command/Visibility.java | 86 ++++---- .../java/com/iluwatar/command/Wizard.java | 4 +- .../employeehandle/EmployeeDatabase.java | 2 +- .../messagingservice/MessagingDatabase.java | 2 +- .../paymentservice/PaymentDatabase.java | 2 +- .../commander/queue/QueueDatabase.java | 2 +- .../shippingservice/ShippingDatabase.java | 2 +- composite/README.md | 4 +- .../java/com/iluwatar/composite/Letter.java | 2 +- .../iluwatar/composite/LetterComposite.java | 116 +++++------ .../java/com/iluwatar/converter/User.java | 8 +- .../java/com/iluwatar/converter/UserDto.java | 8 +- .../com/iluwatar/converter/ConverterTest.java | 2 +- .../cqrs/commandes/CommandServiceImpl.java | 2 +- .../cqrs/queries/QueryServiceImpl.java | 2 +- dao/README.md | 2 +- dao/src/main/java/com/iluwatar/dao/App.java | 2 +- .../com/iluwatar/dao/InMemoryCustomerDao.java | 2 +- .../com/iluwatar/dao/DbCustomerDaoTest.java | 2 +- .../members/MessageCollectorMember.java | 2 +- .../java/com/iluwatar/datamapper/App.java | 166 ++++++++-------- .../datamapper/StudentDataMapperImpl.java | 2 +- data-transfer-object/README.md | 2 +- .../datatransfer/CustomerResource.java | 2 +- decorator/README.md | 2 +- .../com/iluwatar/decorator/ClubbedTroll.java | 2 +- .../iluwatar/decorator/SimpleTrollTest.java | 2 +- .../delegation/simple/DelegateTest.java | 2 +- dependency-injection/README.md | 2 +- .../dependency/injection/AdvancedWizard.java | 2 +- .../dependency/injection/GuiceWizard.java | 2 +- .../dependency/injection/SimpleWizard.java | 2 +- .../injection/utils/InMemoryAppender.java | 2 +- .../java/com/iluwatar/dirtyflag/World.java | 2 +- .../iluwatar/doublebuffer/FrameBuffer.java | 2 +- .../java/com/iluwatar/doublebuffer/Pixel.java | 2 +- .../java/com/iluwatar/doublebuffer/Scene.java | 2 +- .../doublechecked/locking/InventoryTest.java | 2 +- .../iluwatar/doubledispatch/Rectangle.java | 8 +- .../com/iluwatar/event/aggregator/Event.java | 2 +- .../event/aggregator/EventEmitter.java | 2 +- .../iluwatar/event/aggregator/Weekday.java | 2 +- .../event/aggregator/KingJoffreyTest.java | 2 +- .../iluwatar/event/asynchronous/Event.java | 6 +- .../event/asynchronous/EventManager.java | 4 +- .../iluwatar/eda/event/UserCreatedEvent.java | 2 +- .../iluwatar/eda/event/UserUpdatedEvent.java | 2 +- .../eda/framework/EventDispatcher.java | 2 +- .../java/com/iluwatar/eda/model/User.java | 2 +- .../java/com/iluwatar/event/queue/Audio.java | 2 +- .../java/concreteextensions/Commander.java | 2 +- .../java/concreteextensions/Sergeant.java | 2 +- .../main/java/concreteextensions/Soldier.java | 2 +- facade/README.md | 2 +- .../facade/DwarvenGoldmineFacadeTest.java | 2 +- .../factory/method/ElfBlacksmith.java | 2 +- .../iluwatar/factory/method/ElfWeapon.java | 2 +- .../factory/method/OrcBlacksmith.java | 2 +- .../iluwatar/factory/method/OrcWeapon.java | 2 +- .../iluwatar/factory/method/WeaponType.java | 2 +- .../PropertiesFeatureToggleVersion.java | 2 +- .../com/iluwatar/featuretoggle/user/User.java | 2 +- .../featuretoggle/user/UserGroup.java | 4 +- .../com/iluwatar/fluentinterface/app/App.java | 2 +- .../lazy/LazyFluentIterable.java | 2 +- .../java/com/iluwatar/flux/action/Action.java | 2 +- .../com/iluwatar/flux/action/ActionType.java | 2 +- .../com/iluwatar/flux/action/Content.java | 2 +- .../iluwatar/flux/action/ContentAction.java | 2 +- .../com/iluwatar/flux/action/MenuAction.java | 2 +- .../com/iluwatar/flux/action/MenuItem.java | 2 +- .../iluwatar/flux/dispatcher/Dispatcher.java | 2 +- .../java/com/iluwatar/flux/store/Store.java | 2 +- .../com/iluwatar/flyweight/AlchemistShop.java | 4 +- .../controller/utils/InMemoryAppender.java | 2 +- .../com/iluwatar/halfsynchalfasync/App.java | 2 +- .../AsynchronousService.java | 2 +- .../hexagonal/banking/InMemoryBank.java | 2 +- .../database/InMemoryTicketRepository.java | 2 +- .../hexagonal/domain/LotteryNumbers.java | 2 +- .../hexagonal/domain/LotteryTicketId.java | 2 +- .../hexagonal/eventlog/MongoEventLog.java | 2 +- .../hexagonal/domain/LotteryTest.java | 2 +- .../iluwatar/intercepting/filter/Client.java | 10 +- .../intercepting/filter/FilterManager.java | 2 +- .../iluwatar/intercepting/filter/Target.java | 6 +- .../iluwatar/interpreter/MinusExpression.java | 4 +- .../interpreter/MultiplyExpression.java | 4 +- .../interpreter/NumberExpression.java | 2 +- .../iluwatar/interpreter/PlusExpression.java | 4 +- iterator/README.md | 4 +- .../iluwatar/iterator/bst/BstIterator.java | 2 +- .../com/iluwatar/iterator/bst/TreeNode.java | 2 +- .../java/com/iluwatar/iterator/list/Item.java | 2 +- .../iluwatar/iterator/list/TreasureChest.java | 2 +- .../list/TreasureChestItemIterator.java | 4 +- layers/README.md | 2 +- .../java/com/iluwatar/layers/app/App.java | 2 +- .../layers/service/CakeBakingServiceImpl.java | 2 +- .../iluwatar/layers/view/CakeViewImpl.java | 2 +- .../layers/view/CakeViewImplTest.java | 2 +- .../iluwatar/lazy/loading/Java8Holder.java | 2 +- .../com.iluwatar.leaderfollowers/TaskSet.java | 2 +- .../WorkCenter.java | 2 +- .../system/systemmaster/Master.java | 2 +- .../java/com/iluwatar/mediator/Action.java | 104 +++++----- .../iluwatar/mediator/PartyMemberTest.java | 2 +- memento/README.md | 2 +- .../java/com/iluwatar/memento/StarType.java | 2 +- .../model/view/controller/Fatigue.java | 2 +- .../view/controller/GiantController.java | 4 +- .../model/view/controller/Health.java | 2 +- .../model/view/controller/Nourishment.java | 2 +- .../model/view/controller/GiantViewTest.java | 2 +- .../view/presenter/FileSelectorJFrame.java | 14 +- .../view/presenter/FileSelectorPresenter.java | 2 +- .../main/java/com/iluwatar/monad/User.java | 132 ++++++------- multiton/README.md | 6 +- .../java/com/iluwatar/multiton/Nazgul.java | 4 +- .../com/iluwatar/multiton/NazgulEnum.java | 2 +- .../com/iluwatar/multiton/NazgulName.java | 2 +- null-object/README.md | 2 +- .../com/iluwatar/nullobject/NullNode.java | 2 +- .../com/iluwatar/nullobject/TreeTest.java | 2 +- .../java/com/iluwatar/objectmother/Queen.java | 5 +- object-pool/README.md | 6 +- .../com/iluwatar/object/pool/ObjectPool.java | 4 +- .../com/iluwatar/object/pool/Oliphaunt.java | 2 +- observer/README.md | 2 +- .../java/com/iluwatar/observer/Weather.java | 2 +- .../observer/utils/InMemoryAppender.java | 2 +- .../pageobject/AlbumListPageTest.java | 2 +- .../iluwatar/pageobject/AlbumPageTest.java | 2 +- .../iluwatar/pageobject/LoginPageTest.java | 2 +- .../pageobject/AlbumListPageTest.java | 2 +- .../iluwatar/pageobject/AlbumPageTest.java | 2 +- .../iluwatar/pageobject/LoginPageTest.java | 2 +- .../partialresponse/VideoResource.java | 4 +- poison-pill/README.md | 2 +- .../iluwatar/poison/pill/SimpleMessage.java | 2 +- .../iluwatar/poison/pill/ConsumerTest.java | 2 +- .../privateclassdata/ImmutableStew.java | 100 +++++----- .../iluwatar/privateclassdata/StewData.java | 122 ++++++------ .../utils/InMemoryAppender.java | 2 +- .../com/iluwatar/producer/consumer/Item.java | 4 +- .../iluwatar/producer/consumer/ItemQueue.java | 2 +- .../java/com/iluwatar/prototype/ElfBeast.java | 2 +- .../java/com/iluwatar/prototype/ElfMage.java | 2 +- .../com/iluwatar/prototype/ElfWarlord.java | 2 +- .../iluwatar/prototype/HeroFactoryImpl.java | 130 ++++++------ .../java/com/iluwatar/prototype/OrcBeast.java | 2 +- .../java/com/iluwatar/prototype/OrcMage.java | 2 +- .../com/iluwatar/prototype/OrcWarlord.java | 2 +- .../proxy/utils/InMemoryAppender.java | 2 +- .../java/com/iluwatar/reactor/app/App.java | 4 +- .../reactor/framework/NioDatagramChannel.java | 2 +- .../reactor/framework/NioReactor.java | 4 +- .../iluwatar/reader/writer/lock/Reader.java | 6 +- .../reader/writer/lock/ReaderWriterLock.java | 4 +- .../iluwatar/reader/writer/lock/Writer.java | 6 +- .../writer/lock/utils/InMemoryAppender.java | 2 +- repository/README.md | 4 +- .../repository/PersonSpecifications.java | 4 +- .../AnnotationBasedRepositoryTest.java | 10 +- .../iluwatar/repository/RepositoryTest.java | 10 +- .../is/initialization/ClosableTest.java | 2 +- .../com/iluwatar/roleobject/CustomerCore.java | 2 +- .../java/com/iluwatar/roleobject/Role.java | 2 +- .../com/iluwatar/saga/choreography/Saga.java | 4 +- .../choreography/ServiceDiscoveryService.java | 2 +- .../saga/orchestration/ChapterResult.java | 4 +- .../com/iluwatar/saga/orchestration/Saga.java | 2 +- .../ServiceDiscoveryService.java | 2 +- .../SagaOrchestratorInternallyTest.java | 2 +- .../java/com/iluwatar/semaphore/Fruit.java | 2 +- .../com/iluwatar/semaphore/FruitBowl.java | 2 +- .../com/iluwatar/semaphore/FruitShop.java | 6 +- .../main/java/com/iluwatar/servant/App.java | 4 +- .../baas/api/AbstractDynamoDbHandler.java | 2 +- .../baas/api/SavePersonApiHandlerTest.java | 2 +- service-layer/README.md | 6 +- .../servicelayer/magic/MagicServiceImpl.java | 6 +- .../servicelocator/ServiceLocator.java | 2 +- .../iluwatar/sharding/LookupShardManager.java | 2 +- .../java/com/iluwatar/sharding/Shard.java | 2 +- singleton/README.md | 2 +- specification/README.md | 2 +- .../creature/AbstractCreature.java | 10 +- .../specification/property/Color.java | 2 +- .../iluwatar/specification/property/Mass.java | 4 +- .../specification/property/Movement.java | 2 +- .../iluwatar/specification/property/Size.java | 2 +- .../selector/ConjunctionSelector.java | 2 +- .../selector/DisjunctionSelector.java | 2 +- .../selector/NegationSelector.java | 2 +- state/README.md | 4 +- .../java/com/iluwatar/state/AngryState.java | 104 +++++----- .../com/iluwatar/state/PeacefulState.java | 104 +++++----- .../java/com/iluwatar/state/MammothTest.java | 2 +- .../stepbuilder/CharacterStepBuilder.java | 2 +- .../strategy/DragonSlayingStrategyTest.java | 2 +- .../templatemethod/StealingMethodTest.java | 2 +- throttling/README.md | 6 +- .../com/iluwatar/throttling/CallsCount.java | 2 +- .../java/com/iluwatar/throttling/Tenant.java | 4 +- .../iluwatar/throttling/B2BServiceTest.java | 2 +- .../com/iluwatar/tls/DateFormatCallable.java | 186 +++++++++--------- .../main/java/com/iluwatar/tls/Result.java | 130 ++++++------ .../iluwatar/tls/DateFormatCallableTest.java | 6 +- ...FormatCallableTestIncorrectDateFormat.java | 6 +- .../DateFormatCallableTestMultiThread.java | 10 +- tolerant-reader/README.md | 8 +- .../iluwatar/tolerantreader/RainbowFish.java | 8 +- .../java/com/iluwatar/twin/BallItemTest.java | 2 +- .../java/com/iluwatar/typeobject/App.java | 2 +- .../java/com/iluwatar/typeobject/Candy.java | 2 +- .../com/iluwatar/typeobject/CellPool.java | 2 +- unit-of-work/README.md | 4 +- .../unitofwork/StudentRepository.java | 4 +- .../java/com/iluwatar/updatemethod/World.java | 3 +- .../com/iluwatar/value/object/HeroStat.java | 5 +- visitor/README.md | 2 +- .../main/java/com/iluwatar/visitor/Unit.java | 90 ++++----- .../com/iluwatar/visitor/VisitorTest.java | 2 +- 243 files changed, 1154 insertions(+), 1162 deletions(-) diff --git a/abstract-document/src/test/java/com/iluwatar/abstractdocument/AbstractDocumentTest.java b/abstract-document/src/test/java/com/iluwatar/abstractdocument/AbstractDocumentTest.java index d7fe5688d..c0791c30b 100644 --- a/abstract-document/src/test/java/com/iluwatar/abstractdocument/AbstractDocumentTest.java +++ b/abstract-document/src/test/java/com/iluwatar/abstractdocument/AbstractDocumentTest.java @@ -47,7 +47,7 @@ public class AbstractDocumentTest { } } - private DocumentImplementation document = new DocumentImplementation(new HashMap<>()); + private final DocumentImplementation document = new DocumentImplementation(new HashMap<>()); @Test public void shouldPutAndGetValue() { diff --git a/abstract-factory/src/test/java/com/iluwatar/abstractfactory/AbstractFactoryTest.java b/abstract-factory/src/test/java/com/iluwatar/abstractfactory/AbstractFactoryTest.java index be83cc315..f3db525a1 100644 --- a/abstract-factory/src/test/java/com/iluwatar/abstractfactory/AbstractFactoryTest.java +++ b/abstract-factory/src/test/java/com/iluwatar/abstractfactory/AbstractFactoryTest.java @@ -36,7 +36,7 @@ import org.junit.jupiter.api.Test; */ public class AbstractFactoryTest { - private App app = new App(); + private final App app = new App(); private KingdomFactory elfFactory; private KingdomFactory orcFactory; diff --git a/acyclic-visitor/src/test/java/com/iluwatar/acyclicvisitor/ConfigureForDosVisitorTest.java b/acyclic-visitor/src/test/java/com/iluwatar/acyclicvisitor/ConfigureForDosVisitorTest.java index 8847a131e..79097a454 100644 --- a/acyclic-visitor/src/test/java/com/iluwatar/acyclicvisitor/ConfigureForDosVisitorTest.java +++ b/acyclic-visitor/src/test/java/com/iluwatar/acyclicvisitor/ConfigureForDosVisitorTest.java @@ -37,7 +37,7 @@ import uk.org.lidalia.slf4jtest.TestLoggerFactory; */ public class ConfigureForDosVisitorTest { - private TestLogger logger = TestLoggerFactory.getTestLogger(ConfigureForDosVisitor.class); + private final TestLogger logger = TestLoggerFactory.getTestLogger(ConfigureForDosVisitor.class); @Test public void testVisitForZoom() { diff --git a/adapter/README.md b/adapter/README.md index b36558cbc..75edad180 100644 --- a/adapter/README.md +++ b/adapter/README.md @@ -56,7 +56,7 @@ And captain expects an implementation of `RowingBoat` interface to be able to mo ```java public class Captain { - private RowingBoat rowingBoat; + private final RowingBoat rowingBoat; // default constructor and setter for rowingBoat public Captain(RowingBoat rowingBoat) { this.rowingBoat = rowingBoat; @@ -75,7 +75,7 @@ public class FishingBoatAdapter implements RowingBoat { private static final Logger LOGGER = LoggerFactory.getLogger(FishingBoatAdapter.class); - private FishingBoat boat; + private final FishingBoat boat; public FishingBoatAdapter() { boat = new FishingBoat(); diff --git a/adapter/src/main/java/com/iluwatar/adapter/FishingBoatAdapter.java b/adapter/src/main/java/com/iluwatar/adapter/FishingBoatAdapter.java index 5ccde5c53..39a9adab4 100644 --- a/adapter/src/main/java/com/iluwatar/adapter/FishingBoatAdapter.java +++ b/adapter/src/main/java/com/iluwatar/adapter/FishingBoatAdapter.java @@ -29,7 +29,7 @@ package com.iluwatar.adapter; */ public class FishingBoatAdapter implements RowingBoat { - private FishingBoat boat; + private final FishingBoat boat; public FishingBoatAdapter() { boat = new FishingBoat(); diff --git a/ambassador/src/test/java/com/iluwatar/ambassador/RemoteServiceTest.java b/ambassador/src/test/java/com/iluwatar/ambassador/RemoteServiceTest.java index 3cfea2623..6c45acf66 100644 --- a/ambassador/src/test/java/com/iluwatar/ambassador/RemoteServiceTest.java +++ b/ambassador/src/test/java/com/iluwatar/ambassador/RemoteServiceTest.java @@ -48,7 +48,7 @@ class RemoteServiceTest { } private static class StaticRandomProvider implements RandomProvider { - private double value; + private final double value; StaticRandomProvider(double value) { this.value = value; 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 7bdf84171..e430e9ce4 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 @@ -100,7 +100,7 @@ public class ThreadAsyncExecutor implements AsyncExecutor { void setValue(T value) { this.value = value; this.state = COMPLETED; - this.callback.ifPresent(ac -> ac.onComplete(value, Optional.empty())); + this.callback.ifPresent(ac -> ac.onComplete(value, Optional.empty())); synchronized (lock) { lock.notifyAll(); } 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 dcf4ce6b2..2c13bc149 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 @@ -28,7 +28,7 @@ package com.iluwatar.business.delegate; */ public class Client { - private BusinessDelegate businessDelegate; + private final BusinessDelegate businessDelegate; public Client(BusinessDelegate businessDelegate) { this.businessDelegate = businessDelegate; 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 87fd1562d..c0f02b5e3 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 @@ -28,5 +28,5 @@ package com.iluwatar.business.delegate; */ public enum ServiceType { - EJB, JMS; + EJB, JMS } diff --git a/bytecode/src/main/java/com/iluwatar/bytecode/VirtualMachine.java b/bytecode/src/main/java/com/iluwatar/bytecode/VirtualMachine.java index 5afc2fb93..c45301c29 100644 --- a/bytecode/src/main/java/com/iluwatar/bytecode/VirtualMachine.java +++ b/bytecode/src/main/java/com/iluwatar/bytecode/VirtualMachine.java @@ -30,9 +30,9 @@ import java.util.Stack; */ public class VirtualMachine { - private Stack stack = new Stack<>(); + private final Stack stack = new Stack<>(); - private Wizard[] wizards = new Wizard[2]; + private final Wizard[] wizards = new Wizard[2]; /** * Constructor. diff --git a/bytecode/src/test/java/com/iluwatar/bytecode/VirtualMachineTest.java b/bytecode/src/test/java/com/iluwatar/bytecode/VirtualMachineTest.java index 61a316f5a..4518ca310 100644 --- a/bytecode/src/test/java/com/iluwatar/bytecode/VirtualMachineTest.java +++ b/bytecode/src/test/java/com/iluwatar/bytecode/VirtualMachineTest.java @@ -104,7 +104,7 @@ public class VirtualMachineTest { bytecode[2] = LITERAL.getIntValue(); bytecode[3] = 50; // health amount bytecode[4] = SET_HEALTH.getIntValue(); - bytecode[5] = LITERAL.getIntValue();; + bytecode[5] = LITERAL.getIntValue(); bytecode[6] = wizardNumber; bytecode[7] = GET_HEALTH.getIntValue(); diff --git a/caching/src/main/java/com/iluwatar/caching/CachingPolicy.java b/caching/src/main/java/com/iluwatar/caching/CachingPolicy.java index 6bc6dbd77..84b8307f3 100644 --- a/caching/src/main/java/com/iluwatar/caching/CachingPolicy.java +++ b/caching/src/main/java/com/iluwatar/caching/CachingPolicy.java @@ -29,7 +29,7 @@ package com.iluwatar.caching; public enum CachingPolicy { THROUGH("through"), AROUND("around"), BEHIND("behind"), ASIDE("aside"); - private String policy; + private final String policy; CachingPolicy(String policy) { this.policy = policy; diff --git a/chain/README.md b/chain/README.md index cdc5966bd..f11f0c59e 100644 --- a/chain/README.md +++ b/chain/README.md @@ -65,7 +65,7 @@ Then the request handler hierarchy ```java public abstract class RequestHandler { private static final Logger LOGGER = LoggerFactory.getLogger(RequestHandler.class); - private RequestHandler next; + private final RequestHandler next; public RequestHandler(RequestHandler next) { this.next = next; diff --git a/chain/src/main/java/com/iluwatar/chain/RequestHandler.java b/chain/src/main/java/com/iluwatar/chain/RequestHandler.java index 7923f03a6..4778ecf91 100644 --- a/chain/src/main/java/com/iluwatar/chain/RequestHandler.java +++ b/chain/src/main/java/com/iluwatar/chain/RequestHandler.java @@ -33,7 +33,7 @@ public abstract class RequestHandler { private static final Logger LOGGER = LoggerFactory.getLogger(RequestHandler.class); - private RequestHandler next; + private final RequestHandler next; public RequestHandler(RequestHandler next) { this.next = next; diff --git a/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/Car.java b/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/Car.java index 2828cffd4..cffdc7c82 100644 --- a/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/Car.java +++ b/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/Car.java @@ -87,10 +87,7 @@ public class Car { } else if (!model.equals(other.model)) { return false; } - if (year != other.year) { - return false; - } - return true; + return year == other.year; } public String getMake() { diff --git a/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/Person.java b/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/Person.java index 2e564b701..3e25f6993 100644 --- a/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/Person.java +++ b/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/Person.java @@ -29,7 +29,7 @@ import java.util.List; * A Person class that has the list of cars that the person owns and use. */ public class Person { - private List cars; + private final List cars; /** * Constructor to create an instance of person. diff --git a/collection-pipeline/src/test/java/com/iluwatar/collectionpipeline/AppTest.java b/collection-pipeline/src/test/java/com/iluwatar/collectionpipeline/AppTest.java index 6bf373e81..cedc492b9 100644 --- a/collection-pipeline/src/test/java/com/iluwatar/collectionpipeline/AppTest.java +++ b/collection-pipeline/src/test/java/com/iluwatar/collectionpipeline/AppTest.java @@ -37,7 +37,7 @@ import org.slf4j.LoggerFactory; public class AppTest { private static final Logger LOGGER = LoggerFactory.getLogger(AppTest.class); - private List cars = CarFactory.createCars(); + private final List cars = CarFactory.createCars(); @Test public void testGetModelsAfter2000UsingFor() { diff --git a/command/README.md b/command/README.md index 02a290e4d..fc0a11d9f 100644 --- a/command/README.md +++ b/command/README.md @@ -36,8 +36,8 @@ public class Wizard { private static final Logger LOGGER = LoggerFactory.getLogger(Wizard.class); - private Deque undoStack = new LinkedList<>(); - private Deque redoStack = new LinkedList<>(); + private final Deque undoStack = new LinkedList<>(); + private final Deque redoStack = new LinkedList<>(); public Wizard() {} diff --git a/command/src/main/java/com/iluwatar/command/Size.java b/command/src/main/java/com/iluwatar/command/Size.java index ae327d8b1..c9aeb7017 100644 --- a/command/src/main/java/com/iluwatar/command/Size.java +++ b/command/src/main/java/com/iluwatar/command/Size.java @@ -1,43 +1,43 @@ -/* - * 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.command; - -/** - * Enumeration for target size. - */ -public enum Size { - - SMALL("small"), NORMAL("normal"); - - private String title; - - Size(String title) { - this.title = title; - } - - @Override - public String toString() { - return title; - } -} +/* + * 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.command; + +/** + * Enumeration for target size. + */ +public enum Size { + + SMALL("small"), NORMAL("normal"); + + private final String title; + + Size(String title) { + this.title = title; + } + + @Override + public String toString() { + return title; + } +} diff --git a/command/src/main/java/com/iluwatar/command/Visibility.java b/command/src/main/java/com/iluwatar/command/Visibility.java index 3c48990a0..8fe0ce7bb 100644 --- a/command/src/main/java/com/iluwatar/command/Visibility.java +++ b/command/src/main/java/com/iluwatar/command/Visibility.java @@ -1,43 +1,43 @@ -/* - * 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.command; - -/** - * Enumeration for target visibility. - */ -public enum Visibility { - - VISIBLE("visible"), INVISIBLE("invisible"); - - private String title; - - Visibility(String title) { - this.title = title; - } - - @Override - public String toString() { - return title; - } -} +/* + * 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.command; + +/** + * Enumeration for target visibility. + */ +public enum Visibility { + + VISIBLE("visible"), INVISIBLE("invisible"); + + private final String title; + + Visibility(String title) { + this.title = 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 e0b973265..dd469d3c0 100644 --- a/command/src/main/java/com/iluwatar/command/Wizard.java +++ b/command/src/main/java/com/iluwatar/command/Wizard.java @@ -35,8 +35,8 @@ public class Wizard { private static final Logger LOGGER = LoggerFactory.getLogger(Wizard.class); - private Deque undoStack = new LinkedList<>(); - private Deque redoStack = new LinkedList<>(); + private final Deque undoStack = new LinkedList<>(); + private final Deque redoStack = new LinkedList<>(); public Wizard() { // comment to ignore sonar issue: LEVEL critical diff --git a/commander/src/main/java/com/iluwatar/commander/employeehandle/EmployeeDatabase.java b/commander/src/main/java/com/iluwatar/commander/employeehandle/EmployeeDatabase.java index 496bb545a..69ebc1fd9 100644 --- a/commander/src/main/java/com/iluwatar/commander/employeehandle/EmployeeDatabase.java +++ b/commander/src/main/java/com/iluwatar/commander/employeehandle/EmployeeDatabase.java @@ -33,7 +33,7 @@ import java.util.Hashtable; */ public class EmployeeDatabase extends Database { - private Hashtable data; + private final Hashtable data; public EmployeeDatabase() { this.data = new Hashtable<>(); diff --git a/commander/src/main/java/com/iluwatar/commander/messagingservice/MessagingDatabase.java b/commander/src/main/java/com/iluwatar/commander/messagingservice/MessagingDatabase.java index fbba52cac..22ad733cb 100644 --- a/commander/src/main/java/com/iluwatar/commander/messagingservice/MessagingDatabase.java +++ b/commander/src/main/java/com/iluwatar/commander/messagingservice/MessagingDatabase.java @@ -33,7 +33,7 @@ import java.util.Hashtable; */ public class MessagingDatabase extends Database { - private Hashtable data; + private final Hashtable data; public MessagingDatabase() { this.data = new Hashtable<>(); diff --git a/commander/src/main/java/com/iluwatar/commander/paymentservice/PaymentDatabase.java b/commander/src/main/java/com/iluwatar/commander/paymentservice/PaymentDatabase.java index 644979883..bf9e846bb 100644 --- a/commander/src/main/java/com/iluwatar/commander/paymentservice/PaymentDatabase.java +++ b/commander/src/main/java/com/iluwatar/commander/paymentservice/PaymentDatabase.java @@ -34,7 +34,7 @@ import java.util.Hashtable; public class PaymentDatabase extends Database { - private Hashtable data; + private final Hashtable data; public PaymentDatabase() { this.data = new Hashtable<>(); diff --git a/commander/src/main/java/com/iluwatar/commander/queue/QueueDatabase.java b/commander/src/main/java/com/iluwatar/commander/queue/QueueDatabase.java index 91a7966f7..003a7da46 100644 --- a/commander/src/main/java/com/iluwatar/commander/queue/QueueDatabase.java +++ b/commander/src/main/java/com/iluwatar/commander/queue/QueueDatabase.java @@ -35,7 +35,7 @@ import java.util.List; public class QueueDatabase extends Database { - private Queue data; + private final Queue data; public List exceptionsList; public QueueDatabase(Exception... exc) { diff --git a/commander/src/main/java/com/iluwatar/commander/shippingservice/ShippingDatabase.java b/commander/src/main/java/com/iluwatar/commander/shippingservice/ShippingDatabase.java index 305122db2..abaf27c9d 100644 --- a/commander/src/main/java/com/iluwatar/commander/shippingservice/ShippingDatabase.java +++ b/commander/src/main/java/com/iluwatar/commander/shippingservice/ShippingDatabase.java @@ -34,7 +34,7 @@ import java.util.Hashtable; public class ShippingDatabase extends Database { - private Hashtable data; + private final Hashtable data; public ShippingDatabase() { this.data = new Hashtable<>(); diff --git a/composite/README.md b/composite/README.md index 25b553b76..dad6fb5a5 100644 --- a/composite/README.md +++ b/composite/README.md @@ -34,7 +34,7 @@ Taking our sentence example from above. Here we have the base class and differen ```java public abstract class LetterComposite { - private List children = new ArrayList<>(); + private final List children = new ArrayList<>(); public void add(LetterComposite letter) { children.add(letter); @@ -59,7 +59,7 @@ public abstract class LetterComposite { public class Letter extends LetterComposite { - private char character; + private final char character; public Letter(char c) { this.character = c; diff --git a/composite/src/main/java/com/iluwatar/composite/Letter.java b/composite/src/main/java/com/iluwatar/composite/Letter.java index ab2d496ea..00b1a9639 100644 --- a/composite/src/main/java/com/iluwatar/composite/Letter.java +++ b/composite/src/main/java/com/iluwatar/composite/Letter.java @@ -28,7 +28,7 @@ package com.iluwatar.composite; */ public class Letter extends LetterComposite { - private char character; + private final char character; public Letter(char c) { this.character = c; diff --git a/composite/src/main/java/com/iluwatar/composite/LetterComposite.java b/composite/src/main/java/com/iluwatar/composite/LetterComposite.java index 25808c468..0daf88222 100644 --- a/composite/src/main/java/com/iluwatar/composite/LetterComposite.java +++ b/composite/src/main/java/com/iluwatar/composite/LetterComposite.java @@ -1,58 +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.composite; - -import java.util.ArrayList; -import java.util.List; - -/** - * Composite interface. - */ -public abstract class LetterComposite { - - private List children = new ArrayList<>(); - - public void add(LetterComposite letter) { - children.add(letter); - } - - public int count() { - return children.size(); - } - - protected void printThisBefore() { - } - - protected void printThisAfter() { - } - - /** - * Print. - */ - public void print() { - printThisBefore(); - children.forEach(LetterComposite::print); - printThisAfter(); - } -} +/* + * 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.composite; + +import java.util.ArrayList; +import java.util.List; + +/** + * Composite interface. + */ +public abstract class LetterComposite { + + private final List children = new ArrayList<>(); + + public void add(LetterComposite letter) { + children.add(letter); + } + + public int count() { + return children.size(); + } + + protected void printThisBefore() { + } + + protected void printThisAfter() { + } + + /** + * Print. + */ + public void print() { + printThisBefore(); + children.forEach(LetterComposite::print); + printThisAfter(); + } +} diff --git a/converter/src/main/java/com/iluwatar/converter/User.java b/converter/src/main/java/com/iluwatar/converter/User.java index 637d77a25..2c1ba9ff0 100644 --- a/converter/src/main/java/com/iluwatar/converter/User.java +++ b/converter/src/main/java/com/iluwatar/converter/User.java @@ -29,10 +29,10 @@ import java.util.Objects; * User class. */ public class User { - private String firstName; - private String lastName; - private boolean isActive; - private String userId; + private final String firstName; + private final String lastName; + private final boolean isActive; + private final String userId; /** * Constructor. diff --git a/converter/src/main/java/com/iluwatar/converter/UserDto.java b/converter/src/main/java/com/iluwatar/converter/UserDto.java index e75aaab8c..67a886087 100644 --- a/converter/src/main/java/com/iluwatar/converter/UserDto.java +++ b/converter/src/main/java/com/iluwatar/converter/UserDto.java @@ -30,10 +30,10 @@ import java.util.Objects; */ public class UserDto { - private String firstName; - private String lastName; - private boolean isActive; - private String email; + private final String firstName; + private final String lastName; + private final boolean isActive; + private final String email; /** * Constructor. diff --git a/converter/src/test/java/com/iluwatar/converter/ConverterTest.java b/converter/src/test/java/com/iluwatar/converter/ConverterTest.java index d9e4e418b..46aca82a7 100644 --- a/converter/src/test/java/com/iluwatar/converter/ConverterTest.java +++ b/converter/src/test/java/com/iluwatar/converter/ConverterTest.java @@ -34,7 +34,7 @@ import org.junit.jupiter.api.Test; */ public class ConverterTest { - private UserConverter userConverter = new UserConverter(); + private final UserConverter userConverter = new UserConverter(); /** * Tests whether a converter created of opposite functions holds equality as a bijection. diff --git a/cqrs/src/main/java/com/iluwatar/cqrs/commandes/CommandServiceImpl.java b/cqrs/src/main/java/com/iluwatar/cqrs/commandes/CommandServiceImpl.java index ba08811e7..e402adad8 100644 --- a/cqrs/src/main/java/com/iluwatar/cqrs/commandes/CommandServiceImpl.java +++ b/cqrs/src/main/java/com/iluwatar/cqrs/commandes/CommandServiceImpl.java @@ -34,7 +34,7 @@ import org.hibernate.SessionFactory; */ public class CommandServiceImpl implements ICommandService { - private SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + private final SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); private Author getAuthorByUsername(String username) { Author author; diff --git a/cqrs/src/main/java/com/iluwatar/cqrs/queries/QueryServiceImpl.java b/cqrs/src/main/java/com/iluwatar/cqrs/queries/QueryServiceImpl.java index 9b008402e..d30c0f386 100644 --- a/cqrs/src/main/java/com/iluwatar/cqrs/queries/QueryServiceImpl.java +++ b/cqrs/src/main/java/com/iluwatar/cqrs/queries/QueryServiceImpl.java @@ -38,7 +38,7 @@ import org.hibernate.transform.Transformers; */ public class QueryServiceImpl implements IQueryService { - private SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + private final SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); @Override public Author getAuthorByUsername(String username) { diff --git a/dao/README.md b/dao/README.md index 4b65679c4..11e5f9ca3 100644 --- a/dao/README.md +++ b/dao/README.md @@ -112,7 +112,7 @@ public interface CustomerDao { public class InMemoryCustomerDao implements CustomerDao { - private Map idToCustomer = new HashMap<>(); + private final Map idToCustomer = new HashMap<>(); @Override public Stream getAll() { diff --git a/dao/src/main/java/com/iluwatar/dao/App.java b/dao/src/main/java/com/iluwatar/dao/App.java index de9c7b7c1..6d578bc79 100644 --- a/dao/src/main/java/com/iluwatar/dao/App.java +++ b/dao/src/main/java/com/iluwatar/dao/App.java @@ -44,7 +44,7 @@ import org.slf4j.LoggerFactory; */ public class App { private static final String DB_URL = "jdbc:h2:~/dao"; - private static Logger log = LoggerFactory.getLogger(App.class); + private static final Logger log = LoggerFactory.getLogger(App.class); private static final String ALL_CUSTOMERS = "customerDao.getAllCustomers(): "; /** diff --git a/dao/src/main/java/com/iluwatar/dao/InMemoryCustomerDao.java b/dao/src/main/java/com/iluwatar/dao/InMemoryCustomerDao.java index 6dbfa367a..0a3bd40e3 100644 --- a/dao/src/main/java/com/iluwatar/dao/InMemoryCustomerDao.java +++ b/dao/src/main/java/com/iluwatar/dao/InMemoryCustomerDao.java @@ -36,7 +36,7 @@ import java.util.stream.Stream; */ public class InMemoryCustomerDao implements CustomerDao { - private Map idToCustomer = new HashMap<>(); + private final Map idToCustomer = new HashMap<>(); /** * An eagerly evaluated stream of customers stored in memory. diff --git a/dao/src/test/java/com/iluwatar/dao/DbCustomerDaoTest.java b/dao/src/test/java/com/iluwatar/dao/DbCustomerDaoTest.java index b7a0b9769..8155cda79 100644 --- a/dao/src/test/java/com/iluwatar/dao/DbCustomerDaoTest.java +++ b/dao/src/test/java/com/iluwatar/dao/DbCustomerDaoTest.java @@ -50,7 +50,7 @@ public class DbCustomerDaoTest { private static final String DB_URL = "jdbc:h2:~/dao"; private DbCustomerDao dao; - private Customer existingCustomer = new Customer(1, "Freddy", "Krueger"); + private final Customer existingCustomer = new Customer(1, "Freddy", "Krueger"); /** * Creates customers schema. diff --git a/data-bus/src/main/java/com/iluwatar/databus/members/MessageCollectorMember.java b/data-bus/src/main/java/com/iluwatar/databus/members/MessageCollectorMember.java index 5a8218225..d77d56b9f 100644 --- a/data-bus/src/main/java/com/iluwatar/databus/members/MessageCollectorMember.java +++ b/data-bus/src/main/java/com/iluwatar/databus/members/MessageCollectorMember.java @@ -41,7 +41,7 @@ public class MessageCollectorMember implements Member { private final String name; - private List messages = new ArrayList<>(); + private final List messages = new ArrayList<>(); public MessageCollectorMember(String name) { this.name = name; diff --git a/data-mapper/src/main/java/com/iluwatar/datamapper/App.java b/data-mapper/src/main/java/com/iluwatar/datamapper/App.java index 9bfc32952..09c027401 100644 --- a/data-mapper/src/main/java/com/iluwatar/datamapper/App.java +++ b/data-mapper/src/main/java/com/iluwatar/datamapper/App.java @@ -1,83 +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.datamapper; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * 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 = LoggerFactory.getLogger(App.class); - private static final String STUDENT_STRING = "App.main(), student : "; - - - /** - * Program entry point. - * - * @param args command line args. - */ - public static void main(final String... args) { - - /* Create new data mapper for type 'first' */ - final var mapper = new StudentDataMapperImpl(); - - /* Create new student */ - var student = new Student(1, "Adam", 'A'); - - /* Add student in respectibe store */ - mapper.insert(student); - - log.debug(STUDENT_STRING + student + ", is inserted"); - - /* Find this student */ - final var studentToBeFound = mapper.find(student.getStudentId()); - - log.debug(STUDENT_STRING + studentToBeFound + ", is searched"); - - /* Update existing student object */ - student = new Student(student.getStudentId(), "AdamUpdated", 'A'); - - /* Update student in respectibe db */ - mapper.update(student); - - log.debug(STUDENT_STRING + student + ", is updated"); - log.debug(STUDENT_STRING + student + ", is going to be deleted"); - - /* Delete student in db */ - mapper.delete(student); - } - - private App() { - } -} +/* + * 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.datamapper; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * 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 final Logger log = LoggerFactory.getLogger(App.class); + private static final String STUDENT_STRING = "App.main(), student : "; + + + /** + * Program entry point. + * + * @param args command line args. + */ + public static void main(final String... args) { + + /* Create new data mapper for type 'first' */ + final var mapper = new StudentDataMapperImpl(); + + /* Create new student */ + var student = new Student(1, "Adam", 'A'); + + /* Add student in respectibe store */ + mapper.insert(student); + + log.debug(STUDENT_STRING + student + ", is inserted"); + + /* Find this student */ + final var studentToBeFound = mapper.find(student.getStudentId()); + + log.debug(STUDENT_STRING + studentToBeFound + ", is searched"); + + /* Update existing student object */ + student = new Student(student.getStudentId(), "AdamUpdated", 'A'); + + /* Update student in respectibe db */ + mapper.update(student); + + log.debug(STUDENT_STRING + student + ", is updated"); + log.debug(STUDENT_STRING + 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/StudentDataMapperImpl.java b/data-mapper/src/main/java/com/iluwatar/datamapper/StudentDataMapperImpl.java index 85ad4aa8d..7abe04e3f 100644 --- a/data-mapper/src/main/java/com/iluwatar/datamapper/StudentDataMapperImpl.java +++ b/data-mapper/src/main/java/com/iluwatar/datamapper/StudentDataMapperImpl.java @@ -33,7 +33,7 @@ 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<>(); + private final List students = new ArrayList<>(); @Override public Optional find(int studentId) { diff --git a/data-transfer-object/README.md b/data-transfer-object/README.md index e9286ce03..fd0ff1137 100644 --- a/data-transfer-object/README.md +++ b/data-transfer-object/README.md @@ -64,7 +64,7 @@ Customer resource class acts as the server for customer information. ```java public class CustomerResource { - private List customers; + private final List customers; public CustomerResource(List customers) { this.customers = customers; diff --git a/data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerResource.java b/data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerResource.java index 7e4b8340d..d0a153f6f 100644 --- a/data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerResource.java +++ b/data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerResource.java @@ -30,7 +30,7 @@ import java.util.List; * has all customer details. */ public class CustomerResource { - private List customers; + private final List customers; /** * Initialise resource with existing customers. diff --git a/decorator/README.md b/decorator/README.md index a9dd5d745..26dbd1803 100644 --- a/decorator/README.md +++ b/decorator/README.md @@ -70,7 +70,7 @@ public class ClubbedTroll implements Troll { private static final Logger LOGGER = LoggerFactory.getLogger(ClubbedTroll.class); - private Troll decorated; + private final Troll decorated; public ClubbedTroll(Troll decorated) { this.decorated = decorated; diff --git a/decorator/src/main/java/com/iluwatar/decorator/ClubbedTroll.java b/decorator/src/main/java/com/iluwatar/decorator/ClubbedTroll.java index 70fd15489..74a1434e1 100644 --- a/decorator/src/main/java/com/iluwatar/decorator/ClubbedTroll.java +++ b/decorator/src/main/java/com/iluwatar/decorator/ClubbedTroll.java @@ -33,7 +33,7 @@ public class ClubbedTroll implements Troll { private static final Logger LOGGER = LoggerFactory.getLogger(ClubbedTroll.class); - private Troll decorated; + private final Troll decorated; public ClubbedTroll(Troll decorated) { this.decorated = decorated; diff --git a/decorator/src/test/java/com/iluwatar/decorator/SimpleTrollTest.java b/decorator/src/test/java/com/iluwatar/decorator/SimpleTrollTest.java index c9f62407c..a398135e6 100644 --- a/decorator/src/test/java/com/iluwatar/decorator/SimpleTrollTest.java +++ b/decorator/src/test/java/com/iluwatar/decorator/SimpleTrollTest.java @@ -68,7 +68,7 @@ public class SimpleTrollTest { private class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender(Class clazz) { ((Logger) LoggerFactory.getLogger(clazz)).addAppender(this); diff --git a/delegation/src/test/java/com/iluwatar/delegation/simple/DelegateTest.java b/delegation/src/test/java/com/iluwatar/delegation/simple/DelegateTest.java index 2da1e0571..8aefc4b56 100644 --- a/delegation/src/test/java/com/iluwatar/delegation/simple/DelegateTest.java +++ b/delegation/src/test/java/com/iluwatar/delegation/simple/DelegateTest.java @@ -86,7 +86,7 @@ public class DelegateTest { */ private class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender() { ((Logger) LoggerFactory.getLogger("root")).addAppender(this); diff --git a/dependency-injection/README.md b/dependency-injection/README.md index abf647b50..b47c1d2f9 100644 --- a/dependency-injection/README.md +++ b/dependency-injection/README.md @@ -62,7 +62,7 @@ public interface Wizard { public class AdvancedWizard implements Wizard { - private Tobacco tobacco; + private final Tobacco tobacco; public AdvancedWizard(Tobacco tobacco) { this.tobacco = tobacco; 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 e0c952186..f0ff2da94 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 @@ -29,7 +29,7 @@ package com.iluwatar.dependency.injection; */ public class AdvancedWizard implements Wizard { - private Tobacco tobacco; + private final Tobacco tobacco; public AdvancedWizard(Tobacco tobacco) { this.tobacco = tobacco; 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 319a635eb..d769ffd46 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 @@ -31,7 +31,7 @@ import javax.inject.Inject; */ public class GuiceWizard implements Wizard { - private Tobacco tobacco; + private final Tobacco tobacco; @Inject public GuiceWizard(Tobacco tobacco) { 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 40bca0ffb..0136ff69f 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 @@ -29,7 +29,7 @@ package com.iluwatar.dependency.injection; */ public class SimpleWizard implements Wizard { - private OldTobyTobacco tobacco = new OldTobyTobacco(); + private final OldTobyTobacco tobacco = new OldTobyTobacco(); public void smoke() { tobacco.smoke(this); diff --git a/dependency-injection/src/test/java/com/iluwatar/dependency/injection/utils/InMemoryAppender.java b/dependency-injection/src/test/java/com/iluwatar/dependency/injection/utils/InMemoryAppender.java index 9d0ad1b3b..d91099af9 100644 --- a/dependency-injection/src/test/java/com/iluwatar/dependency/injection/utils/InMemoryAppender.java +++ b/dependency-injection/src/test/java/com/iluwatar/dependency/injection/utils/InMemoryAppender.java @@ -37,7 +37,7 @@ import java.util.List; */ public class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender(Class clazz) { ((Logger) LoggerFactory.getLogger(clazz)).addAppender(this); diff --git a/dirty-flag/src/main/java/com/iluwatar/dirtyflag/World.java b/dirty-flag/src/main/java/com/iluwatar/dirtyflag/World.java index db60924c1..1d4fbfa75 100644 --- a/dirty-flag/src/main/java/com/iluwatar/dirtyflag/World.java +++ b/dirty-flag/src/main/java/com/iluwatar/dirtyflag/World.java @@ -34,7 +34,7 @@ import java.util.List; public class World { private List countries; - private DataFetcher df; + private final DataFetcher df; public World() { this.countries = new ArrayList(); diff --git a/double-buffer/src/main/java/com/iluwatar/doublebuffer/FrameBuffer.java b/double-buffer/src/main/java/com/iluwatar/doublebuffer/FrameBuffer.java index 5f683cf1e..4b974a2e8 100644 --- a/double-buffer/src/main/java/com/iluwatar/doublebuffer/FrameBuffer.java +++ b/double-buffer/src/main/java/com/iluwatar/doublebuffer/FrameBuffer.java @@ -33,7 +33,7 @@ public class FrameBuffer implements Buffer { public static final int WIDTH = 10; public static final int HEIGHT = 8; - private Pixel[] pixels = new Pixel[WIDTH * HEIGHT]; + private final Pixel[] pixels = new Pixel[WIDTH * HEIGHT]; public FrameBuffer() { clearAll(); diff --git a/double-buffer/src/main/java/com/iluwatar/doublebuffer/Pixel.java b/double-buffer/src/main/java/com/iluwatar/doublebuffer/Pixel.java index 501797743..54f130b1d 100644 --- a/double-buffer/src/main/java/com/iluwatar/doublebuffer/Pixel.java +++ b/double-buffer/src/main/java/com/iluwatar/doublebuffer/Pixel.java @@ -31,7 +31,7 @@ public enum Pixel { WHITE(0), BLACK(1); - private int color; + private final int color; Pixel(int color) { this.color = color; diff --git a/double-buffer/src/main/java/com/iluwatar/doublebuffer/Scene.java b/double-buffer/src/main/java/com/iluwatar/doublebuffer/Scene.java index 2c1503918..8ee72ded4 100644 --- a/double-buffer/src/main/java/com/iluwatar/doublebuffer/Scene.java +++ b/double-buffer/src/main/java/com/iluwatar/doublebuffer/Scene.java @@ -35,7 +35,7 @@ public class Scene { private static final Logger LOGGER = LoggerFactory.getLogger(Scene.class); - private Buffer[] frameBuffers; + private final Buffer[] frameBuffers; private int current; 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 index e8ea7c6f8..fe0cbf5e9 100644 --- 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 @@ -109,7 +109,7 @@ public class InventoryTest { private class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender(Class clazz) { ((Logger) LoggerFactory.getLogger(clazz)).addAppender(this); 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 bd832287c..ea18ca3dc 100644 --- a/double-dispatch/src/main/java/com/iluwatar/doubledispatch/Rectangle.java +++ b/double-dispatch/src/main/java/com/iluwatar/doubledispatch/Rectangle.java @@ -28,10 +28,10 @@ package com.iluwatar.doubledispatch; */ public class Rectangle { - private int left; - private int top; - private int right; - private int bottom; + private final int left; + private final int top; + private final int right; + private final int bottom; /** * Constructor. diff --git a/event-aggregator/src/main/java/com/iluwatar/event/aggregator/Event.java b/event-aggregator/src/main/java/com/iluwatar/event/aggregator/Event.java index 7a125c042..91bb020ee 100644 --- a/event-aggregator/src/main/java/com/iluwatar/event/aggregator/Event.java +++ b/event-aggregator/src/main/java/com/iluwatar/event/aggregator/Event.java @@ -31,7 +31,7 @@ public enum Event { STARK_SIGHTED("Stark sighted"), WARSHIPS_APPROACHING("Warships approaching"), TRAITOR_DETECTED( "Traitor detected"); - private String description; + private final String description; Event(String description) { this.description = description; diff --git a/event-aggregator/src/main/java/com/iluwatar/event/aggregator/EventEmitter.java b/event-aggregator/src/main/java/com/iluwatar/event/aggregator/EventEmitter.java index 9985cee60..7d3f32a68 100644 --- a/event-aggregator/src/main/java/com/iluwatar/event/aggregator/EventEmitter.java +++ b/event-aggregator/src/main/java/com/iluwatar/event/aggregator/EventEmitter.java @@ -31,7 +31,7 @@ import java.util.List; */ public abstract class EventEmitter { - private List observers; + private final List observers; public EventEmitter() { observers = new LinkedList<>(); diff --git a/event-aggregator/src/main/java/com/iluwatar/event/aggregator/Weekday.java b/event-aggregator/src/main/java/com/iluwatar/event/aggregator/Weekday.java index 9ec61339c..1e0ce9491 100644 --- a/event-aggregator/src/main/java/com/iluwatar/event/aggregator/Weekday.java +++ b/event-aggregator/src/main/java/com/iluwatar/event/aggregator/Weekday.java @@ -36,7 +36,7 @@ public enum Weekday { SATURDAY("Saturday"), SUNDAY("Sunday"); - private String description; + private final String description; Weekday(String description) { this.description = description; diff --git a/event-aggregator/src/test/java/com/iluwatar/event/aggregator/KingJoffreyTest.java b/event-aggregator/src/test/java/com/iluwatar/event/aggregator/KingJoffreyTest.java index a8bb6cbaa..f8aa5cb37 100644 --- a/event-aggregator/src/test/java/com/iluwatar/event/aggregator/KingJoffreyTest.java +++ b/event-aggregator/src/test/java/com/iluwatar/event/aggregator/KingJoffreyTest.java @@ -74,7 +74,7 @@ public class KingJoffreyTest { } private class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender(Class clazz) { ((Logger) LoggerFactory.getLogger(clazz)).addAppender(this); diff --git a/event-asynchronous/src/main/java/com/iluwatar/event/asynchronous/Event.java b/event-asynchronous/src/main/java/com/iluwatar/event/asynchronous/Event.java index 6925a2ffd..68c4c9781 100644 --- a/event-asynchronous/src/main/java/com/iluwatar/event/asynchronous/Event.java +++ b/event-asynchronous/src/main/java/com/iluwatar/event/asynchronous/Event.java @@ -33,9 +33,9 @@ public class Event implements IEvent, Runnable { private static final Logger LOGGER = LoggerFactory.getLogger(Event.class); - private int eventId; - private int eventTime; - private boolean isSynchronous; + private final int eventId; + private final int eventTime; + private final boolean isSynchronous; private Thread thread; private boolean isComplete = false; private ThreadCompleteListener eventListener; diff --git a/event-asynchronous/src/main/java/com/iluwatar/event/asynchronous/EventManager.java b/event-asynchronous/src/main/java/com/iluwatar/event/asynchronous/EventManager.java index 14d28860b..55671fd82 100644 --- a/event-asynchronous/src/main/java/com/iluwatar/event/asynchronous/EventManager.java +++ b/event-asynchronous/src/main/java/com/iluwatar/event/asynchronous/EventManager.java @@ -43,8 +43,8 @@ public class EventManager implements ThreadCompleteListener { public static final int MAX_ID = MAX_RUNNING_EVENTS; public static final int MAX_EVENT_TIME = 1800; // in seconds / 30 minutes. private int currentlyRunningSyncEvent = -1; - private Random rand; - private Map eventPool; + private final Random rand; + private final Map eventPool; private static final String DOES_NOT_EXIST = " does not exist."; diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserCreatedEvent.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserCreatedEvent.java index c18426c95..dd5e65a9a 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserCreatedEvent.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserCreatedEvent.java @@ -32,7 +32,7 @@ import com.iluwatar.eda.model.User; */ public class UserCreatedEvent extends AbstractEvent { - private User user; + private final User user; public UserCreatedEvent(User user) { this.user = user; diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserUpdatedEvent.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserUpdatedEvent.java index 59583053c..05370c6a6 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserUpdatedEvent.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserUpdatedEvent.java @@ -32,7 +32,7 @@ import com.iluwatar.eda.model.User; */ public class UserUpdatedEvent extends AbstractEvent { - private User user; + private final User user; public UserUpdatedEvent(User user) { this.user = user; diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/EventDispatcher.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/EventDispatcher.java index dd72c1e93..74a7ee145 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/EventDispatcher.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/EventDispatcher.java @@ -32,7 +32,7 @@ import java.util.Map; */ public class EventDispatcher { - private Map, Handler> handlers; + private final Map, Handler> handlers; public EventDispatcher() { handlers = new HashMap<>(); diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/model/User.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/model/User.java index 1492c175c..0c9f12501 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/model/User.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/model/User.java @@ -32,7 +32,7 @@ import com.iluwatar.eda.event.UserUpdatedEvent; */ public class User { - private String username; + private final String username; public User(String username) { this.username = username; diff --git a/event-queue/src/main/java/com/iluwatar/event/queue/Audio.java b/event-queue/src/main/java/com/iluwatar/event/queue/Audio.java index 4286a5ed0..a0ff5d987 100644 --- a/event-queue/src/main/java/com/iluwatar/event/queue/Audio.java +++ b/event-queue/src/main/java/com/iluwatar/event/queue/Audio.java @@ -49,7 +49,7 @@ public class Audio { private volatile Thread updateThread = null; - private PlayMessage[] pendingAudio = new PlayMessage[MAX_PENDING]; + private final PlayMessage[] pendingAudio = new PlayMessage[MAX_PENDING]; // Visible only for testing purposes Audio() { diff --git a/extension-objects/src/main/java/concreteextensions/Commander.java b/extension-objects/src/main/java/concreteextensions/Commander.java index 5a0552b20..1d8054562 100644 --- a/extension-objects/src/main/java/concreteextensions/Commander.java +++ b/extension-objects/src/main/java/concreteextensions/Commander.java @@ -35,7 +35,7 @@ public class Commander implements CommanderExtension { private static final Logger LOGGER = LoggerFactory.getLogger(Commander.class); - private CommanderUnit unit; + private final CommanderUnit unit; public Commander(CommanderUnit commanderUnit) { this.unit = commanderUnit; diff --git a/extension-objects/src/main/java/concreteextensions/Sergeant.java b/extension-objects/src/main/java/concreteextensions/Sergeant.java index a45b82f11..4f5a474b3 100644 --- a/extension-objects/src/main/java/concreteextensions/Sergeant.java +++ b/extension-objects/src/main/java/concreteextensions/Sergeant.java @@ -35,7 +35,7 @@ public class Sergeant implements SergeantExtension { private static final Logger LOGGER = LoggerFactory.getLogger(Sergeant.class); - private SergeantUnit unit; + private final SergeantUnit unit; public Sergeant(SergeantUnit sergeantUnit) { this.unit = sergeantUnit; diff --git a/extension-objects/src/main/java/concreteextensions/Soldier.java b/extension-objects/src/main/java/concreteextensions/Soldier.java index b47ba595d..d500ab604 100644 --- a/extension-objects/src/main/java/concreteextensions/Soldier.java +++ b/extension-objects/src/main/java/concreteextensions/Soldier.java @@ -34,7 +34,7 @@ import units.SoldierUnit; public class Soldier implements SoldierExtension { private static final Logger LOGGER = LoggerFactory.getLogger(Soldier.class); - private SoldierUnit unit; + private final SoldierUnit unit; public Soldier(SoldierUnit soldierUnit) { this.unit = soldierUnit; diff --git a/facade/README.md b/facade/README.md index 018c493a7..ce9d892b6 100644 --- a/facade/README.md +++ b/facade/README.md @@ -83,7 +83,7 @@ public abstract class DwarvenMineWorker { public abstract String name(); - static enum Action { + enum Action { GO_TO_SLEEP, WAKE_UP, GO_HOME, GO_TO_MINE, WORK } } diff --git a/facade/src/test/java/com/iluwatar/facade/DwarvenGoldmineFacadeTest.java b/facade/src/test/java/com/iluwatar/facade/DwarvenGoldmineFacadeTest.java index 3b67f3754..10d6e1ecd 100644 --- a/facade/src/test/java/com/iluwatar/facade/DwarvenGoldmineFacadeTest.java +++ b/facade/src/test/java/com/iluwatar/facade/DwarvenGoldmineFacadeTest.java @@ -110,7 +110,7 @@ public class DwarvenGoldmineFacadeTest { private class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender() { ((Logger) LoggerFactory.getLogger("root")).addAppender(this); diff --git a/factory-method/src/main/java/com/iluwatar/factory/method/ElfBlacksmith.java b/factory-method/src/main/java/com/iluwatar/factory/method/ElfBlacksmith.java index b6f29e43a..99ebcef65 100644 --- a/factory-method/src/main/java/com/iluwatar/factory/method/ElfBlacksmith.java +++ b/factory-method/src/main/java/com/iluwatar/factory/method/ElfBlacksmith.java @@ -32,7 +32,7 @@ import java.util.Map; */ public class ElfBlacksmith implements Blacksmith { - private static Map ELFARSENAL; + private static final Map ELFARSENAL; static { ELFARSENAL = new HashMap<>(WeaponType.values().length); diff --git a/factory-method/src/main/java/com/iluwatar/factory/method/ElfWeapon.java b/factory-method/src/main/java/com/iluwatar/factory/method/ElfWeapon.java index 66a6ea7e7..208dfa277 100644 --- a/factory-method/src/main/java/com/iluwatar/factory/method/ElfWeapon.java +++ b/factory-method/src/main/java/com/iluwatar/factory/method/ElfWeapon.java @@ -28,7 +28,7 @@ package com.iluwatar.factory.method; */ public class ElfWeapon implements Weapon { - private WeaponType weaponType; + private final WeaponType weaponType; public ElfWeapon(WeaponType weaponType) { this.weaponType = weaponType; diff --git a/factory-method/src/main/java/com/iluwatar/factory/method/OrcBlacksmith.java b/factory-method/src/main/java/com/iluwatar/factory/method/OrcBlacksmith.java index b04830085..ea99200de 100644 --- a/factory-method/src/main/java/com/iluwatar/factory/method/OrcBlacksmith.java +++ b/factory-method/src/main/java/com/iluwatar/factory/method/OrcBlacksmith.java @@ -32,7 +32,7 @@ import java.util.Map; */ public class OrcBlacksmith implements Blacksmith { - private static Map ORCARSENAL; + private static final Map ORCARSENAL; static { ORCARSENAL = new HashMap<>(WeaponType.values().length); diff --git a/factory-method/src/main/java/com/iluwatar/factory/method/OrcWeapon.java b/factory-method/src/main/java/com/iluwatar/factory/method/OrcWeapon.java index b35adf798..af1ee5bcf 100644 --- a/factory-method/src/main/java/com/iluwatar/factory/method/OrcWeapon.java +++ b/factory-method/src/main/java/com/iluwatar/factory/method/OrcWeapon.java @@ -28,7 +28,7 @@ package com.iluwatar.factory.method; */ public class OrcWeapon implements Weapon { - private WeaponType weaponType; + private final WeaponType weaponType; public OrcWeapon(WeaponType weaponType) { this.weaponType = weaponType; diff --git a/factory-method/src/main/java/com/iluwatar/factory/method/WeaponType.java b/factory-method/src/main/java/com/iluwatar/factory/method/WeaponType.java index 73ab10dd6..6c7c86712 100644 --- a/factory-method/src/main/java/com/iluwatar/factory/method/WeaponType.java +++ b/factory-method/src/main/java/com/iluwatar/factory/method/WeaponType.java @@ -30,7 +30,7 @@ public enum WeaponType { SHORT_SWORD("short sword"), SPEAR("spear"), AXE("axe"), UNDEFINED(""); - private String title; + private final String title; WeaponType(String title) { this.title = title; diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersion.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersion.java index 6e2281b9a..ed6e69518 100644 --- a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersion.java +++ b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersion.java @@ -42,7 +42,7 @@ import java.util.Properties; */ public class PropertiesFeatureToggleVersion implements Service { - private boolean isEnhanced; + private final boolean isEnhanced; /** * Creates an instance of {@link PropertiesFeatureToggleVersion} using the passed {@link diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/User.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/User.java index 5c660ca59..7924f86e8 100644 --- a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/User.java +++ b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/User.java @@ -29,7 +29,7 @@ package com.iluwatar.featuretoggle.user; */ public class User { - private String name; + private final String name; /** * Default Constructor setting the username. diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/UserGroup.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/UserGroup.java index 524ea6ef8..7b644afd7 100644 --- a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/UserGroup.java +++ b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/UserGroup.java @@ -35,8 +35,8 @@ import java.util.List; */ public class UserGroup { - private static List freeGroup = new ArrayList<>(); - private static List paidGroup = new ArrayList<>(); + private static final List freeGroup = new ArrayList<>(); + private static final List paidGroup = new ArrayList<>(); /** diff --git a/fluentinterface/src/main/java/com/iluwatar/fluentinterface/app/App.java b/fluentinterface/src/main/java/com/iluwatar/fluentinterface/app/App.java index 547c657e4..09513163c 100644 --- a/fluentinterface/src/main/java/com/iluwatar/fluentinterface/app/App.java +++ b/fluentinterface/src/main/java/com/iluwatar/fluentinterface/app/App.java @@ -94,7 +94,7 @@ public class App { .filter(positives()) .first(4) .last(2) - .map(number -> "String[" + valueOf(number) + "]") + .map(number -> "String[" + number + "]") .asList(); prettyPrint("The lazy list contains the last two of the first four positive numbers " + "mapped to Strings: ", lastTwoOfFirstFourStringMapped); diff --git a/fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/lazy/LazyFluentIterable.java b/fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/lazy/LazyFluentIterable.java index f001c532f..966f35287 100644 --- a/fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/lazy/LazyFluentIterable.java +++ b/fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/lazy/LazyFluentIterable.java @@ -198,7 +198,7 @@ public class LazyFluentIterable implements FluentIterable { @Override public Iterator iterator() { return new DecoratingIterator(null) { - Iterator oldTypeIterator = iterable.iterator(); + final Iterator oldTypeIterator = iterable.iterator(); @Override public T computeNext() { diff --git a/flux/src/main/java/com/iluwatar/flux/action/Action.java b/flux/src/main/java/com/iluwatar/flux/action/Action.java index 6a5f608c2..c8e2e012b 100644 --- a/flux/src/main/java/com/iluwatar/flux/action/Action.java +++ b/flux/src/main/java/com/iluwatar/flux/action/Action.java @@ -28,7 +28,7 @@ package com.iluwatar.flux.action; */ public abstract class Action { - private ActionType type; + private final ActionType type; public Action(ActionType type) { this.type = type; diff --git a/flux/src/main/java/com/iluwatar/flux/action/ActionType.java b/flux/src/main/java/com/iluwatar/flux/action/ActionType.java index 6399d2806..e84954efd 100644 --- a/flux/src/main/java/com/iluwatar/flux/action/ActionType.java +++ b/flux/src/main/java/com/iluwatar/flux/action/ActionType.java @@ -28,6 +28,6 @@ package com.iluwatar.flux.action; */ public enum ActionType { - MENU_ITEM_SELECTED, CONTENT_CHANGED; + MENU_ITEM_SELECTED, CONTENT_CHANGED } diff --git a/flux/src/main/java/com/iluwatar/flux/action/Content.java b/flux/src/main/java/com/iluwatar/flux/action/Content.java index 59a63ec18..6fb2e3e0e 100644 --- a/flux/src/main/java/com/iluwatar/flux/action/Content.java +++ b/flux/src/main/java/com/iluwatar/flux/action/Content.java @@ -31,7 +31,7 @@ public enum Content { PRODUCTS("Products - This page lists the company's products."), COMPANY( "Company - This page displays information about the company."); - private String title; + private final String title; Content(String title) { this.title = title; diff --git a/flux/src/main/java/com/iluwatar/flux/action/ContentAction.java b/flux/src/main/java/com/iluwatar/flux/action/ContentAction.java index 3b29b6b4e..c70561a65 100644 --- a/flux/src/main/java/com/iluwatar/flux/action/ContentAction.java +++ b/flux/src/main/java/com/iluwatar/flux/action/ContentAction.java @@ -28,7 +28,7 @@ package com.iluwatar.flux.action; */ public class ContentAction extends Action { - private Content content; + private final Content content; public ContentAction(Content content) { super(ActionType.CONTENT_CHANGED); diff --git a/flux/src/main/java/com/iluwatar/flux/action/MenuAction.java b/flux/src/main/java/com/iluwatar/flux/action/MenuAction.java index 5ddeefde4..f833a6187 100644 --- a/flux/src/main/java/com/iluwatar/flux/action/MenuAction.java +++ b/flux/src/main/java/com/iluwatar/flux/action/MenuAction.java @@ -29,7 +29,7 @@ package com.iluwatar.flux.action; */ public class MenuAction extends Action { - private MenuItem menuItem; + private final MenuItem menuItem; public MenuAction(MenuItem menuItem) { super(ActionType.MENU_ITEM_SELECTED); diff --git a/flux/src/main/java/com/iluwatar/flux/action/MenuItem.java b/flux/src/main/java/com/iluwatar/flux/action/MenuItem.java index f251e1dd7..90fac3e2e 100644 --- a/flux/src/main/java/com/iluwatar/flux/action/MenuItem.java +++ b/flux/src/main/java/com/iluwatar/flux/action/MenuItem.java @@ -30,7 +30,7 @@ public enum MenuItem { HOME("Home"), PRODUCTS("Products"), COMPANY("Company"); - private String title; + private final String title; MenuItem(String title) { this.title = title; diff --git a/flux/src/main/java/com/iluwatar/flux/dispatcher/Dispatcher.java b/flux/src/main/java/com/iluwatar/flux/dispatcher/Dispatcher.java index cf09ecf68..27d374f5d 100644 --- a/flux/src/main/java/com/iluwatar/flux/dispatcher/Dispatcher.java +++ b/flux/src/main/java/com/iluwatar/flux/dispatcher/Dispatcher.java @@ -39,7 +39,7 @@ public final class Dispatcher { private static Dispatcher instance = new Dispatcher(); - private List stores = new LinkedList<>(); + private final List stores = new LinkedList<>(); private Dispatcher() { } diff --git a/flux/src/main/java/com/iluwatar/flux/store/Store.java b/flux/src/main/java/com/iluwatar/flux/store/Store.java index cfbdf4af5..34188fff2 100644 --- a/flux/src/main/java/com/iluwatar/flux/store/Store.java +++ b/flux/src/main/java/com/iluwatar/flux/store/Store.java @@ -33,7 +33,7 @@ import java.util.List; */ public abstract class Store { - private List views = new LinkedList<>(); + private final List views = new LinkedList<>(); public abstract void onAction(Action action); diff --git a/flyweight/src/main/java/com/iluwatar/flyweight/AlchemistShop.java b/flyweight/src/main/java/com/iluwatar/flyweight/AlchemistShop.java index 4fa7312e5..e7af8ee00 100644 --- a/flyweight/src/main/java/com/iluwatar/flyweight/AlchemistShop.java +++ b/flyweight/src/main/java/com/iluwatar/flyweight/AlchemistShop.java @@ -34,8 +34,8 @@ public class AlchemistShop { private static final Logger LOGGER = LoggerFactory.getLogger(AlchemistShop.class); - private List topShelf; - private List bottomShelf; + private final List topShelf; + private final List bottomShelf; /** * Constructor. diff --git a/front-controller/src/test/java/com/iluwatar/front/controller/utils/InMemoryAppender.java b/front-controller/src/test/java/com/iluwatar/front/controller/utils/InMemoryAppender.java index 57cfb2454..8cbf7c631 100644 --- a/front-controller/src/test/java/com/iluwatar/front/controller/utils/InMemoryAppender.java +++ b/front-controller/src/test/java/com/iluwatar/front/controller/utils/InMemoryAppender.java @@ -36,7 +36,7 @@ import java.util.List; */ public class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender() { ((Logger) LoggerFactory.getLogger("root")).addAppender(this); diff --git a/half-sync-half-async/src/main/java/com/iluwatar/halfsynchalfasync/App.java b/half-sync-half-async/src/main/java/com/iluwatar/halfsynchalfasync/App.java index 7df2264ab..d013924cb 100644 --- a/half-sync-half-async/src/main/java/com/iluwatar/halfsynchalfasync/App.java +++ b/half-sync-half-async/src/main/java/com/iluwatar/halfsynchalfasync/App.java @@ -95,7 +95,7 @@ public class App { * ArithmeticSumTask. */ static class ArithmeticSumTask implements AsyncTask { - private long numberOfElements; + private final long numberOfElements; public ArithmeticSumTask(long numberOfElements) { this.numberOfElements = numberOfElements; diff --git a/half-sync-half-async/src/main/java/com/iluwatar/halfsynchalfasync/AsynchronousService.java b/half-sync-half-async/src/main/java/com/iluwatar/halfsynchalfasync/AsynchronousService.java index 3a3bb474c..32f5e9d4a 100644 --- a/half-sync-half-async/src/main/java/com/iluwatar/halfsynchalfasync/AsynchronousService.java +++ b/half-sync-half-async/src/main/java/com/iluwatar/halfsynchalfasync/AsynchronousService.java @@ -48,7 +48,7 @@ public class AsynchronousService { * tasks should be performed in the background which does not affect the performance of main * thread. */ - private ExecutorService service; + private final ExecutorService service; /** * Creates an asynchronous service using {@code workQueue} as communication channel between diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/banking/InMemoryBank.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/banking/InMemoryBank.java index 1a0fdb6b0..746b93508 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/banking/InMemoryBank.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/banking/InMemoryBank.java @@ -32,7 +32,7 @@ import java.util.Map; */ public class InMemoryBank implements WireTransfers { - private static Map accounts = new HashMap<>(); + private static final Map accounts = new HashMap<>(); static { accounts diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/database/InMemoryTicketRepository.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/database/InMemoryTicketRepository.java index 973747acc..5c0461843 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/database/InMemoryTicketRepository.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/database/InMemoryTicketRepository.java @@ -34,7 +34,7 @@ import java.util.Optional; */ public class InMemoryTicketRepository implements LotteryTicketRepository { - private static Map tickets = new HashMap<>(); + private static final Map tickets = new HashMap<>(); @Override public Optional findById(LotteryTicketId id) { diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryNumbers.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryNumbers.java index 8988bba88..acdd2b8c5 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryNumbers.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryNumbers.java @@ -116,7 +116,7 @@ public class LotteryNumbers { */ private static class RandomNumberGenerator { - private PrimitiveIterator.OfInt randomIterator; + private final PrimitiveIterator.OfInt randomIterator; /** * Initialize a new random number generator that generates random numbers in the range [min, diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryTicketId.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryTicketId.java index dfa324449..114e78c9c 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryTicketId.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryTicketId.java @@ -30,7 +30,7 @@ import java.util.concurrent.atomic.AtomicInteger; */ public class LotteryTicketId { - private static AtomicInteger numAllocated = new AtomicInteger(0); + private static final AtomicInteger numAllocated = new AtomicInteger(0); private final int id; public LotteryTicketId() { diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/eventlog/MongoEventLog.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/eventlog/MongoEventLog.java index ba46f2d97..c632debe8 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/eventlog/MongoEventLog.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/eventlog/MongoEventLog.java @@ -41,7 +41,7 @@ public class MongoEventLog implements LotteryEventLog { private MongoDatabase database; private MongoCollection eventsCollection; - private StdOutEventLog stdOutEventLog = new StdOutEventLog(); + private final StdOutEventLog stdOutEventLog = new StdOutEventLog(); /** * Constructor. diff --git a/hexagonal/src/test/java/com/iluwatar/hexagonal/domain/LotteryTest.java b/hexagonal/src/test/java/com/iluwatar/hexagonal/domain/LotteryTest.java index 6d3ba8bc5..541b2b98b 100644 --- a/hexagonal/src/test/java/com/iluwatar/hexagonal/domain/LotteryTest.java +++ b/hexagonal/src/test/java/com/iluwatar/hexagonal/domain/LotteryTest.java @@ -43,7 +43,7 @@ import org.junit.jupiter.api.Test; */ class LotteryTest { - private Injector injector; + private final Injector injector; @Inject private LotteryAdministration administration; @Inject diff --git a/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/Client.java b/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/Client.java index 656008c10..52aa890c1 100644 --- a/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/Client.java +++ b/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/Client.java @@ -51,11 +51,11 @@ public class Client extends JFrame { // NOSONAR private static final long serialVersionUID = 1L; private transient FilterManager filterManager; - private JLabel jl; - private JTextField[] jtFields; - private JTextArea[] jtAreas; - private JButton clearButton; - private JButton processButton; + private final JLabel jl; + private final JTextField[] jtFields; + private final JTextArea[] jtAreas; + private final JButton clearButton; + private final JButton processButton; /** * Constructor. diff --git a/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/FilterManager.java b/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/FilterManager.java index e8f3b941f..91e438882 100644 --- a/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/FilterManager.java +++ b/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/FilterManager.java @@ -30,7 +30,7 @@ package com.iluwatar.intercepting.filter; */ public class FilterManager { - private FilterChain filterChain; + private final FilterChain filterChain; public FilterManager() { filterChain = new FilterChain(); diff --git a/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/Target.java b/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/Target.java index 08ed715b1..db552356d 100644 --- a/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/Target.java +++ b/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/Target.java @@ -46,9 +46,9 @@ public class Target extends JFrame { //NOSONAR private static final long serialVersionUID = 1L; - private JTable jt; - private DefaultTableModel dtm; - private JButton del; + private final JTable jt; + private final DefaultTableModel dtm; + private final JButton del; /** * Constructor. diff --git a/interpreter/src/main/java/com/iluwatar/interpreter/MinusExpression.java b/interpreter/src/main/java/com/iluwatar/interpreter/MinusExpression.java index 24ef7914e..46b5c96cb 100644 --- a/interpreter/src/main/java/com/iluwatar/interpreter/MinusExpression.java +++ b/interpreter/src/main/java/com/iluwatar/interpreter/MinusExpression.java @@ -28,8 +28,8 @@ package com.iluwatar.interpreter; */ public class MinusExpression extends Expression { - private Expression leftExpression; - private Expression rightExpression; + private final Expression leftExpression; + private final Expression rightExpression; public MinusExpression(Expression leftExpression, Expression rightExpression) { this.leftExpression = leftExpression; diff --git a/interpreter/src/main/java/com/iluwatar/interpreter/MultiplyExpression.java b/interpreter/src/main/java/com/iluwatar/interpreter/MultiplyExpression.java index 606937e0b..926d6c119 100644 --- a/interpreter/src/main/java/com/iluwatar/interpreter/MultiplyExpression.java +++ b/interpreter/src/main/java/com/iluwatar/interpreter/MultiplyExpression.java @@ -28,8 +28,8 @@ package com.iluwatar.interpreter; */ public class MultiplyExpression extends Expression { - private Expression leftExpression; - private Expression rightExpression; + private final Expression leftExpression; + private final Expression rightExpression; public MultiplyExpression(Expression leftExpression, Expression rightExpression) { this.leftExpression = leftExpression; diff --git a/interpreter/src/main/java/com/iluwatar/interpreter/NumberExpression.java b/interpreter/src/main/java/com/iluwatar/interpreter/NumberExpression.java index 6b957f6aa..908eec8d1 100644 --- a/interpreter/src/main/java/com/iluwatar/interpreter/NumberExpression.java +++ b/interpreter/src/main/java/com/iluwatar/interpreter/NumberExpression.java @@ -28,7 +28,7 @@ package com.iluwatar.interpreter; */ public class NumberExpression extends Expression { - private int number; + private final int number; public NumberExpression(int number) { this.number = number; diff --git a/interpreter/src/main/java/com/iluwatar/interpreter/PlusExpression.java b/interpreter/src/main/java/com/iluwatar/interpreter/PlusExpression.java index 1ce080259..38a8bb4af 100644 --- a/interpreter/src/main/java/com/iluwatar/interpreter/PlusExpression.java +++ b/interpreter/src/main/java/com/iluwatar/interpreter/PlusExpression.java @@ -28,8 +28,8 @@ package com.iluwatar.interpreter; */ public class PlusExpression extends Expression { - private Expression leftExpression; - private Expression rightExpression; + private final Expression leftExpression; + private final Expression rightExpression; public PlusExpression(Expression leftExpression, Expression rightExpression) { this.leftExpression = leftExpression; diff --git a/iterator/README.md b/iterator/README.md index 7f06a64b9..a98010c5a 100644 --- a/iterator/README.md +++ b/iterator/README.md @@ -36,7 +36,7 @@ The main class in our example is the treasure chest that contains items. ```java public class TreasureChest { - private List items; + private final List items; public TreasureChest() { items = List.of( @@ -64,7 +64,7 @@ public class TreasureChest { public class Item { private ItemType type; - private String name; + private final String name; public Item(ItemType type, String name) { this.setType(type); diff --git a/iterator/src/main/java/com/iluwatar/iterator/bst/BstIterator.java b/iterator/src/main/java/com/iluwatar/iterator/bst/BstIterator.java index b3e0dc3d6..9f584cddc 100644 --- a/iterator/src/main/java/com/iluwatar/iterator/bst/BstIterator.java +++ b/iterator/src/main/java/com/iluwatar/iterator/bst/BstIterator.java @@ -36,7 +36,7 @@ import java.util.NoSuchElementException; */ public class BstIterator> implements Iterator> { - private ArrayDeque> pathStack; + private final ArrayDeque> pathStack; public BstIterator(TreeNode root) { pathStack = new ArrayDeque<>(); diff --git a/iterator/src/main/java/com/iluwatar/iterator/bst/TreeNode.java b/iterator/src/main/java/com/iluwatar/iterator/bst/TreeNode.java index 87f16e96c..b0ec5f486 100644 --- a/iterator/src/main/java/com/iluwatar/iterator/bst/TreeNode.java +++ b/iterator/src/main/java/com/iluwatar/iterator/bst/TreeNode.java @@ -31,7 +31,7 @@ package com.iluwatar.iterator.bst; */ public class TreeNode> { - private T val; + private final T val; private TreeNode left; private TreeNode right; diff --git a/iterator/src/main/java/com/iluwatar/iterator/list/Item.java b/iterator/src/main/java/com/iluwatar/iterator/list/Item.java index 82e66eb30..00d5625a8 100644 --- a/iterator/src/main/java/com/iluwatar/iterator/list/Item.java +++ b/iterator/src/main/java/com/iluwatar/iterator/list/Item.java @@ -29,7 +29,7 @@ package com.iluwatar.iterator.list; public class Item { private ItemType type; - private String name; + private final String name; public Item(ItemType type, String name) { this.setType(type); diff --git a/iterator/src/main/java/com/iluwatar/iterator/list/TreasureChest.java b/iterator/src/main/java/com/iluwatar/iterator/list/TreasureChest.java index f390c760f..8eb4a8e18 100644 --- a/iterator/src/main/java/com/iluwatar/iterator/list/TreasureChest.java +++ b/iterator/src/main/java/com/iluwatar/iterator/list/TreasureChest.java @@ -32,7 +32,7 @@ import java.util.List; */ public class TreasureChest { - private List items; + private final List items; /** * Constructor. diff --git a/iterator/src/main/java/com/iluwatar/iterator/list/TreasureChestItemIterator.java b/iterator/src/main/java/com/iluwatar/iterator/list/TreasureChestItemIterator.java index 90461c420..a309b4ece 100644 --- a/iterator/src/main/java/com/iluwatar/iterator/list/TreasureChestItemIterator.java +++ b/iterator/src/main/java/com/iluwatar/iterator/list/TreasureChestItemIterator.java @@ -30,9 +30,9 @@ import com.iluwatar.iterator.Iterator; */ public class TreasureChestItemIterator implements Iterator { - private TreasureChest chest; + private final TreasureChest chest; private int idx; - private ItemType type; + private final ItemType type; /** * Constructor. diff --git a/layers/README.md b/layers/README.md index c3c56ad00..1e309f92b 100644 --- a/layers/README.md +++ b/layers/README.md @@ -79,7 +79,7 @@ public class CakeViewImpl implements View { private static final Logger LOGGER = LoggerFactory.getLogger(CakeViewImpl.class); - private CakeBakingService cakeBakingService; + private final CakeBakingService cakeBakingService; public CakeViewImpl(CakeBakingService cakeBakingService) { this.cakeBakingService = cakeBakingService; diff --git a/layers/src/main/java/com/iluwatar/layers/app/App.java b/layers/src/main/java/com/iluwatar/layers/app/App.java index afeb5ba50..e5a4f9995 100644 --- a/layers/src/main/java/com/iluwatar/layers/app/App.java +++ b/layers/src/main/java/com/iluwatar/layers/app/App.java @@ -80,7 +80,7 @@ import java.util.List; */ public class App { - private static CakeBakingService cakeBakingService = new CakeBakingServiceImpl(); + private static final CakeBakingService cakeBakingService = new CakeBakingServiceImpl(); /** * Application entry point. diff --git a/layers/src/main/java/com/iluwatar/layers/service/CakeBakingServiceImpl.java b/layers/src/main/java/com/iluwatar/layers/service/CakeBakingServiceImpl.java index 226b5bcea..14fee4dfa 100644 --- a/layers/src/main/java/com/iluwatar/layers/service/CakeBakingServiceImpl.java +++ b/layers/src/main/java/com/iluwatar/layers/service/CakeBakingServiceImpl.java @@ -52,7 +52,7 @@ import org.springframework.transaction.annotation.Transactional; @Transactional public class CakeBakingServiceImpl implements CakeBakingService { - private AbstractApplicationContext context; + private final AbstractApplicationContext context; public CakeBakingServiceImpl() { this.context = new ClassPathXmlApplicationContext("applicationContext.xml"); diff --git a/layers/src/main/java/com/iluwatar/layers/view/CakeViewImpl.java b/layers/src/main/java/com/iluwatar/layers/view/CakeViewImpl.java index 5fcaac776..a5246e7db 100644 --- a/layers/src/main/java/com/iluwatar/layers/view/CakeViewImpl.java +++ b/layers/src/main/java/com/iluwatar/layers/view/CakeViewImpl.java @@ -34,7 +34,7 @@ public class CakeViewImpl implements View { private static final Logger LOGGER = LoggerFactory.getLogger(CakeViewImpl.class); - private CakeBakingService cakeBakingService; + private final CakeBakingService cakeBakingService; public CakeViewImpl(CakeBakingService cakeBakingService) { this.cakeBakingService = cakeBakingService; diff --git a/layers/src/test/java/com/iluwatar/layers/view/CakeViewImplTest.java b/layers/src/test/java/com/iluwatar/layers/view/CakeViewImplTest.java index b707731d2..3c13966de 100644 --- a/layers/src/test/java/com/iluwatar/layers/view/CakeViewImplTest.java +++ b/layers/src/test/java/com/iluwatar/layers/view/CakeViewImplTest.java @@ -90,7 +90,7 @@ public class CakeViewImplTest { private class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender(Class clazz) { ((Logger) LoggerFactory.getLogger(clazz)).addAppender(this); diff --git a/lazy-loading/src/main/java/com/iluwatar/lazy/loading/Java8Holder.java b/lazy-loading/src/main/java/com/iluwatar/lazy/loading/Java8Holder.java index 2854a7822..395dfb81c 100644 --- a/lazy-loading/src/main/java/com/iluwatar/lazy/loading/Java8Holder.java +++ b/lazy-loading/src/main/java/com/iluwatar/lazy/loading/Java8Holder.java @@ -55,7 +55,7 @@ public class Java8Holder { } } - if (!HeavyFactory.class.isInstance(heavy)) { + if (!(heavy instanceof HeavyFactory)) { heavy = new HeavyFactory(); } diff --git a/leader-followers/src/main/java/com.iluwatar.leaderfollowers/TaskSet.java b/leader-followers/src/main/java/com.iluwatar.leaderfollowers/TaskSet.java index 3138427a3..3461bc8c0 100644 --- a/leader-followers/src/main/java/com.iluwatar.leaderfollowers/TaskSet.java +++ b/leader-followers/src/main/java/com.iluwatar.leaderfollowers/TaskSet.java @@ -31,7 +31,7 @@ import java.util.concurrent.BlockingQueue; */ public class TaskSet { - private BlockingQueue queue = new ArrayBlockingQueue<>(100); + private final BlockingQueue queue = new ArrayBlockingQueue<>(100); public void addTask(Task task) throws InterruptedException { queue.put(task); diff --git a/leader-followers/src/main/java/com.iluwatar.leaderfollowers/WorkCenter.java b/leader-followers/src/main/java/com.iluwatar.leaderfollowers/WorkCenter.java index 7c63d95d2..935462037 100644 --- a/leader-followers/src/main/java/com.iluwatar.leaderfollowers/WorkCenter.java +++ b/leader-followers/src/main/java/com.iluwatar.leaderfollowers/WorkCenter.java @@ -34,7 +34,7 @@ import java.util.concurrent.CopyOnWriteArrayList; public class WorkCenter { private Worker leader; - private List workers = new CopyOnWriteArrayList<>(); + private final List workers = new CopyOnWriteArrayList<>(); /** * Create workers and set leader. diff --git a/master-worker-pattern/src/main/java/com/iluwatar/masterworker/system/systemmaster/Master.java b/master-worker-pattern/src/main/java/com/iluwatar/masterworker/system/systemmaster/Master.java index 2466df256..4578752c3 100644 --- a/master-worker-pattern/src/main/java/com/iluwatar/masterworker/system/systemmaster/Master.java +++ b/master-worker-pattern/src/main/java/com/iluwatar/masterworker/system/systemmaster/Master.java @@ -40,7 +40,7 @@ public abstract class Master { private final int numOfWorkers; private final ArrayList workers; private int expectedNumResults; - private Hashtable allResultData; + private final Hashtable allResultData; private Result finalResult; Master(int numOfWorkers) { diff --git a/mediator/src/main/java/com/iluwatar/mediator/Action.java b/mediator/src/main/java/com/iluwatar/mediator/Action.java index 66e1f42c4..17613b5ab 100644 --- a/mediator/src/main/java/com/iluwatar/mediator/Action.java +++ b/mediator/src/main/java/com/iluwatar/mediator/Action.java @@ -1,52 +1,52 @@ -/* - * 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.mediator; - -/** - * Action enumeration. - */ -public enum Action { - - HUNT("hunted a rabbit", "arrives for dinner"), - TALE("tells a tale", "comes to listen"), - GOLD("found gold", "takes his share of the gold"), - ENEMY("spotted enemies", "runs for cover"), - NONE("", ""); - - private String title; - private String description; - - Action(String title, String description) { - this.title = title; - this.description = description; - } - - public String getDescription() { - return description; - } - - public String toString() { - return title; - } -} +/* + * 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.mediator; + +/** + * Action enumeration. + */ +public enum Action { + + HUNT("hunted a rabbit", "arrives for dinner"), + TALE("tells a tale", "comes to listen"), + GOLD("found gold", "takes his share of the gold"), + ENEMY("spotted enemies", "runs for cover"), + NONE("", ""); + + private final String title; + private final String description; + + Action(String title, String description) { + this.title = title; + this.description = description; + } + + public String getDescription() { + return description; + } + + public String toString() { + return title; + } +} diff --git a/mediator/src/test/java/com/iluwatar/mediator/PartyMemberTest.java b/mediator/src/test/java/com/iluwatar/mediator/PartyMemberTest.java index 951f8e166..01e855179 100644 --- a/mediator/src/test/java/com/iluwatar/mediator/PartyMemberTest.java +++ b/mediator/src/test/java/com/iluwatar/mediator/PartyMemberTest.java @@ -121,7 +121,7 @@ public class PartyMemberTest { } private class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender(Class clazz) { ((Logger) LoggerFactory.getLogger(clazz)).addAppender(this); diff --git a/memento/README.md b/memento/README.md index 8011dfc49..b8d95b72a 100644 --- a/memento/README.md +++ b/memento/README.md @@ -38,7 +38,7 @@ public enum StarType { SUN("sun"), RED_GIANT("red giant"), WHITE_DWARF("white dwarf"), SUPERNOVA("supernova"), DEAD( "dead star"), UNDEFINED(""); - private String title; + private final String title; StarType(String title) { this.title = title; diff --git a/memento/src/main/java/com/iluwatar/memento/StarType.java b/memento/src/main/java/com/iluwatar/memento/StarType.java index 507cd506b..339f05f9f 100644 --- a/memento/src/main/java/com/iluwatar/memento/StarType.java +++ b/memento/src/main/java/com/iluwatar/memento/StarType.java @@ -31,7 +31,7 @@ public enum StarType { SUN("sun"), RED_GIANT("red giant"), WHITE_DWARF("white dwarf"), SUPERNOVA("supernova"), DEAD( "dead star"), UNDEFINED(""); - private String title; + private final String title; StarType(String title) { this.title = title; diff --git a/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Fatigue.java b/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Fatigue.java index b1663df1f..2b7ca3999 100644 --- a/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Fatigue.java +++ b/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Fatigue.java @@ -30,7 +30,7 @@ public enum Fatigue { ALERT("alert"), TIRED("tired"), SLEEPING("sleeping"); - private String title; + private final String title; Fatigue(String title) { this.title = title; diff --git a/model-view-controller/src/main/java/com/iluwatar/model/view/controller/GiantController.java b/model-view-controller/src/main/java/com/iluwatar/model/view/controller/GiantController.java index e66608117..9acb49db4 100644 --- a/model-view-controller/src/main/java/com/iluwatar/model/view/controller/GiantController.java +++ b/model-view-controller/src/main/java/com/iluwatar/model/view/controller/GiantController.java @@ -28,8 +28,8 @@ package com.iluwatar.model.view.controller; */ public class GiantController { - private GiantModel giant; - private GiantView view; + private final GiantModel giant; + private final GiantView view; public GiantController(GiantModel giant, GiantView view) { this.giant = giant; diff --git a/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Health.java b/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Health.java index 30b3b2b90..a8346b9c7 100644 --- a/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Health.java +++ b/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Health.java @@ -30,7 +30,7 @@ public enum Health { HEALTHY("healthy"), WOUNDED("wounded"), DEAD("dead"); - private String title; + private final String title; Health(String title) { this.title = title; diff --git a/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Nourishment.java b/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Nourishment.java index 3ced564cc..c61d2de79 100644 --- a/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Nourishment.java +++ b/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Nourishment.java @@ -30,7 +30,7 @@ public enum Nourishment { SATURATED("saturated"), HUNGRY("hungry"), STARVING("starving"); - private String title; + private final String title; Nourishment(String title) { this.title = title; diff --git a/model-view-controller/src/test/java/com/iluwatar/model/view/controller/GiantViewTest.java b/model-view-controller/src/test/java/com/iluwatar/model/view/controller/GiantViewTest.java index a3e33f9dd..9d6421d13 100644 --- a/model-view-controller/src/test/java/com/iluwatar/model/view/controller/GiantViewTest.java +++ b/model-view-controller/src/test/java/com/iluwatar/model/view/controller/GiantViewTest.java @@ -75,7 +75,7 @@ public class GiantViewTest { * Logging Appender Implementation */ public class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender(Class clazz) { ((Logger) LoggerFactory.getLogger(clazz)).addAppender(this); diff --git a/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorJFrame.java b/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorJFrame.java index 77523ccaa..6c4df5231 100644 --- a/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorJFrame.java +++ b/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorJFrame.java @@ -48,37 +48,37 @@ public class FileSelectorJFrame extends JFrame implements FileSelectorView, Acti /** * The "OK" button for loading the file. */ - private JButton ok; + private final JButton ok; /** * The cancel button. */ - private JButton cancel; + private final JButton cancel; /** * The information label. */ - private JLabel info; + private final JLabel info; /** * The contents label. */ - private JLabel contents; + private final JLabel contents; /** * The text field for giving the name of the file that we want to open. */ - private JTextField input; + private final JTextField input; /** * A text area that will keep the contents of the file opened. */ - private JTextArea area; + private final JTextArea area; /** * The panel that will hold our widgets. */ - private JPanel panel; + private final JPanel panel; /** * The Presenter component that the frame will interact with. diff --git a/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorPresenter.java b/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorPresenter.java index 35e1c0076..6fa95b125 100644 --- a/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorPresenter.java +++ b/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorPresenter.java @@ -41,7 +41,7 @@ public class FileSelectorPresenter implements Serializable { /** * The View component that the presenter interacts with. */ - private FileSelectorView view; + private final FileSelectorView view; /** * The Model component that the presenter interacts with. diff --git a/monad/src/main/java/com/iluwatar/monad/User.java b/monad/src/main/java/com/iluwatar/monad/User.java index 77766d1aa..8644c4c0a 100644 --- a/monad/src/main/java/com/iluwatar/monad/User.java +++ b/monad/src/main/java/com/iluwatar/monad/User.java @@ -1,66 +1,66 @@ -/* - * 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.monad; - -/** - * User Definition. - */ -public class User { - - private String name; - private int age; - private Sex sex; - private String email; - - /** - * Constructor. - * - * @param name - name - * @param age - age - * @param sex - sex - * @param email - email address - */ - public User(String name, int age, Sex sex, String email) { - this.name = name; - this.age = age; - this.sex = sex; - this.email = email; - } - - public String getName() { - return name; - } - - public int getAge() { - return age; - } - - public Sex getSex() { - return sex; - } - - public String getEmail() { - return email; - } -} +/* + * 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.monad; + +/** + * User Definition. + */ +public class User { + + private final String name; + private final int age; + private final Sex sex; + private final String email; + + /** + * Constructor. + * + * @param name - name + * @param age - age + * @param sex - sex + * @param email - email address + */ + public User(String name, int age, Sex sex, String email) { + this.name = name; + this.age = age; + this.sex = sex; + this.email = email; + } + + public String getName() { + return name; + } + + public int getAge() { + return age; + } + + public Sex getSex() { + return sex; + } + + public String getEmail() { + return email; + } +} diff --git a/multiton/README.md b/multiton/README.md index ec1429a8f..85ce3acf2 100644 --- a/multiton/README.md +++ b/multiton/README.md @@ -35,14 +35,14 @@ Nazgul is the multiton class. ```java public enum NazgulName { - KHAMUL, MURAZOR, DWAR, JI_INDUR, AKHORAHIL, HOARMURATH, ADUNAPHEL, REN, UVATHA; + KHAMUL, MURAZOR, DWAR, JI_INDUR, AKHORAHIL, HOARMURATH, ADUNAPHEL, REN, UVATHA } public final class Nazgul { - private static Map nazguls; + private static final Map nazguls; - private NazgulName name; + private final NazgulName name; static { nazguls = new ConcurrentHashMap<>(); diff --git a/multiton/src/main/java/com/iluwatar/multiton/Nazgul.java b/multiton/src/main/java/com/iluwatar/multiton/Nazgul.java index f55f85aca..e08107eeb 100644 --- a/multiton/src/main/java/com/iluwatar/multiton/Nazgul.java +++ b/multiton/src/main/java/com/iluwatar/multiton/Nazgul.java @@ -31,9 +31,9 @@ import java.util.concurrent.ConcurrentHashMap; */ public final class Nazgul { - private static Map nazguls; + private static final Map nazguls; - private NazgulName name; + private final NazgulName name; static { nazguls = new ConcurrentHashMap<>(); diff --git a/multiton/src/main/java/com/iluwatar/multiton/NazgulEnum.java b/multiton/src/main/java/com/iluwatar/multiton/NazgulEnum.java index 5b5c48d66..ec20fbc97 100644 --- a/multiton/src/main/java/com/iluwatar/multiton/NazgulEnum.java +++ b/multiton/src/main/java/com/iluwatar/multiton/NazgulEnum.java @@ -28,6 +28,6 @@ package com.iluwatar.multiton; */ public enum NazgulEnum { - KHAMUL, MURAZOR, DWAR, JI_INDUR, AKHORAHIL, HOARMURATH, ADUNAPHEL, REN, UVATHA; + KHAMUL, MURAZOR, DWAR, JI_INDUR, AKHORAHIL, HOARMURATH, ADUNAPHEL, REN, UVATHA } diff --git a/multiton/src/main/java/com/iluwatar/multiton/NazgulName.java b/multiton/src/main/java/com/iluwatar/multiton/NazgulName.java index c7865dceb..76702c358 100644 --- a/multiton/src/main/java/com/iluwatar/multiton/NazgulName.java +++ b/multiton/src/main/java/com/iluwatar/multiton/NazgulName.java @@ -28,6 +28,6 @@ package com.iluwatar.multiton; */ public enum NazgulName { - KHAMUL, MURAZOR, DWAR, JI_INDUR, AKHORAHIL, HOARMURATH, ADUNAPHEL, REN, UVATHA; + KHAMUL, MURAZOR, DWAR, JI_INDUR, AKHORAHIL, HOARMURATH, ADUNAPHEL, REN, UVATHA } diff --git a/null-object/README.md b/null-object/README.md index 0fce86f0e..5b943630e 100644 --- a/null-object/README.md +++ b/null-object/README.md @@ -101,7 +101,7 @@ public class NodeImpl implements Node { public final class NullNode implements Node { - private static NullNode instance = new NullNode(); + private static final NullNode instance = new NullNode(); private NullNode() { } diff --git a/null-object/src/main/java/com/iluwatar/nullobject/NullNode.java b/null-object/src/main/java/com/iluwatar/nullobject/NullNode.java index 9b28c249b..472a1a2fd 100644 --- a/null-object/src/main/java/com/iluwatar/nullobject/NullNode.java +++ b/null-object/src/main/java/com/iluwatar/nullobject/NullNode.java @@ -30,7 +30,7 @@ package com.iluwatar.nullobject; */ public final class NullNode implements Node { - private static NullNode instance = new NullNode(); + private static final NullNode instance = new NullNode(); private NullNode() { } diff --git a/null-object/src/test/java/com/iluwatar/nullobject/TreeTest.java b/null-object/src/test/java/com/iluwatar/nullobject/TreeTest.java index 4ff30f524..3fe584425 100644 --- a/null-object/src/test/java/com/iluwatar/nullobject/TreeTest.java +++ b/null-object/src/test/java/com/iluwatar/nullobject/TreeTest.java @@ -141,7 +141,7 @@ public class TreeTest { } private class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender() { ((Logger) LoggerFactory.getLogger("root")).addAppender(this); diff --git a/object-mother/src/main/java/com/iluwatar/objectmother/Queen.java b/object-mother/src/main/java/com/iluwatar/objectmother/Queen.java index 4c704f6b1..308760ba9 100644 --- a/object-mother/src/main/java/com/iluwatar/objectmother/Queen.java +++ b/object-mother/src/main/java/com/iluwatar/objectmother/Queen.java @@ -66,9 +66,6 @@ public class Queen implements Royalty { * @return A value which describes if the flirt was successful or not. */ public boolean getFlirted(King king) { - if (this.isFlirty && king.isHappy && !king.isDrunk) { - return true; - } - return false; + return this.isFlirty && king.isHappy && !king.isDrunk; } } diff --git a/object-pool/README.md b/object-pool/README.md index a8a20638c..34d216a02 100644 --- a/object-pool/README.md +++ b/object-pool/README.md @@ -36,7 +36,7 @@ Here's the basic Oliphaunt class. These are very expensive to create. ```java public class Oliphaunt { - private static AtomicInteger counter = new AtomicInteger(0); + private static final AtomicInteger counter = new AtomicInteger(0); private final int id; @@ -65,8 +65,8 @@ Next we present the Object Pool and more specifically Oliphaunt Pool. ```java public abstract class ObjectPool { - private Set available = new HashSet<>(); - private Set inUse = new HashSet<>(); + private final Set available = new HashSet<>(); + private final Set inUse = new HashSet<>(); protected abstract T create(); diff --git a/object-pool/src/main/java/com/iluwatar/object/pool/ObjectPool.java b/object-pool/src/main/java/com/iluwatar/object/pool/ObjectPool.java index b8ce3cc05..43ac5d873 100644 --- a/object-pool/src/main/java/com/iluwatar/object/pool/ObjectPool.java +++ b/object-pool/src/main/java/com/iluwatar/object/pool/ObjectPool.java @@ -33,8 +33,8 @@ import java.util.Set; */ public abstract class ObjectPool { - private Set available = new HashSet<>(); - private Set inUse = new HashSet<>(); + private final Set available = new HashSet<>(); + private final Set inUse = new HashSet<>(); protected abstract T create(); diff --git a/object-pool/src/main/java/com/iluwatar/object/pool/Oliphaunt.java b/object-pool/src/main/java/com/iluwatar/object/pool/Oliphaunt.java index 42db07158..09dedbab0 100644 --- a/object-pool/src/main/java/com/iluwatar/object/pool/Oliphaunt.java +++ b/object-pool/src/main/java/com/iluwatar/object/pool/Oliphaunt.java @@ -30,7 +30,7 @@ import java.util.concurrent.atomic.AtomicInteger; */ public class Oliphaunt { - private static AtomicInteger counter = new AtomicInteger(0); + private static final AtomicInteger counter = new AtomicInteger(0); private final int id; diff --git a/observer/README.md b/observer/README.md index edc72ae24..e329a657c 100644 --- a/observer/README.md +++ b/observer/README.md @@ -99,7 +99,7 @@ public class Weather { private static final Logger LOGGER = LoggerFactory.getLogger(Weather.class); private WeatherType currentWeather; - private List observers; + private final List observers; public Weather() { observers = new ArrayList<>(); diff --git a/observer/src/main/java/com/iluwatar/observer/Weather.java b/observer/src/main/java/com/iluwatar/observer/Weather.java index 778858107..a0d80d6bc 100644 --- a/observer/src/main/java/com/iluwatar/observer/Weather.java +++ b/observer/src/main/java/com/iluwatar/observer/Weather.java @@ -37,7 +37,7 @@ public class Weather { private static final Logger LOGGER = LoggerFactory.getLogger(Weather.class); private WeatherType currentWeather; - private List observers; + private final List observers; public Weather() { observers = new ArrayList<>(); diff --git a/observer/src/test/java/com/iluwatar/observer/utils/InMemoryAppender.java b/observer/src/test/java/com/iluwatar/observer/utils/InMemoryAppender.java index b3d2bf1bc..132216d19 100644 --- a/observer/src/test/java/com/iluwatar/observer/utils/InMemoryAppender.java +++ b/observer/src/test/java/com/iluwatar/observer/utils/InMemoryAppender.java @@ -35,7 +35,7 @@ import java.util.List; * InMemory Log Appender Util. */ public class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender(Class clazz) { ((Logger) LoggerFactory.getLogger(clazz)).addAppender(this); diff --git a/page-object/src/test/java/com/iluwatar/pageobject/AlbumListPageTest.java b/page-object/src/test/java/com/iluwatar/pageobject/AlbumListPageTest.java index 779458e05..22bc8a5fb 100644 --- a/page-object/src/test/java/com/iluwatar/pageobject/AlbumListPageTest.java +++ b/page-object/src/test/java/com/iluwatar/pageobject/AlbumListPageTest.java @@ -36,7 +36,7 @@ import org.junit.jupiter.api.Test; */ public class AlbumListPageTest { - private AlbumListPage albumListPage = new AlbumListPage(new WebClient()); + private final AlbumListPage albumListPage = new AlbumListPage(new WebClient()); @BeforeEach public void setUp() { diff --git a/page-object/src/test/java/com/iluwatar/pageobject/AlbumPageTest.java b/page-object/src/test/java/com/iluwatar/pageobject/AlbumPageTest.java index 601093343..68c836bd3 100644 --- a/page-object/src/test/java/com/iluwatar/pageobject/AlbumPageTest.java +++ b/page-object/src/test/java/com/iluwatar/pageobject/AlbumPageTest.java @@ -36,7 +36,7 @@ import org.junit.jupiter.api.Test; */ public class AlbumPageTest { - private AlbumPage albumPage = new AlbumPage(new WebClient()); + private final AlbumPage albumPage = new AlbumPage(new WebClient()); @BeforeEach public void setUp() { diff --git a/page-object/src/test/java/com/iluwatar/pageobject/LoginPageTest.java b/page-object/src/test/java/com/iluwatar/pageobject/LoginPageTest.java index 022f736ca..460bdcf96 100644 --- a/page-object/src/test/java/com/iluwatar/pageobject/LoginPageTest.java +++ b/page-object/src/test/java/com/iluwatar/pageobject/LoginPageTest.java @@ -36,7 +36,7 @@ import org.junit.jupiter.api.Test; */ public class LoginPageTest { - private LoginPage loginPage = new LoginPage(new WebClient()); + private final LoginPage loginPage = new LoginPage(new WebClient()); @BeforeEach public void setUp() { diff --git a/page-object/test-automation/src/test/java/com/iluwatar/pageobject/AlbumListPageTest.java b/page-object/test-automation/src/test/java/com/iluwatar/pageobject/AlbumListPageTest.java index d1b450a24..1acdd5ba5 100644 --- a/page-object/test-automation/src/test/java/com/iluwatar/pageobject/AlbumListPageTest.java +++ b/page-object/test-automation/src/test/java/com/iluwatar/pageobject/AlbumListPageTest.java @@ -34,7 +34,7 @@ import org.junit.jupiter.api.Test; */ public class AlbumListPageTest { - private AlbumListPage albumListPage = new AlbumListPage(new WebClient()); + private final AlbumListPage albumListPage = new AlbumListPage(new WebClient()); @BeforeEach public void setUp() { diff --git a/page-object/test-automation/src/test/java/com/iluwatar/pageobject/AlbumPageTest.java b/page-object/test-automation/src/test/java/com/iluwatar/pageobject/AlbumPageTest.java index 8e694a592..ecde999c3 100644 --- a/page-object/test-automation/src/test/java/com/iluwatar/pageobject/AlbumPageTest.java +++ b/page-object/test-automation/src/test/java/com/iluwatar/pageobject/AlbumPageTest.java @@ -34,7 +34,7 @@ import org.junit.jupiter.api.Test; */ public class AlbumPageTest { - private AlbumPage albumPage = new AlbumPage(new WebClient()); + private final AlbumPage albumPage = new AlbumPage(new WebClient()); @BeforeEach public void setUp() { diff --git a/page-object/test-automation/src/test/java/com/iluwatar/pageobject/LoginPageTest.java b/page-object/test-automation/src/test/java/com/iluwatar/pageobject/LoginPageTest.java index 89668882d..429b7fcc5 100644 --- a/page-object/test-automation/src/test/java/com/iluwatar/pageobject/LoginPageTest.java +++ b/page-object/test-automation/src/test/java/com/iluwatar/pageobject/LoginPageTest.java @@ -34,7 +34,7 @@ import org.junit.jupiter.api.Test; */ public class LoginPageTest { - private LoginPage loginPage = new LoginPage(new WebClient()); + private final LoginPage loginPage = new LoginPage(new WebClient()); @BeforeEach public void setUp() { diff --git a/partial-response/src/main/java/com/iluwatar/partialresponse/VideoResource.java b/partial-response/src/main/java/com/iluwatar/partialresponse/VideoResource.java index a61a3c429..11a4f23ca 100644 --- a/partial-response/src/main/java/com/iluwatar/partialresponse/VideoResource.java +++ b/partial-response/src/main/java/com/iluwatar/partialresponse/VideoResource.java @@ -30,8 +30,8 @@ import java.util.Map; * has all video details. */ public class VideoResource { - private FieldJsonMapper fieldJsonMapper; - private Map videos; + private final FieldJsonMapper fieldJsonMapper; + private final Map videos; /** * Constructor. diff --git a/poison-pill/README.md b/poison-pill/README.md index 823bb7df8..a6cd2fe80 100644 --- a/poison-pill/README.md +++ b/poison-pill/README.md @@ -80,7 +80,7 @@ public interface Message { public class SimpleMessage implements Message { - private Map headers = new HashMap<>(); + private final Map headers = new HashMap<>(); private String body; @Override diff --git a/poison-pill/src/main/java/com/iluwatar/poison/pill/SimpleMessage.java b/poison-pill/src/main/java/com/iluwatar/poison/pill/SimpleMessage.java index 8a7af515f..70d116c9f 100644 --- a/poison-pill/src/main/java/com/iluwatar/poison/pill/SimpleMessage.java +++ b/poison-pill/src/main/java/com/iluwatar/poison/pill/SimpleMessage.java @@ -32,7 +32,7 @@ import java.util.Map; */ public class SimpleMessage implements Message { - private Map headers = new HashMap<>(); + private final Map headers = new HashMap<>(); private String body; @Override diff --git a/poison-pill/src/test/java/com/iluwatar/poison/pill/ConsumerTest.java b/poison-pill/src/test/java/com/iluwatar/poison/pill/ConsumerTest.java index 100565fbc..8365fca17 100644 --- a/poison-pill/src/test/java/com/iluwatar/poison/pill/ConsumerTest.java +++ b/poison-pill/src/test/java/com/iluwatar/poison/pill/ConsumerTest.java @@ -92,7 +92,7 @@ public class ConsumerTest { } private class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender(Class clazz) { ((Logger) LoggerFactory.getLogger(clazz)).addAppender(this); diff --git a/private-class-data/src/main/java/com/iluwatar/privateclassdata/ImmutableStew.java b/private-class-data/src/main/java/com/iluwatar/privateclassdata/ImmutableStew.java index 695424695..d312cd34a 100644 --- a/private-class-data/src/main/java/com/iluwatar/privateclassdata/ImmutableStew.java +++ b/private-class-data/src/main/java/com/iluwatar/privateclassdata/ImmutableStew.java @@ -1,50 +1,50 @@ -/* - * 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.privateclassdata; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Immutable stew class, protected with Private Class Data pattern. - */ -public class ImmutableStew { - - private static final Logger LOGGER = LoggerFactory.getLogger(ImmutableStew.class); - - private StewData data; - - public ImmutableStew(int numPotatoes, int numCarrots, int numMeat, int numPeppers) { - data = new StewData(numPotatoes, numCarrots, numMeat, numPeppers); - } - - /** - * Mix the stew. - */ - public void mix() { - LOGGER - .info("Mixing the immutable stew we find: {} potatoes, {} carrots, {} meat and {} peppers", - data.getNumPotatoes(), data.getNumCarrots(), data.getNumMeat(), data.getNumPeppers()); - } -} +/* + * 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.privateclassdata; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Immutable stew class, protected with Private Class Data pattern. + */ +public class ImmutableStew { + + private static final Logger LOGGER = LoggerFactory.getLogger(ImmutableStew.class); + + private final StewData data; + + public ImmutableStew(int numPotatoes, int numCarrots, int numMeat, int numPeppers) { + data = new StewData(numPotatoes, numCarrots, numMeat, numPeppers); + } + + /** + * Mix the stew. + */ + public void mix() { + LOGGER + .info("Mixing the immutable stew we find: {} potatoes, {} carrots, {} meat and {} peppers", + data.getNumPotatoes(), data.getNumCarrots(), data.getNumMeat(), data.getNumPeppers()); + } +} diff --git a/private-class-data/src/main/java/com/iluwatar/privateclassdata/StewData.java b/private-class-data/src/main/java/com/iluwatar/privateclassdata/StewData.java index bcdaba3e9..1b0fd269b 100644 --- a/private-class-data/src/main/java/com/iluwatar/privateclassdata/StewData.java +++ b/private-class-data/src/main/java/com/iluwatar/privateclassdata/StewData.java @@ -1,61 +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.privateclassdata; - -/** - * Stew ingredients. - */ -public class StewData { - - private int numPotatoes; - private int numCarrots; - private int numMeat; - private int numPeppers; - - /** - * Constructor. - */ - public StewData(int numPotatoes, int numCarrots, int numMeat, int numPeppers) { - this.numPotatoes = numPotatoes; - this.numCarrots = numCarrots; - this.numMeat = numMeat; - this.numPeppers = numPeppers; - } - - public int getNumPotatoes() { - return numPotatoes; - } - - public int getNumCarrots() { - return numCarrots; - } - - public int getNumMeat() { - return numMeat; - } - - public int getNumPeppers() { - return numPeppers; - } -} +/* + * 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.privateclassdata; + +/** + * Stew ingredients. + */ +public class StewData { + + private final int numPotatoes; + private final int numCarrots; + private final int numMeat; + private final int numPeppers; + + /** + * Constructor. + */ + public StewData(int numPotatoes, int numCarrots, int numMeat, int numPeppers) { + this.numPotatoes = numPotatoes; + this.numCarrots = numCarrots; + this.numMeat = numMeat; + this.numPeppers = numPeppers; + } + + public int getNumPotatoes() { + return numPotatoes; + } + + public int getNumCarrots() { + return numCarrots; + } + + public int getNumMeat() { + return numMeat; + } + + public int getNumPeppers() { + return numPeppers; + } +} diff --git a/private-class-data/src/test/java/com/iluwatar/privateclassdata/utils/InMemoryAppender.java b/private-class-data/src/test/java/com/iluwatar/privateclassdata/utils/InMemoryAppender.java index 6fbe638ae..bbcbc8021 100644 --- a/private-class-data/src/test/java/com/iluwatar/privateclassdata/utils/InMemoryAppender.java +++ b/private-class-data/src/test/java/com/iluwatar/privateclassdata/utils/InMemoryAppender.java @@ -34,7 +34,7 @@ import org.slf4j.LoggerFactory; * InMemory Log Appender Util. */ public class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender() { ((Logger) LoggerFactory.getLogger("root")).addAppender(this); diff --git a/producer-consumer/src/main/java/com/iluwatar/producer/consumer/Item.java b/producer-consumer/src/main/java/com/iluwatar/producer/consumer/Item.java index 6991ec4d1..89f692282 100644 --- a/producer-consumer/src/main/java/com/iluwatar/producer/consumer/Item.java +++ b/producer-consumer/src/main/java/com/iluwatar/producer/consumer/Item.java @@ -28,9 +28,9 @@ package com.iluwatar.producer.consumer; */ public class Item { - private String producer; + private final String producer; - private int id; + private final int id; public Item(String producer, int id) { this.id = id; diff --git a/producer-consumer/src/main/java/com/iluwatar/producer/consumer/ItemQueue.java b/producer-consumer/src/main/java/com/iluwatar/producer/consumer/ItemQueue.java index 674fb069a..118e3265d 100644 --- a/producer-consumer/src/main/java/com/iluwatar/producer/consumer/ItemQueue.java +++ b/producer-consumer/src/main/java/com/iluwatar/producer/consumer/ItemQueue.java @@ -31,7 +31,7 @@ import java.util.concurrent.LinkedBlockingQueue; */ public class ItemQueue { - private BlockingQueue queue; + private final BlockingQueue queue; public ItemQueue() { diff --git a/prototype/src/main/java/com/iluwatar/prototype/ElfBeast.java b/prototype/src/main/java/com/iluwatar/prototype/ElfBeast.java index 1401460d6..8e2ed9474 100644 --- a/prototype/src/main/java/com/iluwatar/prototype/ElfBeast.java +++ b/prototype/src/main/java/com/iluwatar/prototype/ElfBeast.java @@ -28,7 +28,7 @@ package com.iluwatar.prototype; */ public class ElfBeast extends Beast { - private String helpType; + private final String helpType; public ElfBeast(String helpType) { this.helpType = helpType; diff --git a/prototype/src/main/java/com/iluwatar/prototype/ElfMage.java b/prototype/src/main/java/com/iluwatar/prototype/ElfMage.java index 4a7eea98f..42a54ca97 100644 --- a/prototype/src/main/java/com/iluwatar/prototype/ElfMage.java +++ b/prototype/src/main/java/com/iluwatar/prototype/ElfMage.java @@ -28,7 +28,7 @@ package com.iluwatar.prototype; */ public class ElfMage extends Mage { - private String helpType; + private final String helpType; public ElfMage(String helpType) { this.helpType = helpType; diff --git a/prototype/src/main/java/com/iluwatar/prototype/ElfWarlord.java b/prototype/src/main/java/com/iluwatar/prototype/ElfWarlord.java index 101cd5942..fb426a444 100644 --- a/prototype/src/main/java/com/iluwatar/prototype/ElfWarlord.java +++ b/prototype/src/main/java/com/iluwatar/prototype/ElfWarlord.java @@ -28,7 +28,7 @@ package com.iluwatar.prototype; */ public class ElfWarlord extends Warlord { - private String helpType; + private final String helpType; public ElfWarlord(String helpType) { this.helpType = helpType; diff --git a/prototype/src/main/java/com/iluwatar/prototype/HeroFactoryImpl.java b/prototype/src/main/java/com/iluwatar/prototype/HeroFactoryImpl.java index eb84b2982..14516f3b4 100644 --- a/prototype/src/main/java/com/iluwatar/prototype/HeroFactoryImpl.java +++ b/prototype/src/main/java/com/iluwatar/prototype/HeroFactoryImpl.java @@ -1,65 +1,65 @@ -/* - * 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.prototype; - -/** - * Concrete factory class. - */ -public class HeroFactoryImpl implements HeroFactory { - - private Mage mage; - private Warlord warlord; - private Beast beast; - - /** - * Constructor. - */ - public HeroFactoryImpl(Mage mage, Warlord warlord, Beast beast) { - this.mage = mage; - this.warlord = warlord; - this.beast = beast; - } - - /** - * Create mage. - */ - public Mage createMage() { - return mage.copy(); - } - - /** - * Create warlord. - */ - public Warlord createWarlord() { - return warlord.copy(); - } - - /** - * Create beast. - */ - public Beast createBeast() { - return beast.copy(); - } - -} +/* + * 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.prototype; + +/** + * Concrete factory class. + */ +public class HeroFactoryImpl implements HeroFactory { + + private final Mage mage; + private final Warlord warlord; + private final Beast beast; + + /** + * Constructor. + */ + public HeroFactoryImpl(Mage mage, Warlord warlord, Beast beast) { + this.mage = mage; + this.warlord = warlord; + this.beast = beast; + } + + /** + * Create mage. + */ + public Mage createMage() { + return mage.copy(); + } + + /** + * Create warlord. + */ + public Warlord createWarlord() { + return warlord.copy(); + } + + /** + * Create beast. + */ + public Beast createBeast() { + return beast.copy(); + } + +} diff --git a/prototype/src/main/java/com/iluwatar/prototype/OrcBeast.java b/prototype/src/main/java/com/iluwatar/prototype/OrcBeast.java index cf3dc18d8..91339887c 100644 --- a/prototype/src/main/java/com/iluwatar/prototype/OrcBeast.java +++ b/prototype/src/main/java/com/iluwatar/prototype/OrcBeast.java @@ -28,7 +28,7 @@ package com.iluwatar.prototype; */ public class OrcBeast extends Beast { - private String weapon; + private final String weapon; public OrcBeast(String weapon) { this.weapon = weapon; diff --git a/prototype/src/main/java/com/iluwatar/prototype/OrcMage.java b/prototype/src/main/java/com/iluwatar/prototype/OrcMage.java index cb8239c3f..439e7f368 100644 --- a/prototype/src/main/java/com/iluwatar/prototype/OrcMage.java +++ b/prototype/src/main/java/com/iluwatar/prototype/OrcMage.java @@ -28,7 +28,7 @@ package com.iluwatar.prototype; */ public class OrcMage extends Mage { - private String weapon; + private final String weapon; public OrcMage(String weapon) { this.weapon = weapon; diff --git a/prototype/src/main/java/com/iluwatar/prototype/OrcWarlord.java b/prototype/src/main/java/com/iluwatar/prototype/OrcWarlord.java index 39facc41e..a2ae31b4d 100644 --- a/prototype/src/main/java/com/iluwatar/prototype/OrcWarlord.java +++ b/prototype/src/main/java/com/iluwatar/prototype/OrcWarlord.java @@ -28,7 +28,7 @@ package com.iluwatar.prototype; */ public class OrcWarlord extends Warlord { - private String weapon; + private final String weapon; public OrcWarlord(String weapon) { this.weapon = weapon; diff --git a/proxy/src/test/java/com/iluwatar/proxy/utils/InMemoryAppender.java b/proxy/src/test/java/com/iluwatar/proxy/utils/InMemoryAppender.java index 2187c3300..173825288 100644 --- a/proxy/src/test/java/com/iluwatar/proxy/utils/InMemoryAppender.java +++ b/proxy/src/test/java/com/iluwatar/proxy/utils/InMemoryAppender.java @@ -35,7 +35,7 @@ import org.slf4j.LoggerFactory; * InMemory Log Appender Util. */ public class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender(Class clazz) { ((Logger) LoggerFactory.getLogger(clazz)).addAppender(this); diff --git a/reactor/src/main/java/com/iluwatar/reactor/app/App.java b/reactor/src/main/java/com/iluwatar/reactor/app/App.java index 3bd8176a6..f656eacf6 100644 --- a/reactor/src/main/java/com/iluwatar/reactor/app/App.java +++ b/reactor/src/main/java/com/iluwatar/reactor/app/App.java @@ -89,8 +89,8 @@ import java.util.List; public class App { private NioReactor reactor; - private List channels = new ArrayList<>(); - private Dispatcher dispatcher; + private final List channels = new ArrayList<>(); + private final Dispatcher dispatcher; /** * Creates an instance of App which will use provided dispatcher for dispatching events on diff --git a/reactor/src/main/java/com/iluwatar/reactor/framework/NioDatagramChannel.java b/reactor/src/main/java/com/iluwatar/reactor/framework/NioDatagramChannel.java index 13657cdb2..aba99d65c 100644 --- a/reactor/src/main/java/com/iluwatar/reactor/framework/NioDatagramChannel.java +++ b/reactor/src/main/java/com/iluwatar/reactor/framework/NioDatagramChannel.java @@ -134,7 +134,7 @@ public class NioDatagramChannel extends AbstractNioChannel { */ public static class DatagramPacket { private SocketAddress sender; - private ByteBuffer data; + private final ByteBuffer data; private SocketAddress receiver; /** diff --git a/reactor/src/main/java/com/iluwatar/reactor/framework/NioReactor.java b/reactor/src/main/java/com/iluwatar/reactor/framework/NioReactor.java index 1a0b17386..77e39a88d 100644 --- a/reactor/src/main/java/com/iluwatar/reactor/framework/NioReactor.java +++ b/reactor/src/main/java/com/iluwatar/reactor/framework/NioReactor.java @@ -228,8 +228,8 @@ public class NioReactor { * A command that changes the interested operations of the key provided. */ class ChangeKeyOpsCommand implements Runnable { - private SelectionKey key; - private int interestedOps; + private final SelectionKey key; + private final int interestedOps; public ChangeKeyOpsCommand(SelectionKey key, int interestedOps) { this.key = key; diff --git a/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/Reader.java b/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/Reader.java index 6d705de2f..c54e62e58 100644 --- a/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/Reader.java +++ b/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/Reader.java @@ -34,11 +34,11 @@ public class Reader implements Runnable { private static final Logger LOGGER = LoggerFactory.getLogger(Reader.class); - private Lock readLock; + private final Lock readLock; - private String name; + private final String name; - private long readingTime; + private final long readingTime; /** * Create new Reader. diff --git a/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/ReaderWriterLock.java b/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/ReaderWriterLock.java index 99c9b056b..932428b4f 100644 --- a/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/ReaderWriterLock.java +++ b/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/ReaderWriterLock.java @@ -59,8 +59,8 @@ public class ReaderWriterLock implements ReadWriteLock { */ private final Set globalMutex = new HashSet<>(); - private ReadLock readerLock = new ReadLock(); - private WriteLock writerLock = new WriteLock(); + private final ReadLock readerLock = new ReadLock(); + private final WriteLock writerLock = new WriteLock(); @Override public Lock readLock() { diff --git a/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/Writer.java b/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/Writer.java index 7a971b28b..fbc8321f2 100644 --- a/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/Writer.java +++ b/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/Writer.java @@ -34,11 +34,11 @@ public class Writer implements Runnable { private static final Logger LOGGER = LoggerFactory.getLogger(Writer.class); - private Lock writeLock; + private final Lock writeLock; - private String name; + private final String name; - private long writingTime; + private final long writingTime; /** * Create new Writer who writes for 250ms. diff --git a/reader-writer-lock/src/test/java/com/iluwatar/reader/writer/lock/utils/InMemoryAppender.java b/reader-writer-lock/src/test/java/com/iluwatar/reader/writer/lock/utils/InMemoryAppender.java index c7e8bc02a..01a63d6c8 100644 --- a/reader-writer-lock/src/test/java/com/iluwatar/reader/writer/lock/utils/InMemoryAppender.java +++ b/reader-writer-lock/src/test/java/com/iluwatar/reader/writer/lock/utils/InMemoryAppender.java @@ -34,7 +34,7 @@ import org.slf4j.LoggerFactory; * InMemory Log Appender Util. */ public class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender(Class clazz) { ((Logger) LoggerFactory.getLogger(clazz)).addAppender(this); diff --git a/repository/README.md b/repository/README.md index 09a9a2bba..ad603ee2b 100644 --- a/repository/README.md +++ b/repository/README.md @@ -157,9 +157,9 @@ public class PersonSpecifications { public static class AgeBetweenSpec implements Specification { - private int from; + private final int from; - private int to; + private final int to; public AgeBetweenSpec(int from, int to) { this.from = from; diff --git a/repository/src/main/java/com/iluwatar/repository/PersonSpecifications.java b/repository/src/main/java/com/iluwatar/repository/PersonSpecifications.java index f91c0a6e1..919b746be 100644 --- a/repository/src/main/java/com/iluwatar/repository/PersonSpecifications.java +++ b/repository/src/main/java/com/iluwatar/repository/PersonSpecifications.java @@ -39,9 +39,9 @@ public class PersonSpecifications { */ public static class AgeBetweenSpec implements Specification { - private int from; + private final int from; - private int to; + private final int to; public AgeBetweenSpec(int from, int to) { this.from = from; diff --git a/repository/src/test/java/com/iluwatar/repository/AnnotationBasedRepositoryTest.java b/repository/src/test/java/com/iluwatar/repository/AnnotationBasedRepositoryTest.java index 6b47cbe9a..9e2e1f4e1 100644 --- a/repository/src/test/java/com/iluwatar/repository/AnnotationBasedRepositoryTest.java +++ b/repository/src/test/java/com/iluwatar/repository/AnnotationBasedRepositoryTest.java @@ -48,12 +48,12 @@ public class AnnotationBasedRepositoryTest { @Resource private PersonRepository repository; - private Person peter = new Person("Peter", "Sagan", 17); - private Person nasta = new Person("Nasta", "Kuzminova", 25); - private Person john = new Person("John", "lawrence", 35); - private Person terry = new Person("Terry", "Law", 36); + private final Person peter = new Person("Peter", "Sagan", 17); + private final Person nasta = new Person("Nasta", "Kuzminova", 25); + private final Person john = new Person("John", "lawrence", 35); + private final Person terry = new Person("Terry", "Law", 36); - private List persons = List.of(peter, nasta, john, terry); + private final List persons = List.of(peter, nasta, john, terry); /** * Prepare data for test diff --git a/repository/src/test/java/com/iluwatar/repository/RepositoryTest.java b/repository/src/test/java/com/iluwatar/repository/RepositoryTest.java index ad9587aca..77e2b3e35 100644 --- a/repository/src/test/java/com/iluwatar/repository/RepositoryTest.java +++ b/repository/src/test/java/com/iluwatar/repository/RepositoryTest.java @@ -48,12 +48,12 @@ public class RepositoryTest { @Resource private PersonRepository repository; - private Person peter = new Person("Peter", "Sagan", 17); - private Person nasta = new Person("Nasta", "Kuzminova", 25); - private Person john = new Person("John", "lawrence", 35); - private Person terry = new Person("Terry", "Law", 36); + private final Person peter = new Person("Peter", "Sagan", 17); + private final Person nasta = new Person("Nasta", "Kuzminova", 25); + private final Person john = new Person("John", "lawrence", 35); + private final Person terry = new Person("Terry", "Law", 36); - private List persons = List.of(peter, nasta, john, terry); + private final List persons = List.of(peter, nasta, john, terry); /** * Prepare data for test diff --git a/resource-acquisition-is-initialization/src/test/java/com/iluwatar/resource/acquisition/is/initialization/ClosableTest.java b/resource-acquisition-is-initialization/src/test/java/com/iluwatar/resource/acquisition/is/initialization/ClosableTest.java index 7bba17553..53caabea7 100644 --- a/resource-acquisition-is-initialization/src/test/java/com/iluwatar/resource/acquisition/is/initialization/ClosableTest.java +++ b/resource-acquisition-is-initialization/src/test/java/com/iluwatar/resource/acquisition/is/initialization/ClosableTest.java @@ -68,7 +68,7 @@ public class ClosableTest { * Logging Appender Implementation */ public class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender() { ((Logger) LoggerFactory.getLogger("root")).addAppender(this); diff --git a/role-object/src/main/java/com/iluwatar/roleobject/CustomerCore.java b/role-object/src/main/java/com/iluwatar/roleobject/CustomerCore.java index 966d0e3f0..1c4cf0383 100644 --- a/role-object/src/main/java/com/iluwatar/roleobject/CustomerCore.java +++ b/role-object/src/main/java/com/iluwatar/roleobject/CustomerCore.java @@ -36,7 +36,7 @@ import java.util.Optional; */ public class CustomerCore extends Customer { - private Map roles; + private final Map roles; public CustomerCore() { roles = new HashMap<>(); diff --git a/role-object/src/main/java/com/iluwatar/roleobject/Role.java b/role-object/src/main/java/com/iluwatar/roleobject/Role.java index cbc6cc79b..a776178fb 100644 --- a/role-object/src/main/java/com/iluwatar/roleobject/Role.java +++ b/role-object/src/main/java/com/iluwatar/roleobject/Role.java @@ -34,7 +34,7 @@ public enum Role { Borrower(BorrowerRole.class), Investor(InvestorRole.class); - private Class typeCst; + private final Class typeCst; Role(Class typeCst) { this.typeCst = typeCst; diff --git a/saga/src/main/java/com/iluwatar/saga/choreography/Saga.java b/saga/src/main/java/com/iluwatar/saga/choreography/Saga.java index 818b59a14..506587c76 100644 --- a/saga/src/main/java/com/iluwatar/saga/choreography/Saga.java +++ b/saga/src/main/java/com/iluwatar/saga/choreography/Saga.java @@ -33,7 +33,7 @@ import java.util.List; */ public class Saga { - private List chapters; + private final List chapters; private int pos; private boolean forward; private boolean finished; @@ -153,7 +153,7 @@ public class Saga { * outcoming parameter). */ public static class Chapter { - private String name; + private final String name; private ChapterResult result; private Object inValue; diff --git a/saga/src/main/java/com/iluwatar/saga/choreography/ServiceDiscoveryService.java b/saga/src/main/java/com/iluwatar/saga/choreography/ServiceDiscoveryService.java index a616ff4a5..c6bc7bc80 100644 --- a/saga/src/main/java/com/iluwatar/saga/choreography/ServiceDiscoveryService.java +++ b/saga/src/main/java/com/iluwatar/saga/choreography/ServiceDiscoveryService.java @@ -32,7 +32,7 @@ import java.util.Optional; * The class representing a service discovery pattern. */ public class ServiceDiscoveryService { - private Map services; + private final Map services; /** * find any service. diff --git a/saga/src/main/java/com/iluwatar/saga/orchestration/ChapterResult.java b/saga/src/main/java/com/iluwatar/saga/orchestration/ChapterResult.java index ef34ddb98..b04d22849 100644 --- a/saga/src/main/java/com/iluwatar/saga/orchestration/ChapterResult.java +++ b/saga/src/main/java/com/iluwatar/saga/orchestration/ChapterResult.java @@ -29,8 +29,8 @@ package com.iluwatar.saga.orchestration; * @param incoming value */ public class ChapterResult { - private K value; - private State state; + private final K value; + private final State state; public K getValue() { return value; diff --git a/saga/src/main/java/com/iluwatar/saga/orchestration/Saga.java b/saga/src/main/java/com/iluwatar/saga/orchestration/Saga.java index aff3593f1..1b68d6cf7 100644 --- a/saga/src/main/java/com/iluwatar/saga/orchestration/Saga.java +++ b/saga/src/main/java/com/iluwatar/saga/orchestration/Saga.java @@ -32,7 +32,7 @@ import java.util.List; */ public class Saga { - private List chapters; + private final List chapters; private Saga() { diff --git a/saga/src/main/java/com/iluwatar/saga/orchestration/ServiceDiscoveryService.java b/saga/src/main/java/com/iluwatar/saga/orchestration/ServiceDiscoveryService.java index dbc6e7eb5..f88efae52 100644 --- a/saga/src/main/java/com/iluwatar/saga/orchestration/ServiceDiscoveryService.java +++ b/saga/src/main/java/com/iluwatar/saga/orchestration/ServiceDiscoveryService.java @@ -31,7 +31,7 @@ import java.util.Optional; * The class representing a service discovery pattern. */ public class ServiceDiscoveryService { - private Map> services; + private final Map> services; public Optional find(String service) { return Optional.ofNullable(services.getOrDefault(service, null)); diff --git a/saga/src/test/java/com/iluwatar/saga/orchestration/SagaOrchestratorInternallyTest.java b/saga/src/test/java/com/iluwatar/saga/orchestration/SagaOrchestratorInternallyTest.java index 423b8e12e..f80a46fdc 100644 --- a/saga/src/test/java/com/iluwatar/saga/orchestration/SagaOrchestratorInternallyTest.java +++ b/saga/src/test/java/com/iluwatar/saga/orchestration/SagaOrchestratorInternallyTest.java @@ -34,7 +34,7 @@ import org.junit.Test; */ public class SagaOrchestratorInternallyTest { - private List records = new ArrayList<>(); + private final List records = new ArrayList<>(); @Test public void executeTest() { diff --git a/semaphore/src/main/java/com/iluwatar/semaphore/Fruit.java b/semaphore/src/main/java/com/iluwatar/semaphore/Fruit.java index d94764dbe..1f4026b92 100644 --- a/semaphore/src/main/java/com/iluwatar/semaphore/Fruit.java +++ b/semaphore/src/main/java/com/iluwatar/semaphore/Fruit.java @@ -35,7 +35,7 @@ public class Fruit { ORANGE, APPLE, LEMON } - private FruitType type; + private final FruitType type; public Fruit(FruitType type) { this.type = type; diff --git a/semaphore/src/main/java/com/iluwatar/semaphore/FruitBowl.java b/semaphore/src/main/java/com/iluwatar/semaphore/FruitBowl.java index 6b43c8100..5c2901efe 100644 --- a/semaphore/src/main/java/com/iluwatar/semaphore/FruitBowl.java +++ b/semaphore/src/main/java/com/iluwatar/semaphore/FruitBowl.java @@ -31,7 +31,7 @@ import java.util.List; */ public class FruitBowl { - private List fruit = new ArrayList<>(); + private final List fruit = new ArrayList<>(); /** * Returns the amount of fruits left in bowl. diff --git a/semaphore/src/main/java/com/iluwatar/semaphore/FruitShop.java b/semaphore/src/main/java/com/iluwatar/semaphore/FruitShop.java index a360f955c..c74145610 100644 --- a/semaphore/src/main/java/com/iluwatar/semaphore/FruitShop.java +++ b/semaphore/src/main/java/com/iluwatar/semaphore/FruitShop.java @@ -31,7 +31,7 @@ public class FruitShop { /** * The FruitBowl instances stored in the class. */ - private FruitBowl[] bowls = { + private final FruitBowl[] bowls = { new FruitBowl(), new FruitBowl(), new FruitBowl() @@ -40,7 +40,7 @@ public class FruitShop { /** * Access flags for each of the FruitBowl instances. */ - private boolean[] available = { + private final boolean[] available = { true, true, true @@ -49,7 +49,7 @@ public class FruitShop { /** * The Semaphore that controls access to the class resources. */ - private Semaphore semaphore; + private final Semaphore semaphore; /** * FruitShop constructor. diff --git a/servant/src/main/java/com/iluwatar/servant/App.java b/servant/src/main/java/com/iluwatar/servant/App.java index b68cb9aee..9c4591b05 100644 --- a/servant/src/main/java/com/iluwatar/servant/App.java +++ b/servant/src/main/java/com/iluwatar/servant/App.java @@ -39,8 +39,8 @@ public class App { private static final Logger LOGGER = LoggerFactory.getLogger(App.class); - private static Servant jenkins = new Servant("Jenkins"); - private static Servant travis = new Servant("Travis"); + private static final Servant jenkins = new Servant("Jenkins"); + private static final Servant travis = new Servant("Travis"); /** * Program entry point. diff --git a/serverless/src/main/java/com/iluwatar/serverless/baas/api/AbstractDynamoDbHandler.java b/serverless/src/main/java/com/iluwatar/serverless/baas/api/AbstractDynamoDbHandler.java index a13893f70..abe7c388d 100644 --- a/serverless/src/main/java/com/iluwatar/serverless/baas/api/AbstractDynamoDbHandler.java +++ b/serverless/src/main/java/com/iluwatar/serverless/baas/api/AbstractDynamoDbHandler.java @@ -40,7 +40,7 @@ import java.util.Map; public abstract class AbstractDynamoDbHandler { private DynamoDBMapper dynamoDbMapper; - private ObjectMapper objectMapper; + private final ObjectMapper objectMapper; public AbstractDynamoDbHandler() { this.initAmazonDynamoDb(); diff --git a/serverless/src/test/java/com/iluwatar/serverless/baas/api/SavePersonApiHandlerTest.java b/serverless/src/test/java/com/iluwatar/serverless/baas/api/SavePersonApiHandlerTest.java index ef3909adc..a8c729163 100644 --- a/serverless/src/test/java/com/iluwatar/serverless/baas/api/SavePersonApiHandlerTest.java +++ b/serverless/src/test/java/com/iluwatar/serverless/baas/api/SavePersonApiHandlerTest.java @@ -52,7 +52,7 @@ public class SavePersonApiHandlerTest { @Mock private DynamoDBMapper dynamoDbMapper; - private ObjectMapper objectMapper = new ObjectMapper(); + private final ObjectMapper objectMapper = new ObjectMapper(); @Before public void setUp() { diff --git a/service-layer/README.md b/service-layer/README.md index 910eaeaea..5e8e49ea6 100644 --- a/service-layer/README.md +++ b/service-layer/README.md @@ -155,9 +155,9 @@ public interface MagicService { public class MagicServiceImpl implements MagicService { - private WizardDao wizardDao; - private SpellbookDao spellbookDao; - private SpellDao spellDao; + private final WizardDao wizardDao; + private final SpellbookDao spellbookDao; + private final SpellDao spellDao; public MagicServiceImpl(WizardDao wizardDao, SpellbookDao spellbookDao, SpellDao spellDao) { this.wizardDao = wizardDao; diff --git a/service-layer/src/main/java/com/iluwatar/servicelayer/magic/MagicServiceImpl.java b/service-layer/src/main/java/com/iluwatar/servicelayer/magic/MagicServiceImpl.java index 962487bd9..cdcf926d0 100644 --- a/service-layer/src/main/java/com/iluwatar/servicelayer/magic/MagicServiceImpl.java +++ b/service-layer/src/main/java/com/iluwatar/servicelayer/magic/MagicServiceImpl.java @@ -37,9 +37,9 @@ import java.util.List; */ public class MagicServiceImpl implements MagicService { - private WizardDao wizardDao; - private SpellbookDao spellbookDao; - private SpellDao spellDao; + private final WizardDao wizardDao; + private final SpellbookDao spellbookDao; + private final SpellDao spellDao; /** * Constructor. diff --git a/service-locator/src/main/java/com/iluwatar/servicelocator/ServiceLocator.java b/service-locator/src/main/java/com/iluwatar/servicelocator/ServiceLocator.java index 60f0f7c03..4e787d34c 100644 --- a/service-locator/src/main/java/com/iluwatar/servicelocator/ServiceLocator.java +++ b/service-locator/src/main/java/com/iluwatar/servicelocator/ServiceLocator.java @@ -31,7 +31,7 @@ package com.iluwatar.servicelocator; */ public final class ServiceLocator { - private static ServiceCache serviceCache = new ServiceCache(); + private static final ServiceCache serviceCache = new ServiceCache(); private ServiceLocator() { } diff --git a/sharding/src/main/java/com/iluwatar/sharding/LookupShardManager.java b/sharding/src/main/java/com/iluwatar/sharding/LookupShardManager.java index 4948c2a19..ce239c156 100644 --- a/sharding/src/main/java/com/iluwatar/sharding/LookupShardManager.java +++ b/sharding/src/main/java/com/iluwatar/sharding/LookupShardManager.java @@ -39,7 +39,7 @@ public class LookupShardManager extends ShardManager { private static final Logger LOGGER = LoggerFactory.getLogger(LookupShardManager.class); - private Map lookupMap = new HashMap<>(); + private final Map lookupMap = new HashMap<>(); @Override public int storeData(Data data) { diff --git a/sharding/src/main/java/com/iluwatar/sharding/Shard.java b/sharding/src/main/java/com/iluwatar/sharding/Shard.java index eb0814258..56037bc3a 100644 --- a/sharding/src/main/java/com/iluwatar/sharding/Shard.java +++ b/sharding/src/main/java/com/iluwatar/sharding/Shard.java @@ -33,7 +33,7 @@ public class Shard { private final int id; - private Map dataStore; + private final Map dataStore; public Shard(final int id) { this.id = id; diff --git a/singleton/README.md b/singleton/README.md index 83f7fb355..60a103a3b 100644 --- a/singleton/README.md +++ b/singleton/README.md @@ -34,7 +34,7 @@ Joshua Bloch, Effective Java 2nd Edition p.18 ```java public enum EnumIvoryTower { - INSTANCE; + INSTANCE } ``` diff --git a/specification/README.md b/specification/README.md index 6e52bd2e7..6cc0c702f 100644 --- a/specification/README.md +++ b/specification/README.md @@ -146,7 +146,7 @@ public abstract class AbstractSelector implements Predicate { ```java public class ConjunctionSelector extends AbstractSelector { - private List> leafComponents; + private final List> leafComponents; @SafeVarargs ConjunctionSelector(AbstractSelector... selectors) { diff --git a/specification/src/main/java/com/iluwatar/specification/creature/AbstractCreature.java b/specification/src/main/java/com/iluwatar/specification/creature/AbstractCreature.java index 6b359d8ac..214ae4562 100644 --- a/specification/src/main/java/com/iluwatar/specification/creature/AbstractCreature.java +++ b/specification/src/main/java/com/iluwatar/specification/creature/AbstractCreature.java @@ -33,11 +33,11 @@ import com.iluwatar.specification.property.Size; */ public abstract class AbstractCreature implements Creature { - private String name; - private Size size; - private Movement movement; - private Color color; - private Mass mass; + private final String name; + private final Size size; + private final Movement movement; + private final Color color; + private final Mass mass; /** * Constructor. diff --git a/specification/src/main/java/com/iluwatar/specification/property/Color.java b/specification/src/main/java/com/iluwatar/specification/property/Color.java index 6e96b5813..b3128054e 100644 --- a/specification/src/main/java/com/iluwatar/specification/property/Color.java +++ b/specification/src/main/java/com/iluwatar/specification/property/Color.java @@ -30,7 +30,7 @@ public enum Color { DARK("dark"), LIGHT("light"), GREEN("green"), RED("red"); - private String title; + private final String title; Color(String title) { this.title = title; diff --git a/specification/src/main/java/com/iluwatar/specification/property/Mass.java b/specification/src/main/java/com/iluwatar/specification/property/Mass.java index b2d6ddc66..e0e90aa06 100644 --- a/specification/src/main/java/com/iluwatar/specification/property/Mass.java +++ b/specification/src/main/java/com/iluwatar/specification/property/Mass.java @@ -28,8 +28,8 @@ package com.iluwatar.specification.property; */ public class Mass { - private double value; - private String title; + private final double value; + private final String title; public Mass(double value) { this.value = value; diff --git a/specification/src/main/java/com/iluwatar/specification/property/Movement.java b/specification/src/main/java/com/iluwatar/specification/property/Movement.java index f76b0584f..fcdcfae70 100644 --- a/specification/src/main/java/com/iluwatar/specification/property/Movement.java +++ b/specification/src/main/java/com/iluwatar/specification/property/Movement.java @@ -30,7 +30,7 @@ public enum Movement { WALKING("walking"), SWIMMING("swimming"), FLYING("flying"); - private String title; + private final String title; Movement(String title) { this.title = title; diff --git a/specification/src/main/java/com/iluwatar/specification/property/Size.java b/specification/src/main/java/com/iluwatar/specification/property/Size.java index 27bc48024..c5ad5525c 100644 --- a/specification/src/main/java/com/iluwatar/specification/property/Size.java +++ b/specification/src/main/java/com/iluwatar/specification/property/Size.java @@ -30,7 +30,7 @@ public enum Size { SMALL("small"), NORMAL("normal"), LARGE("large"); - private String title; + private final String title; Size(String title) { this.title = title; diff --git a/specification/src/main/java/com/iluwatar/specification/selector/ConjunctionSelector.java b/specification/src/main/java/com/iluwatar/specification/selector/ConjunctionSelector.java index bd29aa260..661c8bceb 100644 --- a/specification/src/main/java/com/iluwatar/specification/selector/ConjunctionSelector.java +++ b/specification/src/main/java/com/iluwatar/specification/selector/ConjunctionSelector.java @@ -30,7 +30,7 @@ import java.util.List; */ public class ConjunctionSelector extends AbstractSelector { - private List> leafComponents; + private final List> leafComponents; @SafeVarargs ConjunctionSelector(AbstractSelector... selectors) { diff --git a/specification/src/main/java/com/iluwatar/specification/selector/DisjunctionSelector.java b/specification/src/main/java/com/iluwatar/specification/selector/DisjunctionSelector.java index 1fb38a43d..32dcf7e73 100644 --- a/specification/src/main/java/com/iluwatar/specification/selector/DisjunctionSelector.java +++ b/specification/src/main/java/com/iluwatar/specification/selector/DisjunctionSelector.java @@ -30,7 +30,7 @@ import java.util.List; */ public class DisjunctionSelector extends AbstractSelector { - private List> leafComponents; + private final List> leafComponents; @SafeVarargs DisjunctionSelector(AbstractSelector... selectors) { diff --git a/specification/src/main/java/com/iluwatar/specification/selector/NegationSelector.java b/specification/src/main/java/com/iluwatar/specification/selector/NegationSelector.java index ad3063000..30302baa2 100644 --- a/specification/src/main/java/com/iluwatar/specification/selector/NegationSelector.java +++ b/specification/src/main/java/com/iluwatar/specification/selector/NegationSelector.java @@ -30,7 +30,7 @@ package com.iluwatar.specification.selector; */ public class NegationSelector extends AbstractSelector { - private AbstractSelector component; + private final AbstractSelector component; NegationSelector(AbstractSelector selector) { this.component = selector; diff --git a/state/README.md b/state/README.md index 7be4d3351..a8dd2b5fc 100644 --- a/state/README.md +++ b/state/README.md @@ -43,7 +43,7 @@ public class PeacefulState implements State { private static final Logger LOGGER = LoggerFactory.getLogger(PeacefulState.class); - private Mammoth mammoth; + private final Mammoth mammoth; public PeacefulState(Mammoth mammoth) { this.mammoth = mammoth; @@ -64,7 +64,7 @@ public class AngryState implements State { private static final Logger LOGGER = LoggerFactory.getLogger(AngryState.class); - private Mammoth mammoth; + private final Mammoth mammoth; public AngryState(Mammoth mammoth) { this.mammoth = mammoth; diff --git a/state/src/main/java/com/iluwatar/state/AngryState.java b/state/src/main/java/com/iluwatar/state/AngryState.java index 8dc296c53..e105262b8 100644 --- a/state/src/main/java/com/iluwatar/state/AngryState.java +++ b/state/src/main/java/com/iluwatar/state/AngryState.java @@ -1,52 +1,52 @@ -/* - * 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.state; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Angry state. - */ -public class AngryState implements State { - - private static final Logger LOGGER = LoggerFactory.getLogger(AngryState.class); - - private Mammoth mammoth; - - public AngryState(Mammoth mammoth) { - this.mammoth = mammoth; - } - - @Override - public void observe() { - LOGGER.info("{} is furious!", mammoth); - } - - @Override - public void onEnterState() { - LOGGER.info("{} gets angry!", mammoth); - } - -} +/* + * 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.state; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Angry state. + */ +public class AngryState implements State { + + private static final Logger LOGGER = LoggerFactory.getLogger(AngryState.class); + + private final Mammoth mammoth; + + public AngryState(Mammoth mammoth) { + this.mammoth = mammoth; + } + + @Override + public void observe() { + LOGGER.info("{} is furious!", mammoth); + } + + @Override + public void onEnterState() { + LOGGER.info("{} gets angry!", mammoth); + } + +} diff --git a/state/src/main/java/com/iluwatar/state/PeacefulState.java b/state/src/main/java/com/iluwatar/state/PeacefulState.java index ed83a0738..adf8be209 100644 --- a/state/src/main/java/com/iluwatar/state/PeacefulState.java +++ b/state/src/main/java/com/iluwatar/state/PeacefulState.java @@ -1,52 +1,52 @@ -/* - * 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.state; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Peaceful state. - */ -public class PeacefulState implements State { - - private static final Logger LOGGER = LoggerFactory.getLogger(PeacefulState.class); - - private Mammoth mammoth; - - public PeacefulState(Mammoth mammoth) { - this.mammoth = mammoth; - } - - @Override - public void observe() { - LOGGER.info("{} is calm and peaceful.", mammoth); - } - - @Override - public void onEnterState() { - LOGGER.info("{} calms down.", mammoth); - } - -} +/* + * 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.state; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Peaceful state. + */ +public class PeacefulState implements State { + + private static final Logger LOGGER = LoggerFactory.getLogger(PeacefulState.class); + + private final Mammoth mammoth; + + public PeacefulState(Mammoth mammoth) { + this.mammoth = mammoth; + } + + @Override + public void observe() { + LOGGER.info("{} is calm and peaceful.", mammoth); + } + + @Override + public void onEnterState() { + LOGGER.info("{} calms down.", mammoth); + } + +} diff --git a/state/src/test/java/com/iluwatar/state/MammothTest.java b/state/src/test/java/com/iluwatar/state/MammothTest.java index 15624c7ab..4cc6e0adb 100644 --- a/state/src/test/java/com/iluwatar/state/MammothTest.java +++ b/state/src/test/java/com/iluwatar/state/MammothTest.java @@ -96,7 +96,7 @@ public class MammothTest { } private class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender() { ((Logger) LoggerFactory.getLogger("root")).addAppender(this); diff --git a/step-builder/src/main/java/com/iluwatar/stepbuilder/CharacterStepBuilder.java b/step-builder/src/main/java/com/iluwatar/stepbuilder/CharacterStepBuilder.java index a0c7f84e6..5be38e471 100644 --- a/step-builder/src/main/java/com/iluwatar/stepbuilder/CharacterStepBuilder.java +++ b/step-builder/src/main/java/com/iluwatar/stepbuilder/CharacterStepBuilder.java @@ -105,7 +105,7 @@ public final class CharacterStepBuilder { private String wizardClass; private String weapon; private String spell; - private List abilities = new ArrayList<>(); + private final List abilities = new ArrayList<>(); @Override public ClassStep name(String name) { diff --git a/strategy/src/test/java/com/iluwatar/strategy/DragonSlayingStrategyTest.java b/strategy/src/test/java/com/iluwatar/strategy/DragonSlayingStrategyTest.java index cca82cefc..0b5a2d615 100644 --- a/strategy/src/test/java/com/iluwatar/strategy/DragonSlayingStrategyTest.java +++ b/strategy/src/test/java/com/iluwatar/strategy/DragonSlayingStrategyTest.java @@ -91,7 +91,7 @@ public class DragonSlayingStrategyTest { } private class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender() { ((Logger) LoggerFactory.getLogger("root")).addAppender(this); diff --git a/template-method/src/test/java/com/iluwatar/templatemethod/StealingMethodTest.java b/template-method/src/test/java/com/iluwatar/templatemethod/StealingMethodTest.java index ba6030da4..95326eeec 100644 --- a/template-method/src/test/java/com/iluwatar/templatemethod/StealingMethodTest.java +++ b/template-method/src/test/java/com/iluwatar/templatemethod/StealingMethodTest.java @@ -146,7 +146,7 @@ public abstract class StealingMethodTest { } private class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender() { ((Logger) LoggerFactory.getLogger("root")).addAppender(this); diff --git a/throttling/README.md b/throttling/README.md index 48e1b1c78..257bce54a 100644 --- a/throttling/README.md +++ b/throttling/README.md @@ -32,8 +32,8 @@ Tenant class presents the clients of the API. CallsCount tracks the number of AP ```java public class Tenant { - private String name; - private int allowedCallsPerSecond; + private final String name; + private final int allowedCallsPerSecond; public Tenant(String name, int allowedCallsPerSecond, CallsCount callsCount) { if (allowedCallsPerSecond < 0) { @@ -56,7 +56,7 @@ public class Tenant { public final class CallsCount { private static final Logger LOGGER = LoggerFactory.getLogger(CallsCount.class); - private Map tenantCallsCount = new ConcurrentHashMap<>(); + private final Map tenantCallsCount = new ConcurrentHashMap<>(); public void addTenant(String tenantName) { tenantCallsCount.putIfAbsent(tenantName, new AtomicLong(0)); diff --git a/throttling/src/main/java/com/iluwatar/throttling/CallsCount.java b/throttling/src/main/java/com/iluwatar/throttling/CallsCount.java index 8f8036286..abfd4d351 100644 --- a/throttling/src/main/java/com/iluwatar/throttling/CallsCount.java +++ b/throttling/src/main/java/com/iluwatar/throttling/CallsCount.java @@ -38,7 +38,7 @@ import org.slf4j.LoggerFactory; public final class CallsCount { private static final Logger LOGGER = LoggerFactory.getLogger(CallsCount.class); - private Map tenantCallsCount = new ConcurrentHashMap<>(); + private final Map tenantCallsCount = new ConcurrentHashMap<>(); /** * Add a new tenant to the map. diff --git a/throttling/src/main/java/com/iluwatar/throttling/Tenant.java b/throttling/src/main/java/com/iluwatar/throttling/Tenant.java index d94344428..5fe2c72db 100644 --- a/throttling/src/main/java/com/iluwatar/throttling/Tenant.java +++ b/throttling/src/main/java/com/iluwatar/throttling/Tenant.java @@ -30,8 +30,8 @@ import java.security.InvalidParameterException; */ public class Tenant { - private String name; - private int allowedCallsPerSecond; + private final String name; + private final int allowedCallsPerSecond; /** * Constructor. diff --git a/throttling/src/test/java/com/iluwatar/throttling/B2BServiceTest.java b/throttling/src/test/java/com/iluwatar/throttling/B2BServiceTest.java index 6a328c3f0..786325237 100644 --- a/throttling/src/test/java/com/iluwatar/throttling/B2BServiceTest.java +++ b/throttling/src/test/java/com/iluwatar/throttling/B2BServiceTest.java @@ -34,7 +34,7 @@ import org.junit.jupiter.api.Test; */ public class B2BServiceTest { - private CallsCount callsCount = new CallsCount(); + private final CallsCount callsCount = new CallsCount(); @Test public void dummyCustomerApiTest() { diff --git a/tls/src/main/java/com/iluwatar/tls/DateFormatCallable.java b/tls/src/main/java/com/iluwatar/tls/DateFormatCallable.java index c4e885896..4e5c14e0b 100644 --- a/tls/src/main/java/com/iluwatar/tls/DateFormatCallable.java +++ b/tls/src/main/java/com/iluwatar/tls/DateFormatCallable.java @@ -1,93 +1,93 @@ -/* - * 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.tls; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.concurrent.Callable; -import java.util.stream.IntStream; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * DateFormatCallable converts string dates to a date format using SimpleDateFormat. The date format - * and the date value will be passed to the Callable by the constructor. The constructor creates a - * instance of SimpleDateFormat and stores it in a ThreadLocal class variable. For the complete - * description of the example see {@link App}. - * - *

You can comment out the code marked with //TLTL and comment in the code marked //NTLNTL. Then - * you can see what will happen if you do not use the ThreadLocal. For details see the description - * of {@link App} - * - * @author Thomas Bauer, 2017 - */ -public class DateFormatCallable implements Callable { - - private static final Logger LOGGER = LoggerFactory.getLogger(DateFormatCallable.class); - // class variables (members) - private ThreadLocal df; //TLTL - // private DateFormat df; //NTLNTL - - private String dateValue; // for dateValue Thread Local not needed - - - /** - * The date format and the date value are passed to the constructor. - * - * @param inDateFormat string date format string, e.g. "dd/MM/yyyy" - * @param inDateValue string date value, e.g. "21/06/2016" - */ - public DateFormatCallable(String inDateFormat, String inDateValue) { - final var idf = inDateFormat; //TLTL - this.df = ThreadLocal.withInitial(() -> { //TLTL - return new SimpleDateFormat(idf); //TLTL - }); //TLTL - // this.df = new SimpleDateFormat(inDateFormat); //NTLNTL - this.dateValue = inDateValue; - } - - @Override - public Result call() { - LOGGER.info(Thread.currentThread() + " started executing..."); - var result = new Result(); - - // Convert date value to date 5 times - IntStream.rangeClosed(1, 5).forEach(i -> { - try { - // this is the statement where it is important to have the - // instance of SimpleDateFormat locally - // Create the date value and store it in dateList - result.getDateList().add(this.df.get().parse(this.dateValue)); //TLTL - // result.getDateList().add(this.df.parse(this.dateValue)); //NTLNTL - } catch (Exception e) { - // write the Exception to a list and continue work - result.getExceptionList().add(e.getClass() + ": " + e.getMessage()); - } - }); - - LOGGER.info(Thread.currentThread() + " finished processing part of the thread"); - - return result; - } -} +/* + * 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.tls; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.concurrent.Callable; +import java.util.stream.IntStream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * DateFormatCallable converts string dates to a date format using SimpleDateFormat. The date format + * and the date value will be passed to the Callable by the constructor. The constructor creates a + * instance of SimpleDateFormat and stores it in a ThreadLocal class variable. For the complete + * description of the example see {@link App}. + * + *

You can comment out the code marked with //TLTL and comment in the code marked //NTLNTL. Then + * you can see what will happen if you do not use the ThreadLocal. For details see the description + * of {@link App} + * + * @author Thomas Bauer, 2017 + */ +public class DateFormatCallable implements Callable { + + private static final Logger LOGGER = LoggerFactory.getLogger(DateFormatCallable.class); + // class variables (members) + private final ThreadLocal df; //TLTL + // private DateFormat df; //NTLNTL + + private final String dateValue; // for dateValue Thread Local not needed + + + /** + * The date format and the date value are passed to the constructor. + * + * @param inDateFormat string date format string, e.g. "dd/MM/yyyy" + * @param inDateValue string date value, e.g. "21/06/2016" + */ + public DateFormatCallable(String inDateFormat, String inDateValue) { + final var idf = inDateFormat; //TLTL + this.df = ThreadLocal.withInitial(() -> { //TLTL + return new SimpleDateFormat(idf); //TLTL + }); //TLTL + // this.df = new SimpleDateFormat(inDateFormat); //NTLNTL + this.dateValue = inDateValue; + } + + @Override + public Result call() { + LOGGER.info(Thread.currentThread() + " started executing..."); + var result = new Result(); + + // Convert date value to date 5 times + IntStream.rangeClosed(1, 5).forEach(i -> { + try { + // this is the statement where it is important to have the + // instance of SimpleDateFormat locally + // Create the date value and store it in dateList + result.getDateList().add(this.df.get().parse(this.dateValue)); //TLTL + // result.getDateList().add(this.df.parse(this.dateValue)); //NTLNTL + } catch (Exception e) { + // write the Exception to a list and continue work + result.getExceptionList().add(e.getClass() + ": " + e.getMessage()); + } + }); + + LOGGER.info(Thread.currentThread() + " finished processing part of the thread"); + + return result; + } +} diff --git a/tls/src/main/java/com/iluwatar/tls/Result.java b/tls/src/main/java/com/iluwatar/tls/Result.java index c98a07b91..38dc197cf 100644 --- a/tls/src/main/java/com/iluwatar/tls/Result.java +++ b/tls/src/main/java/com/iluwatar/tls/Result.java @@ -1,65 +1,65 @@ -/* - * 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. - */ - -/* - * Fiducia IT AG, All rights reserved. Use is subject to license terms. - */ - -package com.iluwatar.tls; - -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - -/** - * Result object that will be returned by the Callable {@link DateFormatCallable} used in {@link - * App}. - * - * @author Thomas Bauer, 2017 - */ -public class Result { - // A list to collect the date values created in one thread - private List dateList = new ArrayList<>(); - - // A list to collect Exceptions thrown in one threads (should be none in - // this example) - private List exceptionList = new ArrayList<>(); - - /** - * Get list of date values collected within a thread execution. - * - * @return List of date values collected within an thread execution - */ - public List getDateList() { - return dateList; - } - - /** - * Get list of exceptions thrown within a thread execution. - * - * @return List of exceptions thrown within an thread execution - */ - public List getExceptionList() { - return exceptionList; - } -} +/* + * 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. + */ + +/* + * Fiducia IT AG, All rights reserved. Use is subject to license terms. + */ + +package com.iluwatar.tls; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * Result object that will be returned by the Callable {@link DateFormatCallable} used in {@link + * App}. + * + * @author Thomas Bauer, 2017 + */ +public class Result { + // A list to collect the date values created in one thread + private final List dateList = new ArrayList<>(); + + // A list to collect Exceptions thrown in one threads (should be none in + // this example) + private final List exceptionList = new ArrayList<>(); + + /** + * Get list of date values collected within a thread execution. + * + * @return List of date values collected within an thread execution + */ + public List getDateList() { + return dateList; + } + + /** + * Get list of exceptions thrown within a thread execution. + * + * @return List of exceptions thrown within an thread execution + */ + public List getExceptionList() { + return exceptionList; + } +} diff --git a/tls/src/test/java/com/iluwatar/tls/DateFormatCallableTest.java b/tls/src/test/java/com/iluwatar/tls/DateFormatCallableTest.java index 48e5854a3..5338829d0 100644 --- a/tls/src/test/java/com/iluwatar/tls/DateFormatCallableTest.java +++ b/tls/src/test/java/com/iluwatar/tls/DateFormatCallableTest.java @@ -66,18 +66,18 @@ public class DateFormatCallableTest { /** * Expected number of date values in the date value list created by the run of DateFormatRunnalbe */ - private int expectedCounterDateValues = 5; + private final int expectedCounterDateValues = 5; /** * Expected number of exceptions in the exception list created by the run of DateFormatRunnalbe. */ - private int expectedCounterExceptions = 0; + private final int expectedCounterExceptions = 0; /** * Expected content of the list containing the date values created by the run of * DateFormatRunnalbe */ - private List expectedDateValues = + private final List expectedDateValues = List.of("15.11.2015", "15.11.2015", "15.11.2015", "15.11.2015", "15.11.2015"); /** diff --git a/tls/src/test/java/com/iluwatar/tls/DateFormatCallableTestIncorrectDateFormat.java b/tls/src/test/java/com/iluwatar/tls/DateFormatCallableTestIncorrectDateFormat.java index 8b02faf0b..7b3d6b4ad 100644 --- a/tls/src/test/java/com/iluwatar/tls/DateFormatCallableTestIncorrectDateFormat.java +++ b/tls/src/test/java/com/iluwatar/tls/DateFormatCallableTestIncorrectDateFormat.java @@ -54,18 +54,18 @@ public class DateFormatCallableTestIncorrectDateFormat { /** * Expected number of date values in the date value list created by the run of DateFormatRunnalbe */ - private int expectedCounterDateValues = 0; + private final int expectedCounterDateValues = 0; /** * Expected number of exceptions in the exception list created by the run of DateFormatRunnalbe. */ - private int expectedCounterExceptions = 5; + private final int expectedCounterExceptions = 5; /** * Expected content of the list containing the exceptions created by the run of * DateFormatRunnalbe */ - private List expectedExceptions = List.of( + private final List expectedExceptions = List.of( "class java.text.ParseException: Unparseable date: \"15.12.2015\"", "class java.text.ParseException: Unparseable date: \"15.12.2015\"", "class java.text.ParseException: Unparseable date: \"15.12.2015\"", diff --git a/tls/src/test/java/com/iluwatar/tls/DateFormatCallableTestMultiThread.java b/tls/src/test/java/com/iluwatar/tls/DateFormatCallableTestMultiThread.java index c0e8e1844..b3328d4c5 100644 --- a/tls/src/test/java/com/iluwatar/tls/DateFormatCallableTestMultiThread.java +++ b/tls/src/test/java/com/iluwatar/tls/DateFormatCallableTestMultiThread.java @@ -55,7 +55,7 @@ public class DateFormatCallableTestMultiThread { * Result object given back by DateFormatCallable, one for each thread -- Array with converted * date values -- Array with thrown exceptions */ - private static Result[] result = new Result[4]; + private static final Result[] result = new Result[4]; /** * The date values created by the run of of DateFormatRunnalbe. List will be filled in the setup() @@ -66,22 +66,22 @@ public class DateFormatCallableTestMultiThread { /* nothing needed here */ } - private static List[] createdDateValues = new StringArrayList[4]; + private static final List[] createdDateValues = new StringArrayList[4]; /** * Expected number of date values in the date value list created by each thread */ - private int expectedCounterDateValues = 5; + private final int expectedCounterDateValues = 5; /** * Expected number of exceptions in the exception list created by each thread */ - private int expectedCounterExceptions = 0; + private final int expectedCounterExceptions = 0; /** * Expected content of the list containing the date values created by each thread */ - private List expectedDateValues = + private final List expectedDateValues = List.of("15.11.2015", "15.11.2015", "15.11.2015", "15.11.2015", "15.11.2015"); /** diff --git a/tolerant-reader/README.md b/tolerant-reader/README.md index a62e5f4cd..922de90de 100644 --- a/tolerant-reader/README.md +++ b/tolerant-reader/README.md @@ -35,10 +35,10 @@ public class RainbowFish implements Serializable { private static final long serialVersionUID = 1L; - private String name; - private int age; - private int lengthMeters; - private int weightTons; + private final String name; + private final int age; + private final int lengthMeters; + private final int weightTons; /** * Constructor. diff --git a/tolerant-reader/src/main/java/com/iluwatar/tolerantreader/RainbowFish.java b/tolerant-reader/src/main/java/com/iluwatar/tolerantreader/RainbowFish.java index 775fc98f7..7529435fe 100644 --- a/tolerant-reader/src/main/java/com/iluwatar/tolerantreader/RainbowFish.java +++ b/tolerant-reader/src/main/java/com/iluwatar/tolerantreader/RainbowFish.java @@ -32,10 +32,10 @@ public class RainbowFish implements Serializable { private static final long serialVersionUID = 1L; - private String name; - private int age; - private int lengthMeters; - private int weightTons; + private final String name; + private final int age; + private final int lengthMeters; + private final int weightTons; /** * Constructor. diff --git a/twin/src/test/java/com/iluwatar/twin/BallItemTest.java b/twin/src/test/java/com/iluwatar/twin/BallItemTest.java index 568c1d7b0..18aba2bed 100644 --- a/twin/src/test/java/com/iluwatar/twin/BallItemTest.java +++ b/twin/src/test/java/com/iluwatar/twin/BallItemTest.java @@ -108,7 +108,7 @@ public class BallItemTest { * Logging Appender Implementation */ public class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender() { ((Logger) LoggerFactory.getLogger("root")).addAppender(this); diff --git a/typeobjectpattern/src/main/java/com/iluwatar/typeobject/App.java b/typeobjectpattern/src/main/java/com/iluwatar/typeobject/App.java index e70acbf9e..80054a5fb 100644 --- a/typeobjectpattern/src/main/java/com/iluwatar/typeobject/App.java +++ b/typeobjectpattern/src/main/java/com/iluwatar/typeobject/App.java @@ -56,7 +56,7 @@ public class App { * * @param args command line args */ - public static void main(String[] args) throws FileNotFoundException, IOException, ParseException { + public static void main(String[] args) throws IOException, ParseException { var givenTime = 50; //50ms var toWin = 500; //points var pointsWon = 0; diff --git a/typeobjectpattern/src/main/java/com/iluwatar/typeobject/Candy.java b/typeobjectpattern/src/main/java/com/iluwatar/typeobject/Candy.java index ec41dc6cd..88bfe0ada 100644 --- a/typeobjectpattern/src/main/java/com/iluwatar/typeobject/Candy.java +++ b/typeobjectpattern/src/main/java/com/iluwatar/typeobject/Candy.java @@ -38,7 +38,7 @@ public class Candy { Candy parent; String parentName; private int points; - private Type type; + private final Type type; Candy(String name, String parentName, Type type, int points) { this.name = name; diff --git a/typeobjectpattern/src/main/java/com/iluwatar/typeobject/CellPool.java b/typeobjectpattern/src/main/java/com/iluwatar/typeobject/CellPool.java index 553458a6d..f33640f2a 100644 --- a/typeobjectpattern/src/main/java/com/iluwatar/typeobject/CellPool.java +++ b/typeobjectpattern/src/main/java/com/iluwatar/typeobject/CellPool.java @@ -77,7 +77,7 @@ public class CellPool { pointer++; } - Candy[] assignRandomCandytypes() throws FileNotFoundException, IOException, ParseException { + Candy[] assignRandomCandytypes() throws IOException, ParseException { var jp = new JsonParser(); jp.parse(); var randomCode = new Candy[jp.candies.size() - 2]; //exclude generic types 'fruit' and 'candy' diff --git a/unit-of-work/README.md b/unit-of-work/README.md index 1f6c7c5b2..590f718d3 100644 --- a/unit-of-work/README.md +++ b/unit-of-work/README.md @@ -79,8 +79,8 @@ public interface IUnitOfWork { public class StudentRepository implements IUnitOfWork { private static final Logger LOGGER = LoggerFactory.getLogger(StudentRepository.class); - private Map> context; - private StudentDatabase studentDatabase; + private final Map> context; + private final StudentDatabase studentDatabase; public StudentRepository(Map> context, StudentDatabase studentDatabase) { this.context = context; diff --git a/unit-of-work/src/main/java/com/iluwatar/unitofwork/StudentRepository.java b/unit-of-work/src/main/java/com/iluwatar/unitofwork/StudentRepository.java index ee5fc613d..73c1068b3 100644 --- a/unit-of-work/src/main/java/com/iluwatar/unitofwork/StudentRepository.java +++ b/unit-of-work/src/main/java/com/iluwatar/unitofwork/StudentRepository.java @@ -35,8 +35,8 @@ import org.slf4j.LoggerFactory; public class StudentRepository implements IUnitOfWork { private static final Logger LOGGER = LoggerFactory.getLogger(StudentRepository.class); - private Map> context; - private StudentDatabase studentDatabase; + private final Map> context; + private final StudentDatabase studentDatabase; /** * Constructor. diff --git a/update-method/src/main/java/com/iluwatar/updatemethod/World.java b/update-method/src/main/java/com/iluwatar/updatemethod/World.java index 8cabead56..5b99050c8 100644 --- a/update-method/src/main/java/com/iluwatar/updatemethod/World.java +++ b/update-method/src/main/java/com/iluwatar/updatemethod/World.java @@ -87,7 +87,8 @@ public class World { * Render the next frame. Here we do nothing since it is not related to the * pattern. */ - private void render() {} + private void render() { + } /** * Run game loop. diff --git a/value-object/src/main/java/com/iluwatar/value/object/HeroStat.java b/value-object/src/main/java/com/iluwatar/value/object/HeroStat.java index 740be76b1..453718875 100644 --- a/value-object/src/main/java/com/iluwatar/value/object/HeroStat.java +++ b/value-object/src/main/java/com/iluwatar/value/object/HeroStat.java @@ -103,10 +103,7 @@ public class HeroStat { if (luck != other.luck) { return false; } - if (strength != other.strength) { - return false; - } - return true; + return strength == other.strength; } // The clone() method should not be public. Just don't override it. diff --git a/visitor/README.md b/visitor/README.md index 3b4be5082..c97e97120 100644 --- a/visitor/README.md +++ b/visitor/README.md @@ -32,7 +32,7 @@ Given the army unit example from above, we first have the Unit and UnitVisitor b ```java public abstract class Unit { - private Unit[] children; + private final Unit[] children; public Unit(Unit... children) { this.children = children; diff --git a/visitor/src/main/java/com/iluwatar/visitor/Unit.java b/visitor/src/main/java/com/iluwatar/visitor/Unit.java index c890884b3..3597c4d60 100644 --- a/visitor/src/main/java/com/iluwatar/visitor/Unit.java +++ b/visitor/src/main/java/com/iluwatar/visitor/Unit.java @@ -1,45 +1,45 @@ -/* - * 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.visitor; - -import java.util.Arrays; - -/** - * Interface for the nodes in hierarchy. - */ -public abstract class Unit { - - private Unit[] children; - - public Unit(Unit... children) { - this.children = children; - } - - /** - * Accept visitor. - */ - public void accept(UnitVisitor visitor) { - Arrays.stream(children).forEach(child -> child.accept(visitor)); - } -} +/* + * 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.visitor; + +import java.util.Arrays; + +/** + * Interface for the nodes in hierarchy. + */ +public abstract class Unit { + + private final Unit[] children; + + public Unit(Unit... children) { + this.children = children; + } + + /** + * Accept visitor. + */ + public void accept(UnitVisitor visitor) { + Arrays.stream(children).forEach(child -> child.accept(visitor)); + } +} diff --git a/visitor/src/test/java/com/iluwatar/visitor/VisitorTest.java b/visitor/src/test/java/com/iluwatar/visitor/VisitorTest.java index 146ee22f8..fd2f1cb76 100644 --- a/visitor/src/test/java/com/iluwatar/visitor/VisitorTest.java +++ b/visitor/src/test/java/com/iluwatar/visitor/VisitorTest.java @@ -123,7 +123,7 @@ public abstract class VisitorTest { } private class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender() { ((Logger) LoggerFactory.getLogger("root")).addAppender(this); From 8364b289b4c6bcfbee5df4f694f7f8bc3f59f58d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Thu, 30 Jul 2020 21:38:40 +0300 Subject: [PATCH 190/211] #590 explanation for Abstract Document --- abstract-document/README.md | 175 +++++++++++++++++- .../abstractdocument/domain/HasParts.java | 1 - .../abstractdocument/domain/HasPrice.java | 1 - .../abstractdocument/domain/HasType.java | 1 - 4 files changed, 168 insertions(+), 10 deletions(-) diff --git a/abstract-document/README.md b/abstract-document/README.md index 15f5c6c85..d985cff2b 100644 --- a/abstract-document/README.md +++ b/abstract-document/README.md @@ -9,21 +9,182 @@ tags: --- ## Intent -Achieve flexibility of untyped languages and keep the type-safety + +Use dynamic properties and achieve flexibility of untyped languages while keeping type-safety. + +## Explanation + +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. + +Real world example + +> Consider a car that consists of multiple parts. However we don't know if the specific car really has all the parts, or just some of them. Our cars are dynamic and extremely flexible. + +In plain words + +> Abstract Document pattern allows attaching properties to objects without them knowing about it. + +Wikipedia says + +> An object-oriented structural design pattern for organizing objects in loosely typed key-value stores and exposing +the data using typed views. The purpose of the pattern is to achieve a high degree of flexibility between components +in a strongly typed language where new properties can be added to the object-tree on the fly, without losing the +support of type-safety. The pattern makes use of traits to separate different properties of a class into different +interfaces. + +**Programmatic Example** + +Let's first define the base classes `Document` and `AbstractDocument`. They basically make the object hold a property +map and any amount of child objects. + +```java +public interface Document { + + Void put(String key, Object value); + + Object get(String key); + + Stream children(String key, Function, T> constructor); +} + +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) { + return Stream.ofNullable(get(key)) + .filter(Objects::nonNull) + .map(el -> (List>) el) + .findAny() + .stream() + .flatMap(Collection::stream) + .map(constructor); + } + ... +} +``` +Next we define an enum `Property` and a set of interfaces for type, price, model and parts. This allows us to create +static looking interface to our `Car` class. + +```java +public enum Property { + + PARTS, TYPE, PRICE, MODEL +} + +public interface HasType extends Document { + + default Optional getType() { + return Optional.ofNullable((String) get(Property.TYPE.toString())); + } +} + +public interface HasPrice extends Document { + + default Optional getPrice() { + return Optional.ofNullable((Number) get(Property.PRICE.toString())); + } +} +public interface HasModel extends Document { + + default Optional getModel() { + return Optional.ofNullable((String) get(Property.MODEL.toString())); + } +} + +public interface HasParts extends Document { + + default Stream getParts() { + return children(Property.PARTS.toString(), Part::new); + } +} +``` + +Now we are ready to introduce the `Car`. + +```java +public class Car extends AbstractDocument implements HasModel, HasPrice, HasParts { + + public Car(Map properties) { + super(properties); + } +} +``` + +And finally here's how we construct and use the `Car` in a full example. + +```java + LOGGER.info("Constructing parts and car"); + + var wheelProperties = Map.of( + Property.TYPE.toString(), "wheel", + Property.MODEL.toString(), "15C", + Property.PRICE.toString(), 100L); + + var doorProperties = Map.of( + Property.TYPE.toString(), "door", + Property.MODEL.toString(), "Lambo", + Property.PRICE.toString(), 300L); + + var carProperties = Map.of( + Property.MODEL.toString(), "300SL", + Property.PRICE.toString(), 10000L, + Property.PARTS.toString(), List.of(wheelProperties, doorProperties)); + + var car = new Car(carProperties); + + LOGGER.info("Here is our car:"); + LOGGER.info("-> model: {}", car.getModel().orElseThrow()); + LOGGER.info("-> price: {}", car.getPrice().orElseThrow()); + LOGGER.info("-> parts: "); + car.getParts().forEach(p -> LOGGER.info("\t{}/{}/{}", + p.getType().orElse(null), + p.getModel().orElse(null), + p.getPrice().orElse(null)) + ); + + // Constructing parts and car + // Here is our car: + // model: 300SL + // price: 10000 + // parts: + // wheel/15C/100 + // door/Lambo/300 +``` ## Class diagram + ![alt text](./etc/abstract-document.png "Abstract Document Traits and Domain") - ## 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 - +* 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) +* [Pattern-Oriented Software Architecture Volume 4: A Pattern Language for Distributed Computing (v. 4)](https://www.amazon.com/gp/product/0470059028/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=0470059028&linkId=e3aacaea7017258acf184f9f3283b492) 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 index 8ecfa85fb..54f308ccf 100644 --- a/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/HasParts.java +++ b/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/HasParts.java @@ -32,7 +32,6 @@ import java.util.stream.Stream; */ public interface HasParts extends Document { - default Stream getParts() { return children(Property.PARTS.toString(), 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 index 9a95f2a51..a50c725c3 100644 --- a/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/HasPrice.java +++ b/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/HasPrice.java @@ -32,7 +32,6 @@ import java.util.Optional; */ public interface HasPrice extends Document { - default Optional getPrice() { return Optional.ofNullable((Number) get(Property.PRICE.toString())); } 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 index b1d5bd6b5..2722564d5 100644 --- a/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/HasType.java +++ b/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/HasType.java @@ -32,7 +32,6 @@ import java.util.Optional; */ public interface HasType extends Document { - default Optional getType() { return Optional.ofNullable((String) get(Property.TYPE.toString())); } From 55bb1f11e0536a42196b1e9dde855b6eeabea237 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Thu, 30 Jul 2020 21:57:07 +0300 Subject: [PATCH 191/211] #590 fix typo --- abstract-document/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/abstract-document/README.md b/abstract-document/README.md index d985cff2b..cbb35cee8 100644 --- a/abstract-document/README.md +++ b/abstract-document/README.md @@ -184,7 +184,7 @@ Use the Abstract Document Pattern when * 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) * [Pattern-Oriented Software Architecture Volume 4: A Pattern Language for Distributed Computing (v. 4)](https://www.amazon.com/gp/product/0470059028/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=0470059028&linkId=e3aacaea7017258acf184f9f3283b492) From 29f799c815379808624d6662b9172b2e2f3b3395 Mon Sep 17 00:00:00 2001 From: Matt Dolan Date: Fri, 31 Jul 2020 22:50:48 -0400 Subject: [PATCH 192/211] Corrected assertEquals order for expected, actual. --- .../java/com/iluwatar/arrangeactassert/CashAAATest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arrange-act-assert/src/test/java/com/iluwatar/arrangeactassert/CashAAATest.java b/arrange-act-assert/src/test/java/com/iluwatar/arrangeactassert/CashAAATest.java index d7841843d..115dd3a11 100644 --- a/arrange-act-assert/src/test/java/com/iluwatar/arrangeactassert/CashAAATest.java +++ b/arrange-act-assert/src/test/java/com/iluwatar/arrangeactassert/CashAAATest.java @@ -60,7 +60,7 @@ public class CashAAATest { //Act cash.plus(4); //Assert - assertEquals(cash.count(), 7); + assertEquals(7, cash.count()); } @Test @@ -71,7 +71,7 @@ public class CashAAATest { var result = cash.minus(5); //Assert assertTrue(result); - assertEquals(cash.count(), 3); + assertEquals(3, cash.count()); } @Test @@ -82,7 +82,7 @@ public class CashAAATest { var result = cash.minus(6); //Assert assertFalse(result); - assertEquals(cash.count(), 1); + assertEquals(1, cash.count()); } @Test @@ -94,6 +94,6 @@ public class CashAAATest { var result = cash.minus(3); //Assert assertTrue(result); - assertEquals(cash.count(), 8); + assertEquals(8, cash.count()); } } From fb6507ceda06675fd910a736bcc35edd752321cb Mon Sep 17 00:00:00 2001 From: Matt Dolan Date: Fri, 31 Jul 2020 22:52:23 -0400 Subject: [PATCH 193/211] Corrected assertEquals order for expected, actual. --- .../com/iluwatar/arrangeactassert/CashAntiAAATest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arrange-act-assert/src/test/java/com/iluwatar/arrangeactassert/CashAntiAAATest.java b/arrange-act-assert/src/test/java/com/iluwatar/arrangeactassert/CashAntiAAATest.java index 3f8c33d5e..564b923e7 100644 --- a/arrange-act-assert/src/test/java/com/iluwatar/arrangeactassert/CashAntiAAATest.java +++ b/arrange-act-assert/src/test/java/com/iluwatar/arrangeactassert/CashAntiAAATest.java @@ -44,16 +44,16 @@ public class CashAntiAAATest { var cash = new Cash(3); //test plus cash.plus(4); - assertEquals(cash.count(), 7); + assertEquals(7, cash.count()); //test minus cash = new Cash(8); assertTrue(cash.minus(5)); - assertEquals(cash.count(), 3); + assertEquals(3, cash.count()); assertFalse(cash.minus(6)); - assertEquals(cash.count(), 3); + assertEquals(3, cash.count()); //test update cash.plus(5); assertTrue(cash.minus(5)); - assertEquals(cash.count(), 3); + assertEquals(3, cash.count()); } } From 41020982de25493497b1976c19929e4e49b200e0 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Sat, 1 Aug 2020 07:41:47 +0000 Subject: [PATCH 194/211] docs: update README.md [skip ci] --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d3c815cb3..401a92103 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-114-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-115-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -239,6 +239,7 @@ This project is licensed under the terms of the MIT license.
Lars Kappert

🖋
Mike Liu

🌍 +
Matt Dolan

💻 From 7908d38604403eb3e6459d8e8a15b984f32ceab5 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Sat, 1 Aug 2020 07:41:48 +0000 Subject: [PATCH 195/211] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 9a536d34d..50f6363e0 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1038,6 +1038,15 @@ "contributions": [ "translation" ] + }, + { + "login": "charlesfinley", + "name": "Matt Dolan", + "avatar_url": "https://avatars1.githubusercontent.com/u/6307904?v=4", + "profile": "https://github.com/charlesfinley", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 4, From 15eb49e5743a80d588f8b562f2a23fd7151d4f47 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Sat, 1 Aug 2020 08:07:20 +0000 Subject: [PATCH 196/211] docs: update README.md [skip ci] --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 401a92103..13a32d769 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-115-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-116-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -240,6 +240,7 @@ This project is licensed under the terms of the MIT license.
Lars Kappert

🖋
Mike Liu

🌍
Matt Dolan

💻 +
Manan

👀 From 0a2c87d49adbde9b96866a93f1886ff5764ce753 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Sat, 1 Aug 2020 08:07:21 +0000 Subject: [PATCH 197/211] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 50f6363e0..8045f7326 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1047,6 +1047,15 @@ "contributions": [ "code" ] + }, + { + "login": "MananS77", + "name": "Manan", + "avatar_url": "https://avatars3.githubusercontent.com/u/21033516?v=4", + "profile": "https://github.com/MananS77", + "contributions": [ + "review" + ] } ], "contributorsPerLine": 4, From e4473e5c882f5496eb89959aa453e1b9aca2510f Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Sat, 1 Aug 2020 08:45:38 +0000 Subject: [PATCH 198/211] docs: update README.md [skip ci] --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 13a32d769..feb64a1b5 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-116-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-117-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -242,6 +242,9 @@ This project is licensed under the terms of the MIT license.
Matt Dolan

💻
Manan

👀 + +
Nishant Arora

💻 + From d41077f355a4f52c911220e5f001af377db851dd Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Sat, 1 Aug 2020 08:45:39 +0000 Subject: [PATCH 199/211] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 8045f7326..58d3e4c5d 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1056,6 +1056,15 @@ "contributions": [ "review" ] + }, + { + "login": "nishant", + "name": "Nishant Arora", + "avatar_url": "https://avatars2.githubusercontent.com/u/15331971?v=4", + "profile": "https://github.com/nishant", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 4, From 27c40826de7fa6c059d51775f026e59b24333410 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Sat, 1 Aug 2020 09:48:23 +0000 Subject: [PATCH 200/211] docs: update README.md [skip ci] --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index feb64a1b5..21939391e 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-117-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-118-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -244,6 +244,7 @@ This project is licensed under the terms of the MIT license.
Nishant Arora

💻 +
Peeyush

💻 From 38791a6a661f080be6cc1b3e48f742de993c7599 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Sat, 1 Aug 2020 09:48:24 +0000 Subject: [PATCH 201/211] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 58d3e4c5d..80c2288b6 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1065,6 +1065,15 @@ "contributions": [ "code" ] + }, + { + "login": "raja-peeyush-kumar-singh", + "name": "Peeyush", + "avatar_url": "https://avatars0.githubusercontent.com/u/5496024?v=4", + "profile": "https://github.com/raja-peeyush-kumar-singh", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 4, From 7ac8eba43467c9fc85a2b5a61516fccef20a8403 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sat, 1 Aug 2020 15:18:32 +0300 Subject: [PATCH 202/211] #590 explanation for Acyclic Visitor --- acyclic-visitor/README.md | 126 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 122 insertions(+), 4 deletions(-) diff --git a/acyclic-visitor/README.md b/acyclic-visitor/README.md index f293e4393..19e886505 100644 --- a/acyclic-visitor/README.md +++ b/acyclic-visitor/README.md @@ -9,12 +9,126 @@ tags: --- ## Intent -Allow new functions to be added to existing class hierarchies without affecting those hierarchies, and without creating the troublesome dependency cycles that are inherent to the GOF VISITOR Pattern. + +Allow new functions to be added to existing class hierarchies without affecting those hierarchies, and without creating +the troublesome dependency cycles that are inherent to the GoF Visitor Pattern. + +## Explanation + +Real world example + +> We have a hierarchy of modem classes. The modems in this hierarchy need to be visited by an external algorithm based +> on filtering criteria (is it Unix or DOS compatible modem). + +In plain words + +> Acyclic Visitor allows functions to be added to existing class hierarchies without modifying the hierarchies. + +[WikiWikiWeb](https://wiki.c2.com/?AcyclicVisitor) says + +> The Acyclic Visitor pattern allows new functions to be added to existing class hierarchies without affecting those +> hierarchies, and without creating the dependency cycles that are inherent to the GangOfFour VisitorPattern. + +**Programmatic Example** + +Here's the `Modem` hierarchy. + +```java +public abstract class Modem { + public abstract void accept(ModemVisitor modemVisitor); +} + +public class Zoom extends Modem { + ... + @Override + public void accept(ModemVisitor modemVisitor) { + if (modemVisitor instanceof ZoomVisitor) { + ((ZoomVisitor) modemVisitor).visit(this); + } else { + LOGGER.info("Only ZoomVisitor is allowed to visit Zoom modem"); + } + } +} + +public class Hayes extends Modem { + ... + @Override + public void accept(ModemVisitor modemVisitor) { + if (modemVisitor instanceof HayesVisitor) { + ((HayesVisitor) modemVisitor).visit(this); + } else { + LOGGER.info("Only HayesVisitor is allowed to visit Hayes modem"); + } + } +} +``` + +Next we introduce the `ModemVisitor` hierarchy. + +```java +public interface ModemVisitor { +} + +public interface HayesVisitor extends ModemVisitor { + void visit(Hayes hayes); +} + +public interface ZoomVisitor extends ModemVisitor { + void visit(Zoom zoom); +} + +public interface AllModemVisitor extends ZoomVisitor, HayesVisitor { +} + +public class ConfigureForDosVisitor implements AllModemVisitor { + ... + @Override + public void visit(Hayes hayes) { + LOGGER.info(hayes + " used with Dos configurator."); + } + @Override + public void visit(Zoom zoom) { + LOGGER.info(zoom + " used with Dos configurator."); + } +} + +public class ConfigureForUnixVisitor implements ZoomVisitor { + ... + @Override + public void visit(Zoom zoom) { + LOGGER.info(zoom + " used with Unix configurator."); + } +} +``` + +Finally here are the visitors in action. + +```java + var conUnix = new ConfigureForUnixVisitor(); + var conDos = new ConfigureForDosVisitor(); + var zoom = new Zoom(); + var hayes = new Hayes(); + hayes.accept(conDos); + zoom.accept(conDos); + hayes.accept(conUnix); + zoom.accept(conUnix); +``` + +Program output: + +``` + // Hayes modem used with Dos configurator. + // Zoom modem used with Dos configurator. + // Only HayesVisitor is allowed to visit Hayes modem + // Zoom modem used with Unix configurator. +``` ## Class diagram + ![alt text](./etc/acyclic-visitor.png "Acyclic Visitor") ## Applicability + This pattern can be used: * When you need to add a new function to an existing hierarchy without the need to alter or affect that hierarchy. @@ -24,6 +138,7 @@ This pattern can be used: * When the recompilation, relinking, retesting or redistribution of the derivatives of Element is very expensive. ## Consequences + The good: * No dependency cycles between class hierarchies. @@ -32,11 +147,14 @@ The good: The bad: -* Violates the principle of least surprise or Liskov's Substitution principle by showing that it can accept all visitors but actually only being interested in particular visitors. +* Violates [Liskov's Substitution Principle](https://java-design-patterns.com/principles/#liskov-substitution-principle) by showing that it can accept all visitors but actually only being interested in particular visitors. * Parallel hierarchy of visitors has to be created for all members in visitable class hierarchy. ## Related patterns -* [Visitor Pattern](../visitor/) + +* [Visitor Pattern](https://java-design-patterns.com/patterns/visitor/) ## Credits -* [Acyclic Visitor](http://condor.depaul.edu/dmumaugh/OOT/Design-Principles/acv.pdf) + +* [Acyclic Visitor by Robert C. Martin](http://condor.depaul.edu/dmumaugh/OOT/Design-Principles/acv.pdf) +* [Acyclic Visitor in WikiWikiWeb](https://wiki.c2.com/?AcyclicVisitor) From 6a8297598e93195be7aa401af8f528768bef6f7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sat, 1 Aug 2020 15:19:09 +0300 Subject: [PATCH 203/211] #1047 remove module infos --- .../abstractdocument/module-info.java | 26 ----------------- .../iluwatar/abstractfactory/module-info.java | 26 ----------------- .../iluwatar/acyclicvisitor/module-info.java | 26 ----------------- .../business/delegate/module-info.java | 26 ----------------- .../com/iluwatar/callback/module-info.java | 26 ----------------- .../java/com/iluwatar/chain/module-info.java | 26 ----------------- .../collectionpipeline/module-info.java | 26 ----------------- .../com/iluwatar/command/module-info.java | 26 ----------------- .../com/iluwatar/composite/module-info.java | 26 ----------------- .../com/iluwatar/converter/module-info.java | 26 ----------------- .../java/com/iluwatar/dao/module-info.java | 29 ------------------- .../com/iluwatar/datamapper/module-info.java | 26 ----------------- .../iluwatar/datatransfer/module-info.java | 26 ----------------- .../com/iluwatar/decorator/module-info.java | 26 ----------------- .../com/iluwatar/delegation/module-info.java | 26 ----------------- .../com/iluwatar/dirtyflag/module-info.java | 26 ----------------- .../doublechecked/locking/module-info.java | 26 ----------------- .../iluwatar/doubledispatch/module-info.java | 26 ----------------- .../eip/message/channel/module-info.java | 27 ----------------- .../eip/publish/subscribe/module-info.java | 27 ----------------- .../event/aggregator/module-info.java | 26 ----------------- .../event/asynchronous/module-info.java | 26 ----------------- .../iluwatar/execute/around/module-info.java | 26 ----------------- .../java/com/iluwatar/facade/module-info.java | 26 ----------------- .../com/iluwatar/factorykit/module-info.java | 26 ----------------- .../iluwatar/factory/method/module-info.java | 26 ----------------- .../iluwatar/featuretoggle/module-info.java | 26 ----------------- 27 files changed, 707 deletions(-) delete mode 100644 abstract-document/src/main/java/com/iluwatar/abstractdocument/module-info.java delete mode 100644 abstract-factory/src/main/java/com/iluwatar/abstractfactory/module-info.java delete mode 100644 acyclic-visitor/src/main/java/com/iluwatar/acyclicvisitor/module-info.java delete mode 100644 business-delegate/src/main/java/com/iluwatar/business/delegate/module-info.java delete mode 100644 callback/src/main/java/com/iluwatar/callback/module-info.java delete mode 100644 chain/src/main/java/com/iluwatar/chain/module-info.java delete mode 100644 collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/module-info.java delete mode 100644 command/src/main/java/com/iluwatar/command/module-info.java delete mode 100644 composite/src/main/java/com/iluwatar/composite/module-info.java delete mode 100644 converter/src/main/java/com/iluwatar/converter/module-info.java delete mode 100644 dao/src/main/java/com/iluwatar/dao/module-info.java delete mode 100644 data-mapper/src/main/java/com/iluwatar/datamapper/module-info.java delete mode 100644 data-transfer-object/src/main/java/com/iluwatar/datatransfer/module-info.java delete mode 100644 decorator/src/main/java/com/iluwatar/decorator/module-info.java delete mode 100644 delegation/src/main/java/com/iluwatar/delegation/module-info.java delete mode 100644 dirty-flag/src/main/java/com/iluwatar/dirtyflag/module-info.java delete mode 100644 double-checked-locking/src/main/java/com/iluwatar/doublechecked/locking/module-info.java delete mode 100644 double-dispatch/src/main/java/com/iluwatar/doubledispatch/module-info.java delete mode 100644 eip-message-channel/src/main/java/com/iluwatar/eip/message/channel/module-info.java delete mode 100644 eip-publish-subscribe/src/main/java/com/iluwatar/eip/publish/subscribe/module-info.java delete mode 100644 event-aggregator/src/main/java/com/iluwatar/event/aggregator/module-info.java delete mode 100644 event-asynchronous/src/main/java/com/iluwatar/event/asynchronous/module-info.java delete mode 100644 execute-around/src/main/java/com/iluwatar/execute/around/module-info.java delete mode 100644 facade/src/main/java/com/iluwatar/facade/module-info.java delete mode 100644 factory-kit/src/main/java/com/iluwatar/factorykit/module-info.java delete mode 100644 factory-method/src/main/java/com/iluwatar/factory/method/module-info.java delete mode 100644 feature-toggle/src/main/java/com/iluwatar/featuretoggle/module-info.java diff --git a/abstract-document/src/main/java/com/iluwatar/abstractdocument/module-info.java b/abstract-document/src/main/java/com/iluwatar/abstractdocument/module-info.java deleted file mode 100644 index 9121f0049..000000000 --- a/abstract-document/src/main/java/com/iluwatar/abstractdocument/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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. - */ - -module com.iluwatar.abstractdocument { - requires org.slf4j; -} \ No newline at end of file diff --git a/abstract-factory/src/main/java/com/iluwatar/abstractfactory/module-info.java b/abstract-factory/src/main/java/com/iluwatar/abstractfactory/module-info.java deleted file mode 100644 index f075aadc0..000000000 --- a/abstract-factory/src/main/java/com/iluwatar/abstractfactory/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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. - */ - -module com.iluwatar.abstractfactory { - requires org.slf4j; -} \ No newline at end of file diff --git a/acyclic-visitor/src/main/java/com/iluwatar/acyclicvisitor/module-info.java b/acyclic-visitor/src/main/java/com/iluwatar/acyclicvisitor/module-info.java deleted file mode 100644 index 78de5a786..000000000 --- a/acyclic-visitor/src/main/java/com/iluwatar/acyclicvisitor/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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. - */ - -module com.iluwatar.acyclicvisitor { - requires org.slf4j; -} \ No newline at end of file diff --git a/business-delegate/src/main/java/com/iluwatar/business/delegate/module-info.java b/business-delegate/src/main/java/com/iluwatar/business/delegate/module-info.java deleted file mode 100644 index 8f331c848..000000000 --- a/business-delegate/src/main/java/com/iluwatar/business/delegate/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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. - */ - -module com.iluwatar.business.delegate { - requires org.slf4j; -} \ No newline at end of file diff --git a/callback/src/main/java/com/iluwatar/callback/module-info.java b/callback/src/main/java/com/iluwatar/callback/module-info.java deleted file mode 100644 index 21a7a732b..000000000 --- a/callback/src/main/java/com/iluwatar/callback/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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. - */ - -module com.iluwatar.callback { - requires org.slf4j; -} \ No newline at end of file diff --git a/chain/src/main/java/com/iluwatar/chain/module-info.java b/chain/src/main/java/com/iluwatar/chain/module-info.java deleted file mode 100644 index 4f11ab327..000000000 --- a/chain/src/main/java/com/iluwatar/chain/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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. - */ - -module com.iluwatar.chain { - requires org.slf4j; -} \ No newline at end of file diff --git a/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/module-info.java b/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/module-info.java deleted file mode 100644 index f8bd30a68..000000000 --- a/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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. - */ - -module com.iluwatar.collectionpipeline { - requires org.slf4j; -} \ No newline at end of file diff --git a/command/src/main/java/com/iluwatar/command/module-info.java b/command/src/main/java/com/iluwatar/command/module-info.java deleted file mode 100644 index 0e0c0b31f..000000000 --- a/command/src/main/java/com/iluwatar/command/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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. - */ - -module com.iluwatar.command { - requires org.slf4j; -} \ No newline at end of file diff --git a/composite/src/main/java/com/iluwatar/composite/module-info.java b/composite/src/main/java/com/iluwatar/composite/module-info.java deleted file mode 100644 index d75a7b8f8..000000000 --- a/composite/src/main/java/com/iluwatar/composite/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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. - */ - -module com.iluwatar.composite { - requires org.slf4j; -} \ No newline at end of file diff --git a/converter/src/main/java/com/iluwatar/converter/module-info.java b/converter/src/main/java/com/iluwatar/converter/module-info.java deleted file mode 100644 index d83a43c6b..000000000 --- a/converter/src/main/java/com/iluwatar/converter/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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. - */ - -module com.iluwatar.converter { - requires org.slf4j; -} \ No newline at end of file diff --git a/dao/src/main/java/com/iluwatar/dao/module-info.java b/dao/src/main/java/com/iluwatar/dao/module-info.java deleted file mode 100644 index 08e4f662e..000000000 --- a/dao/src/main/java/com/iluwatar/dao/module-info.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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. - */ - -module com.iluwatar.dao { - requires org.slf4j; - requires java.sql; - requires h2; - requires java.naming; -} \ No newline at end of file diff --git a/data-mapper/src/main/java/com/iluwatar/datamapper/module-info.java b/data-mapper/src/main/java/com/iluwatar/datamapper/module-info.java deleted file mode 100644 index 7abd78826..000000000 --- a/data-mapper/src/main/java/com/iluwatar/datamapper/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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. - */ - -module com.iluwatar.datamapper { - requires org.slf4j; -} \ No newline at end of file diff --git a/data-transfer-object/src/main/java/com/iluwatar/datatransfer/module-info.java b/data-transfer-object/src/main/java/com/iluwatar/datatransfer/module-info.java deleted file mode 100644 index 25685d4d0..000000000 --- a/data-transfer-object/src/main/java/com/iluwatar/datatransfer/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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. - */ - -module com.iluwatar.datatransfer { - requires org.slf4j; -} \ No newline at end of file diff --git a/decorator/src/main/java/com/iluwatar/decorator/module-info.java b/decorator/src/main/java/com/iluwatar/decorator/module-info.java deleted file mode 100644 index 50d17f022..000000000 --- a/decorator/src/main/java/com/iluwatar/decorator/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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. - */ - -module com.iluwatar.decorator { - requires org.slf4j; -} \ No newline at end of file diff --git a/delegation/src/main/java/com/iluwatar/delegation/module-info.java b/delegation/src/main/java/com/iluwatar/delegation/module-info.java deleted file mode 100644 index 156477cde..000000000 --- a/delegation/src/main/java/com/iluwatar/delegation/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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. - */ - -module com.iluwatar.delegation { - requires org.slf4j; -} \ No newline at end of file diff --git a/dirty-flag/src/main/java/com/iluwatar/dirtyflag/module-info.java b/dirty-flag/src/main/java/com/iluwatar/dirtyflag/module-info.java deleted file mode 100644 index bf47d2cd7..000000000 --- a/dirty-flag/src/main/java/com/iluwatar/dirtyflag/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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. - */ - -module com.iluwatar.dirtyflag { - requires org.slf4j; -} \ No newline at end of file diff --git a/double-checked-locking/src/main/java/com/iluwatar/doublechecked/locking/module-info.java b/double-checked-locking/src/main/java/com/iluwatar/doublechecked/locking/module-info.java deleted file mode 100644 index 4f4216ea7..000000000 --- a/double-checked-locking/src/main/java/com/iluwatar/doublechecked/locking/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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. - */ - -module com.iluwatar.doublecheckedlocking { - requires org.slf4j; -} \ No newline at end of file diff --git a/double-dispatch/src/main/java/com/iluwatar/doubledispatch/module-info.java b/double-dispatch/src/main/java/com/iluwatar/doubledispatch/module-info.java deleted file mode 100644 index b1bc2e824..000000000 --- a/double-dispatch/src/main/java/com/iluwatar/doubledispatch/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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. - */ - -module com.iluwatar.doubledispatch { - requires org.slf4j; -} \ No newline at end of file diff --git a/eip-message-channel/src/main/java/com/iluwatar/eip/message/channel/module-info.java b/eip-message-channel/src/main/java/com/iluwatar/eip/message/channel/module-info.java deleted file mode 100644 index b904ee1c8..000000000 --- a/eip-message-channel/src/main/java/com/iluwatar/eip/message/channel/module-info.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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. - */ - -module com.iluwatar.eipmessagechannel { - requires org.slf4j; - requires camel.core; -} \ No newline at end of file diff --git a/eip-publish-subscribe/src/main/java/com/iluwatar/eip/publish/subscribe/module-info.java b/eip-publish-subscribe/src/main/java/com/iluwatar/eip/publish/subscribe/module-info.java deleted file mode 100644 index 50eab8360..000000000 --- a/eip-publish-subscribe/src/main/java/com/iluwatar/eip/publish/subscribe/module-info.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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. - */ - -module com.iluwatar.eippublishsubscribe { - requires org.slf4j; - requires camel.core; -} \ No newline at end of file diff --git a/event-aggregator/src/main/java/com/iluwatar/event/aggregator/module-info.java b/event-aggregator/src/main/java/com/iluwatar/event/aggregator/module-info.java deleted file mode 100644 index 93ebd3173..000000000 --- a/event-aggregator/src/main/java/com/iluwatar/event/aggregator/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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. - */ - -module com.iluwatar.eventaggregator { - requires org.slf4j; -} \ No newline at end of file diff --git a/event-asynchronous/src/main/java/com/iluwatar/event/asynchronous/module-info.java b/event-asynchronous/src/main/java/com/iluwatar/event/asynchronous/module-info.java deleted file mode 100644 index aa9b6c29d..000000000 --- a/event-asynchronous/src/main/java/com/iluwatar/event/asynchronous/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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. - */ - -module com.iluwatar.eventasynchronous { - requires org.slf4j; -} \ No newline at end of file diff --git a/execute-around/src/main/java/com/iluwatar/execute/around/module-info.java b/execute-around/src/main/java/com/iluwatar/execute/around/module-info.java deleted file mode 100644 index a3e179094..000000000 --- a/execute-around/src/main/java/com/iluwatar/execute/around/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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. - */ - -module com.iluwatar.executearound { - requires org.slf4j; -} \ No newline at end of file diff --git a/facade/src/main/java/com/iluwatar/facade/module-info.java b/facade/src/main/java/com/iluwatar/facade/module-info.java deleted file mode 100644 index 966758790..000000000 --- a/facade/src/main/java/com/iluwatar/facade/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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. - */ - -module com.iluwatar.facade { - requires org.slf4j; -} \ No newline at end of file diff --git a/factory-kit/src/main/java/com/iluwatar/factorykit/module-info.java b/factory-kit/src/main/java/com/iluwatar/factorykit/module-info.java deleted file mode 100644 index 9440571c4..000000000 --- a/factory-kit/src/main/java/com/iluwatar/factorykit/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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. - */ - -module com.iluwatar.factorykit { - requires org.slf4j; -} \ No newline at end of file diff --git a/factory-method/src/main/java/com/iluwatar/factory/method/module-info.java b/factory-method/src/main/java/com/iluwatar/factory/method/module-info.java deleted file mode 100644 index 4ea385c8b..000000000 --- a/factory-method/src/main/java/com/iluwatar/factory/method/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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. - */ - -module com.iluwatar.factorymethod { - requires org.slf4j; -} \ No newline at end of file diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/module-info.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/module-info.java deleted file mode 100644 index 55c2d7714..000000000 --- a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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. - */ - -module com.iluwatar.featuretoggle { - requires org.slf4j; -} \ No newline at end of file From b3bfd43bffdbb02cc9b990c9616ebf632c0896dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sat, 1 Aug 2020 15:54:46 +0300 Subject: [PATCH 204/211] #590 update Acyclic Visitor class diagram --- acyclic-visitor/etc/Acyclic Visitor.ucls | 115 ----------------------- acyclic-visitor/etc/acyclic-visitor.png | Bin 26645 -> 49064 bytes 2 files changed, 115 deletions(-) delete mode 100644 acyclic-visitor/etc/Acyclic Visitor.ucls diff --git a/acyclic-visitor/etc/Acyclic Visitor.ucls b/acyclic-visitor/etc/Acyclic Visitor.ucls deleted file mode 100644 index 03b6c77dd..000000000 --- a/acyclic-visitor/etc/Acyclic Visitor.ucls +++ /dev/null @@ -1,115 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/acyclic-visitor/etc/acyclic-visitor.png b/acyclic-visitor/etc/acyclic-visitor.png index 636532c4d5d6443c94173fec7b0782eb8b661fe9..7b4df13d80f8c0d1be8ca32cbc39594bbd9ec7d4 100644 GIT binary patch literal 49064 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 J8O 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 Date: Sat, 1 Aug 2020 16:26:14 +0300 Subject: [PATCH 205/211] work on Abstract Factory readme --- abstract-factory/README.md | 53 ++++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 19 deletions(-) diff --git a/abstract-factory/README.md b/abstract-factory/README.md index fba3460c1..141bf5021 100644 --- a/abstract-factory/README.md +++ b/abstract-factory/README.md @@ -9,13 +9,16 @@ tags: --- ## Also known as + Kit ## Intent + Provide an interface for creating families of related or dependent objects without specifying their concrete classes. ## Explanation + Real world example > To create a kingdom we need objects with common theme. Elven kingdom needs an Elven king, Elven castle and Elven army whereas Orcish kingdom needs an Orcish king, Orcish castle and Orcish army. There is a dependency between the objects in the kingdom. @@ -36,9 +39,11 @@ Translating the kingdom example above. First of all we have some interfaces and public interface Castle { String getDescription(); } + public interface King { String getDescription(); } + public interface Army { String getDescription(); } @@ -66,7 +71,7 @@ public class ElfArmy implements Army { } } -// Orcish implementations similarly... +// Orcish implementations similarly -> ... ``` @@ -112,9 +117,17 @@ var castle = factory.createCastle(); var king = factory.createKing(); var army = factory.createArmy(); -castle.getDescription(); // Output: This is the Elven castle! -king.getDescription(); // Output: This is the Elven king! -army.getDescription(); // Output: This is the Elven Army! +castle.getDescription(); +king.getDescription(); +army.getDescription(); +``` + +Program output: + +```java +This is the Elven castle! +This is the Elven king! +This is the Elven Army! ``` Now, we can design a factory for our different kingdom factories. In this example, we created FactoryMaker, responsible for returning an instance of either ElfKingdomFactory or OrcKingdomFactory. @@ -156,37 +169,39 @@ public static void main(String[] args) { ``` ## Class diagram + ![alt text](./etc/abstract-factory.urm.png "Abstract Factory class diagram") ## 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 -* the lifetime of the dependency is conceptually shorter than the lifetime of the consumer. -* you need a run-time value to construct a particular dependency -* you want to decide which product to call from a family at runtime. -* you need to supply one or more parameters only known at run-time before you can resolve a dependency. -* when you need consistency among products -* you don’t want to change existing code when adding new products or families of products to the program. +* The system should be independent of how its products are created, composed and represented +* The system should be configured with one of multiple families of products +* The 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 +* The lifetime of the dependency is conceptually shorter than the lifetime of the consumer. +* You need a run-time value to construct a particular dependency +* You want to decide which product to call from a family at runtime. +* You need to supply one or more parameters only known at run-time before you can resolve a dependency. +* When you need consistency among products +* You don’t want to change existing code when adding new products or families of products to the program. ## Use Cases: -* Selecting to call the appropriate implementation of FileSystemAcmeService or DatabaseAcmeService or NetworkAcmeService at runtime. -* Unit test case writing becomes much easier +* Selecting to call the appropriate implementation of FileSystemAcmeService or DatabaseAcmeService or NetworkAcmeService at runtime. +* Unit test case writing becomes much easier * UI tools for different OS ## Consequences: -* Dependency injection in java hides the service class dependencies that can lead to runtime errors that would have been caught at compile time. +* Dependency injection in java hides the service class dependencies that can lead to runtime errors that would have been caught at compile time. * While the pattern is great when creating predefined objects, adding the new ones might be challenging. -* The code may become more complicated than it should be, since a lot of new interfaces and classes are introduced along with the pattern. - +* The code becomes more complicated than it should be, since a lot of new interfaces and classes are introduced along with the pattern. ## Tutorial + * [Abstract Factory Pattern Tutorial](https://www.journaldev.com/1418/abstract-factory-design-pattern-in-java) From 14487261d078ef96f0dec07633c05a213ee1e1ca Mon Sep 17 00:00:00 2001 From: Matt Dolan Date: Sun, 2 Aug 2020 00:03:36 -0400 Subject: [PATCH 206/211] Use of ${artifactId} is deprecated and should be updated to ${project.artifactId} --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f23369107..65d6d3e2b 100644 --- a/pom.xml +++ b/pom.xml @@ -58,7 +58,7 @@ https://sonarcloud.io iluwatar iluwatar_java-design-patterns - ${artifactId} + ${project.artifactId} Java Design Patterns From 689cc8b59b2f1c914ef9c05841e7e9998cb0bdbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 2 Aug 2020 11:53:52 +0300 Subject: [PATCH 207/211] Update surefire and minor improvements --- pom.xml | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/pom.xml b/pom.xml index 65d6d3e2b..3b4f05b37 100644 --- a/pom.xml +++ b/pom.xml @@ -375,10 +375,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.0.0-M3 - - -Xmx1024M ${argLine} - + 3.0.0-M5 org.springframework.boot @@ -474,7 +471,7 @@ true - ${projectRoot}${file.separator}license-plugin-header-style.xml + license-plugin-header-style.xml SLASHSTAR_CUSTOM_STYLE @@ -540,14 +537,4 @@ - - - - org.apache.maven.plugins - maven-jxr-plugin - 3.0.0 - - - - - \ No newline at end of file + From b0ded54c664141bfb7732579817598004cbc0399 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 2 Aug 2020 22:48:54 +0300 Subject: [PATCH 208/211] Cleanup --- .../java/com/iluwatar/abstractdocument/App.java | 16 ++++------------ .../abstractdocument/AbstractDocumentTest.java | 2 +- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/abstract-document/src/main/java/com/iluwatar/abstractdocument/App.java b/abstract-document/src/main/java/com/iluwatar/abstractdocument/App.java index b881ee7ac..d13021e72 100644 --- a/abstract-document/src/main/java/com/iluwatar/abstractdocument/App.java +++ b/abstract-document/src/main/java/com/iluwatar/abstractdocument/App.java @@ -43,9 +43,11 @@ public class App { private static final Logger LOGGER = LoggerFactory.getLogger(App.class); /** - * Executes the App. + * Program entry point. + * + * @param args command line args */ - public App() { + public static void main(String[] args) { LOGGER.info("Constructing parts and car"); var wheelProperties = Map.of( @@ -75,14 +77,4 @@ public class App { p.getPrice().orElse(null)) ); } - - /** - * Program entry point. - * - * @param args command line args - */ - public static void main(String[] args) { - new App(); - } - } diff --git a/abstract-document/src/test/java/com/iluwatar/abstractdocument/AbstractDocumentTest.java b/abstract-document/src/test/java/com/iluwatar/abstractdocument/AbstractDocumentTest.java index c0791c30b..13db318e4 100644 --- a/abstract-document/src/test/java/com/iluwatar/abstractdocument/AbstractDocumentTest.java +++ b/abstract-document/src/test/java/com/iluwatar/abstractdocument/AbstractDocumentTest.java @@ -40,7 +40,7 @@ public class AbstractDocumentTest { private static final String KEY = "key"; private static final String VALUE = "value"; - private class DocumentImplementation extends AbstractDocument { + private static class DocumentImplementation extends AbstractDocument { DocumentImplementation(Map properties) { super(properties); From 83acaa82d441b7373855e8c7acbcbddc2de339b9 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 3 Aug 2020 13:30:51 +0000 Subject: [PATCH 209/211] docs: update README.md [skip ci] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 401a92103..b9509ee16 100644 --- a/README.md +++ b/README.md @@ -239,7 +239,7 @@ This project is licensed under the terms of the MIT license.
Lars Kappert

🖋
Mike Liu

🌍 -
Matt Dolan

💻 +
Matt Dolan

💻 👀 From f84f7b973cf955a8aae29602f2629206647c54f7 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 3 Aug 2020 13:30:52 +0000 Subject: [PATCH 210/211] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 50f6363e0..5e0b93860 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1045,7 +1045,8 @@ "avatar_url": "https://avatars1.githubusercontent.com/u/6307904?v=4", "profile": "https://github.com/charlesfinley", "contributions": [ - "code" + "code", + "review" ] } ], From 9ff5b9e7c09277cc51c3b26224608c699b457156 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Mon, 3 Aug 2020 16:49:46 +0300 Subject: [PATCH 211/211] Fix merge --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index a48db3dd2..d7115a51d 100644 --- a/README.md +++ b/README.md @@ -239,13 +239,12 @@ This project is licensed under the terms of the MIT license.
Lars Kappert

🖋
Mike Liu

🌍 -
Matt Dolan

💻 +
Matt Dolan

💻 👀
Manan

👀
Nishant Arora

💻
Peeyush

💻 -
Matt Dolan

💻 👀