diff --git a/bridge/README.md b/bridge/README.md
index 6c1e70631..a37c35174 100644
--- a/bridge/README.md
+++ b/bridge/README.md
@@ -15,10 +15,170 @@ tags:
Handle/Body
## Intent
-Decouple an abstraction from its implementation so that the two can
-vary independently.
+Decouple an abstraction from its implementation so that the two can vary independently.
-
+## Explanation
+
+Real world example
+
+> Consider you have a weapon with different enchantments and you are supposed to allow mixing different weapons with different enchantments. What would you do? Create multiple copies of each of the weapons for each of the enchantments or would you just create separate enchantment and set it for the weapon as needed? Bridge pattern allows you to do the second.
+
+In Plain Words
+
+> Bridge pattern is about preferring composition over inheritance. Implementation details are pushed from a hierarchy to another object with a separate hierarchy.
+
+Wikipedia says
+
+> The bridge pattern is a design pattern used in software engineering that is meant to "decouple an abstraction from its implementation so that the two can vary independently"
+
+**Programmatic Example**
+
+Translating our weapon example from above. Here we have the `Weapon` hierarchy
+
+```
+public interface Weapon {
+ void wield();
+ void swing();
+ void unwield();
+ Enchantment getEnchantment();
+}
+
+public class Sword implements Weapon {
+
+ private final Enchantment enchantment;
+
+ public Sword(Enchantment enchantment) {
+ this.enchantment = enchantment;
+ }
+
+ @Override
+ public void wield() {
+ LOGGER.info("The sword is wielded.");
+ enchantment.onActivate();
+ }
+
+ @Override
+ public void swing() {
+ LOGGER.info("The sword is swinged.");
+ enchantment.apply();
+ }
+
+ @Override
+ public void unwield() {
+ LOGGER.info("The sword is unwielded.");
+ enchantment.onDeactivate();
+ }
+
+ @Override
+ public Enchantment getEnchantment() {
+ return enchantment;
+ }
+}
+
+public class Hammer implements Weapon {
+
+ private final Enchantment enchantment;
+
+ public Hammer(Enchantment enchantment) {
+ this.enchantment = enchantment;
+ }
+
+ @Override
+ public void wield() {
+ LOGGER.info("The hammer is wielded.");
+ enchantment.onActivate();
+ }
+
+ @Override
+ public void swing() {
+ LOGGER.info("The hammer is swinged.");
+ enchantment.apply();
+ }
+
+ @Override
+ public void unwield() {
+ LOGGER.info("The hammer is unwielded.");
+ enchantment.onDeactivate();
+ }
+
+ @Override
+ public Enchantment getEnchantment() {
+ return enchantment;
+ }
+}
+```
+
+And the separate enchantment hierarchy
+
+```
+public interface Enchantment {
+ void onActivate();
+ void apply();
+ void onDeactivate();
+}
+
+public class FlyingEnchantment implements Enchantment {
+
+ @Override
+ public void onActivate() {
+ LOGGER.info("The item begins to glow faintly.");
+ }
+
+ @Override
+ public void apply() {
+ LOGGER.info("The item flies and strikes the enemies finally returning to owner's hand.");
+ }
+
+ @Override
+ public void onDeactivate() {
+ LOGGER.info("The item's glow fades.");
+ }
+}
+
+public class SoulEatingEnchantment implements Enchantment {
+
+ @Override
+ public void onActivate() {
+ LOGGER.info("The item spreads bloodlust.");
+ }
+
+ @Override
+ public void apply() {
+ LOGGER.info("The item eats the soul of enemies.");
+ }
+
+ @Override
+ public void onDeactivate() {
+ LOGGER.info("Bloodlust slowly disappears.");
+ }
+}
+```
+
+And both the hierarchies in action
+
+```
+Sword enchantedSword = new Sword(new SoulEatingEnchantment());
+enchantedSword.wield();
+enchantedSword.swing();
+enchantedSword.unwield();
+// The sword is wielded.
+// The item spreads bloodlust.
+// The sword is swinged.
+// The item eats the soul of enemies.
+// The sword is unwielded.
+// Bloodlust slowly disappears.
+
+Hammer hammer = new Hammer(new FlyingEnchantment());
+hammer.wield();
+hammer.swing();
+hammer.unwield();
+// The hammer is wielded.
+// The item begins to glow faintly.
+// The hammer is swinged.
+// The item flies and strikes the enemies finally returning to owner's hand.
+// The hammer is unwielded.
+// The item's glow fades.
+```
## Applicability
Use the Bridge pattern when
diff --git a/bridge/etc/bridge.png b/bridge/etc/bridge.png
deleted file mode 100644
index 00d3e611c..000000000
Binary files a/bridge/etc/bridge.png and /dev/null differ
diff --git a/bridge/etc/bridge.ucls b/bridge/etc/bridge.ucls
deleted file mode 100644
index 2eda6e1d1..000000000
--- a/bridge/etc/bridge.ucls
+++ /dev/null
@@ -1,157 +0,0 @@
-
-
- * In Bridge pattern both abstraction ({@link MagicWeapon}) and implementation ( - * {@link MagicWeaponImpl}) have their own class hierarchies. The interface of the implementations + * In Bridge pattern both abstraction ({@link Weapon}) and implementation ( + * {@link Enchantment}) have their own class hierarchies. The interface of the implementations * can be changed without affecting the clients. + *
+ * In this example we have two class hierarchies. One of weapons and another one of enchantments. We can easily + * combine any weapon with any enchantment using composition instead of creating deep class hierarchy. * */ public class App { + private static final Logger LOGGER = LoggerFactory.getLogger(App.class); + /** * Program entry point * * @param args command line args */ public static void main(String[] args) { - BlindingMagicWeapon blindingMagicWeapon = new BlindingMagicWeapon(new Excalibur()); - blindingMagicWeapon.wield(); - blindingMagicWeapon.blind(); - blindingMagicWeapon.swing(); - blindingMagicWeapon.unwield(); + LOGGER.info("The knight receives an enchanted sword."); + Sword enchantedSword = new Sword(new SoulEatingEnchantment()); + enchantedSword.wield(); + enchantedSword.swing(); + enchantedSword.unwield(); - FlyingMagicWeapon flyingMagicWeapon = new FlyingMagicWeapon(new Mjollnir()); - flyingMagicWeapon.wield(); - flyingMagicWeapon.fly(); - flyingMagicWeapon.swing(); - flyingMagicWeapon.unwield(); - - SoulEatingMagicWeapon soulEatingMagicWeapon = new SoulEatingMagicWeapon(new Stormbringer()); - soulEatingMagicWeapon.wield(); - soulEatingMagicWeapon.swing(); - soulEatingMagicWeapon.eatSoul(); - soulEatingMagicWeapon.unwield(); + LOGGER.info("The valkyrie receives an enchanted hammer."); + Hammer hammer = new Hammer(new FlyingEnchantment()); + hammer.wield(); + hammer.swing(); + hammer.unwield(); } } diff --git a/bridge/src/main/java/com/iluwatar/bridge/FlyingMagicWeaponImpl.java b/bridge/src/main/java/com/iluwatar/bridge/Enchantment.java similarity index 90% rename from bridge/src/main/java/com/iluwatar/bridge/FlyingMagicWeaponImpl.java rename to bridge/src/main/java/com/iluwatar/bridge/Enchantment.java index c7b47e780..dd0c17205 100644 --- a/bridge/src/main/java/com/iluwatar/bridge/FlyingMagicWeaponImpl.java +++ b/bridge/src/main/java/com/iluwatar/bridge/Enchantment.java @@ -24,11 +24,14 @@ package com.iluwatar.bridge; /** * - * FlyingMagicWeaponImpl - * + * Enchantment + * */ -public abstract class FlyingMagicWeaponImpl extends MagicWeaponImpl { +public interface Enchantment { - public abstract void flyImp(); + void onActivate(); + void apply(); + + void onDeactivate(); } diff --git a/bridge/src/main/java/com/iluwatar/bridge/Excalibur.java b/bridge/src/main/java/com/iluwatar/bridge/FlyingEnchantment.java similarity index 73% rename from bridge/src/main/java/com/iluwatar/bridge/Excalibur.java rename to bridge/src/main/java/com/iluwatar/bridge/FlyingEnchantment.java index ddd2ac540..8b12c6114 100644 --- a/bridge/src/main/java/com/iluwatar/bridge/Excalibur.java +++ b/bridge/src/main/java/com/iluwatar/bridge/FlyingEnchantment.java @@ -27,30 +27,25 @@ import org.slf4j.LoggerFactory; /** * - * Excalibur + * FlyingEnchantment * */ -public class Excalibur extends BlindingMagicWeaponImpl { +public class FlyingEnchantment implements Enchantment { - private static final Logger LOGGER = LoggerFactory.getLogger(Excalibur.class); + private static final Logger LOGGER = LoggerFactory.getLogger(FlyingEnchantment.class); @Override - public void wieldImp() { - LOGGER.info("wielding Excalibur"); + public void onActivate() { + LOGGER.info("The item begins to glow faintly."); } @Override - public void swingImp() { - LOGGER.info("swinging Excalibur"); + public void apply() { + LOGGER.info("The item flies and strikes the enemies finally returning to owner's hand."); } @Override - public void unwieldImp() { - LOGGER.info("unwielding Excalibur"); - } - - @Override - public void blindImp() { - LOGGER.info("bright light streams from Excalibur blinding the enemy"); + public void onDeactivate() { + LOGGER.info("The item's glow fades."); } } diff --git a/bridge/src/main/java/com/iluwatar/bridge/FlyingMagicWeapon.java b/bridge/src/main/java/com/iluwatar/bridge/FlyingMagicWeapon.java deleted file mode 100644 index 85532d410..000000000 --- a/bridge/src/main/java/com/iluwatar/bridge/FlyingMagicWeapon.java +++ /dev/null @@ -1,59 +0,0 @@ -/** - * The MIT License - * Copyright (c) 2014-2016 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.bridge; - -/** - * - * FlyingMagicWeapon - * - */ -public class FlyingMagicWeapon extends MagicWeapon { - - public FlyingMagicWeapon(FlyingMagicWeaponImpl imp) { - super(imp); - } - - public FlyingMagicWeaponImpl getImp() { - return (FlyingMagicWeaponImpl) imp; - } - - @Override - public void wield() { - getImp().wieldImp(); - } - - @Override - public void swing() { - getImp().swingImp(); - } - - @Override - public void unwield() { - getImp().unwieldImp(); - } - - public void fly() { - getImp().flyImp(); - } - -} diff --git a/bridge/src/main/java/com/iluwatar/bridge/BlindingMagicWeapon.java b/bridge/src/main/java/com/iluwatar/bridge/Hammer.java similarity index 69% rename from bridge/src/main/java/com/iluwatar/bridge/BlindingMagicWeapon.java rename to bridge/src/main/java/com/iluwatar/bridge/Hammer.java index e70cbb96e..51bfda2a1 100644 --- a/bridge/src/main/java/com/iluwatar/bridge/BlindingMagicWeapon.java +++ b/bridge/src/main/java/com/iluwatar/bridge/Hammer.java @@ -22,38 +22,44 @@ */ package com.iluwatar.bridge; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * - * BlindingMagicWeapon + * Hammer * */ -public class BlindingMagicWeapon extends MagicWeapon { +public class Hammer implements Weapon { - public BlindingMagicWeapon(BlindingMagicWeaponImpl imp) { - super(imp); - } + private static final Logger LOGGER = LoggerFactory.getLogger(Hammer.class); - @Override - public BlindingMagicWeaponImpl getImp() { - return (BlindingMagicWeaponImpl) imp; + private final Enchantment enchantment; + + public Hammer(Enchantment enchantment) { + this.enchantment = enchantment; } @Override public void wield() { - getImp().wieldImp(); + LOGGER.info("The hammer is wielded."); + enchantment.onActivate(); } @Override public void swing() { - getImp().swingImp(); + LOGGER.info("The hammer is swinged."); + enchantment.apply(); } @Override public void unwield() { - getImp().unwieldImp(); + LOGGER.info("The hammer is unwielded."); + enchantment.onDeactivate(); } - public void blind() { - getImp().blindImp(); + @Override + public Enchantment getEnchantment() { + return enchantment; } } diff --git a/bridge/src/main/java/com/iluwatar/bridge/MagicWeaponImpl.java b/bridge/src/main/java/com/iluwatar/bridge/MagicWeaponImpl.java deleted file mode 100644 index b0d3070c1..000000000 --- a/bridge/src/main/java/com/iluwatar/bridge/MagicWeaponImpl.java +++ /dev/null @@ -1,38 +0,0 @@ -/** - * The MIT License - * Copyright (c) 2014-2016 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.bridge; - -/** - * - * MagicWeaponImpl - * - */ -public abstract class MagicWeaponImpl { - - public abstract void wieldImp(); - - public abstract void swingImp(); - - public abstract void unwieldImp(); - -} diff --git a/bridge/src/main/java/com/iluwatar/bridge/Mjollnir.java b/bridge/src/main/java/com/iluwatar/bridge/Mjollnir.java deleted file mode 100644 index 7cec530eb..000000000 --- a/bridge/src/main/java/com/iluwatar/bridge/Mjollnir.java +++ /dev/null @@ -1,56 +0,0 @@ -/** - * The MIT License - * Copyright (c) 2014-2016 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.bridge; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * - * Mjollnir - * - */ -public class Mjollnir extends FlyingMagicWeaponImpl { - - private static final Logger LOGGER = LoggerFactory.getLogger(Mjollnir.class); - - @Override - public void wieldImp() { - LOGGER.info("wielding Mjollnir"); - } - - @Override - public void swingImp() { - LOGGER.info("swinging Mjollnir"); - } - - @Override - public void unwieldImp() { - LOGGER.info("unwielding Mjollnir"); - } - - @Override - public void flyImp() { - LOGGER.info("Mjollnir hits the enemy in the air and returns back to the owner's hand"); - } -} diff --git a/bridge/src/main/java/com/iluwatar/bridge/Stormbringer.java b/bridge/src/main/java/com/iluwatar/bridge/SoulEatingEnchantment.java similarity index 76% rename from bridge/src/main/java/com/iluwatar/bridge/Stormbringer.java rename to bridge/src/main/java/com/iluwatar/bridge/SoulEatingEnchantment.java index 0c7a6ce6b..8b08d155c 100644 --- a/bridge/src/main/java/com/iluwatar/bridge/Stormbringer.java +++ b/bridge/src/main/java/com/iluwatar/bridge/SoulEatingEnchantment.java @@ -27,30 +27,25 @@ import org.slf4j.LoggerFactory; /** * - * Stormbringer + * SoulEatingEnchantment * */ -public class Stormbringer extends SoulEatingMagicWeaponImpl { +public class SoulEatingEnchantment implements Enchantment { - private static final Logger LOGGER = LoggerFactory.getLogger(Stormbringer.class); + private static final Logger LOGGER = LoggerFactory.getLogger(SoulEatingEnchantment.class); @Override - public void wieldImp() { - LOGGER.info("wielding Stormbringer"); + public void onActivate() { + LOGGER.info("The item spreads bloodlust."); } @Override - public void swingImp() { - LOGGER.info("swinging Stormbringer"); + public void apply() { + LOGGER.info("The item eats the soul of enemies."); } @Override - public void unwieldImp() { - LOGGER.info("unwielding Stormbringer"); - } - - @Override - public void eatSoulImp() { - LOGGER.info("Stormbringer devours the enemy's soul"); + public void onDeactivate() { + LOGGER.info("Bloodlust slowly disappears."); } } diff --git a/bridge/src/main/java/com/iluwatar/bridge/SoulEatingMagicWeaponImpl.java b/bridge/src/main/java/com/iluwatar/bridge/SoulEatingMagicWeaponImpl.java deleted file mode 100644 index 2ed27242a..000000000 --- a/bridge/src/main/java/com/iluwatar/bridge/SoulEatingMagicWeaponImpl.java +++ /dev/null @@ -1,34 +0,0 @@ -/** - * The MIT License - * Copyright (c) 2014-2016 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.bridge; - -/** - * - * SoulEatingMagicWeaponImpl - * - */ -public abstract class SoulEatingMagicWeaponImpl extends MagicWeaponImpl { - - public abstract void eatSoulImp(); - -} diff --git a/bridge/src/main/java/com/iluwatar/bridge/SoulEatingMagicWeapon.java b/bridge/src/main/java/com/iluwatar/bridge/Sword.java similarity index 69% rename from bridge/src/main/java/com/iluwatar/bridge/SoulEatingMagicWeapon.java rename to bridge/src/main/java/com/iluwatar/bridge/Sword.java index 927ac2d66..6f52943a6 100644 --- a/bridge/src/main/java/com/iluwatar/bridge/SoulEatingMagicWeapon.java +++ b/bridge/src/main/java/com/iluwatar/bridge/Sword.java @@ -22,39 +22,44 @@ */ package com.iluwatar.bridge; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * - * SoulEatingMagicWeapon + * Sword * */ -public class SoulEatingMagicWeapon extends MagicWeapon { +public class Sword implements Weapon { - public SoulEatingMagicWeapon(SoulEatingMagicWeaponImpl imp) { - super(imp); - } + private static final Logger LOGGER = LoggerFactory.getLogger(Sword.class); - @Override - public SoulEatingMagicWeaponImpl getImp() { - return (SoulEatingMagicWeaponImpl) imp; + private final Enchantment enchantment; + + public Sword(Enchantment enchantment) { + this.enchantment = enchantment; } @Override public void wield() { - getImp().wieldImp(); + LOGGER.info("The sword is wielded."); + enchantment.onActivate(); } @Override public void swing() { - getImp().swingImp(); + LOGGER.info("The sword is swinged."); + enchantment.apply(); } @Override public void unwield() { - getImp().unwieldImp(); + LOGGER.info("The sword is unwielded."); + enchantment.onDeactivate(); } - public void eatSoul() { - getImp().eatSoulImp(); + @Override + public Enchantment getEnchantment() { + return enchantment; } - } diff --git a/bridge/src/main/java/com/iluwatar/bridge/BlindingMagicWeaponImpl.java b/bridge/src/main/java/com/iluwatar/bridge/Weapon.java similarity index 89% rename from bridge/src/main/java/com/iluwatar/bridge/BlindingMagicWeaponImpl.java rename to bridge/src/main/java/com/iluwatar/bridge/Weapon.java index 0bd7d7b52..a2d21b88f 100644 --- a/bridge/src/main/java/com/iluwatar/bridge/BlindingMagicWeaponImpl.java +++ b/bridge/src/main/java/com/iluwatar/bridge/Weapon.java @@ -24,11 +24,16 @@ package com.iluwatar.bridge; /** * - * BlindingMagicWeaponImpl - * + * Weapon + * */ -public abstract class BlindingMagicWeaponImpl extends MagicWeaponImpl { +public interface Weapon { - public abstract void blindImp(); + void wield(); + void swing(); + + void unwield(); + + Enchantment getEnchantment(); } diff --git a/bridge/src/test/java/com/iluwatar/bridge/BlindingMagicWeaponTest.java b/bridge/src/test/java/com/iluwatar/bridge/BlindingMagicWeaponTest.java deleted file mode 100644 index 97298a161..000000000 --- a/bridge/src/test/java/com/iluwatar/bridge/BlindingMagicWeaponTest.java +++ /dev/null @@ -1,55 +0,0 @@ -/** - * The MIT License - * Copyright (c) 2014-2016 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.bridge; - -import org.junit.Test; - -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.internal.verification.VerificationModeFactory.times; - -/** - * Date: 12/6/15 - 11:15 PM - * - * @author Jeroen Meulemeester - */ -public class BlindingMagicWeaponTest extends MagicWeaponTest { - - /** - * Invoke all possible actions on the weapon and check if the actions are executed on the actual - * underlying weapon implementation. - */ - @Test - public void testExcalibur() throws Exception { - final Excalibur excalibur = spy(new Excalibur()); - final BlindingMagicWeapon blindingMagicWeapon = new BlindingMagicWeapon(excalibur); - - testBasicWeaponActions(blindingMagicWeapon, excalibur); - - blindingMagicWeapon.blind(); - verify(excalibur, times(1)).blindImp(); - verifyNoMoreInteractions(excalibur); - } - -} diff --git a/bridge/src/test/java/com/iluwatar/bridge/FlyingMagicWeaponTest.java b/bridge/src/test/java/com/iluwatar/bridge/HammerTest.java similarity index 70% rename from bridge/src/test/java/com/iluwatar/bridge/FlyingMagicWeaponTest.java rename to bridge/src/test/java/com/iluwatar/bridge/HammerTest.java index fca3ea9ab..a650bae04 100644 --- a/bridge/src/test/java/com/iluwatar/bridge/FlyingMagicWeaponTest.java +++ b/bridge/src/test/java/com/iluwatar/bridge/HammerTest.java @@ -24,32 +24,22 @@ package com.iluwatar.bridge; import org.junit.Test; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.internal.verification.VerificationModeFactory.times; /** - * Date: 12/6/15 - 11:26 PM - * - * @author Jeroen Meulemeester + * Tests for hammer */ -public class FlyingMagicWeaponTest extends MagicWeaponTest { +public class HammerTest extends WeaponTest { /** * Invoke all possible actions on the weapon and check if the actions are executed on the actual * underlying weapon implementation. */ @Test - public void testMjollnir() throws Exception { - final Mjollnir mjollnir = spy(new Mjollnir()); - final FlyingMagicWeapon flyingMagicWeapon = new FlyingMagicWeapon(mjollnir); - - testBasicWeaponActions(flyingMagicWeapon, mjollnir); - - flyingMagicWeapon.fly(); - verify(mjollnir, times(1)).flyImp(); - verifyNoMoreInteractions(mjollnir); + public void testHammer() throws Exception { + final Hammer hammer = spy(new Hammer(mock(FlyingEnchantment.class))); + testBasicWeaponActions(hammer); } - } \ No newline at end of file diff --git a/bridge/src/test/java/com/iluwatar/bridge/SoulEatingMagicWeaponTest.java b/bridge/src/test/java/com/iluwatar/bridge/SoulEatingMagicWeaponTest.java deleted file mode 100644 index b71fe2228..000000000 --- a/bridge/src/test/java/com/iluwatar/bridge/SoulEatingMagicWeaponTest.java +++ /dev/null @@ -1,55 +0,0 @@ -/** - * The MIT License - * Copyright (c) 2014-2016 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.bridge; - -import org.junit.Test; - -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.internal.verification.VerificationModeFactory.times; - -/** - * Date: 12/6/15 - 11:43 PM - * - * @author Jeroen Meulemeester - */ -public class SoulEatingMagicWeaponTest extends MagicWeaponTest { - - /** - * Invoke all possible actions on the weapon and check if the actions are executed on the actual - * underlying weapon implementation. - */ - @Test - public void testStormBringer() throws Exception { - final Stormbringer stormbringer = spy(new Stormbringer()); - final SoulEatingMagicWeapon soulEatingMagicWeapon = new SoulEatingMagicWeapon(stormbringer); - - testBasicWeaponActions(soulEatingMagicWeapon, stormbringer); - - soulEatingMagicWeapon.eatSoul(); - verify(stormbringer, times(1)).eatSoulImp(); - verifyNoMoreInteractions(stormbringer); - } - -} \ No newline at end of file diff --git a/bridge/src/main/java/com/iluwatar/bridge/MagicWeapon.java b/bridge/src/test/java/com/iluwatar/bridge/SwordTest.java similarity index 69% rename from bridge/src/main/java/com/iluwatar/bridge/MagicWeapon.java rename to bridge/src/test/java/com/iluwatar/bridge/SwordTest.java index 049133d91..7ffd0e492 100644 --- a/bridge/src/main/java/com/iluwatar/bridge/MagicWeapon.java +++ b/bridge/src/test/java/com/iluwatar/bridge/SwordTest.java @@ -22,26 +22,24 @@ */ package com.iluwatar.bridge; +import org.junit.Test; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; + /** - * - * MagicWeapon - * + * Tests for sword */ -public abstract class MagicWeapon { +public class SwordTest extends WeaponTest { - protected MagicWeaponImpl imp; - - public MagicWeapon(MagicWeaponImpl imp) { - this.imp = imp; + /** + * Invoke all possible actions on the weapon and check if the actions are executed on the actual + * underlying weapon implementation. + */ + @Test + public void testSword() throws Exception { + final Sword sword = spy(new Sword(mock(FlyingEnchantment.class))); + testBasicWeaponActions(sword); } - - public abstract void wield(); - - public abstract void swing(); - - public abstract void unwield(); - - public MagicWeaponImpl getImp() { - return imp; - } -} +} \ No newline at end of file diff --git a/bridge/src/test/java/com/iluwatar/bridge/MagicWeaponTest.java b/bridge/src/test/java/com/iluwatar/bridge/WeaponTest.java similarity index 67% rename from bridge/src/test/java/com/iluwatar/bridge/MagicWeaponTest.java rename to bridge/src/test/java/com/iluwatar/bridge/WeaponTest.java index e883f03d3..daec1014a 100644 --- a/bridge/src/test/java/com/iluwatar/bridge/MagicWeaponTest.java +++ b/bridge/src/test/java/com/iluwatar/bridge/WeaponTest.java @@ -28,37 +28,32 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.internal.verification.VerificationModeFactory.times; /** - * Date: 12/6/15 - 11:28 PM - * - * @author Jeroen Meulemeester + * Base class for weapon tests */ -public abstract class MagicWeaponTest { +public abstract class WeaponTest { /** - * Invoke the basic actions of the given weapon, and test if the underlying weapon implementation + * Invoke the basic actions of the given weapon, and test if the underlying enchantment implementation * is invoked * - * @param weaponImpl The spied weapon implementation where actions are bridged to - * @param weapon The weapon, handled by the app */ - protected final void testBasicWeaponActions(final MagicWeapon weapon, - final MagicWeaponImpl weaponImpl) { + protected final void testBasicWeaponActions(final Weapon weapon) { assertNotNull(weapon); - assertNotNull(weaponImpl); - assertNotNull(weapon.getImp()); + Enchantment enchantment = weapon.getEnchantment(); + assertNotNull(enchantment); + assertNotNull(weapon.getEnchantment()); weapon.swing(); - verify(weaponImpl, times(1)).swingImp(); - verifyNoMoreInteractions(weaponImpl); + verify(enchantment, times(1)).apply(); + verifyNoMoreInteractions(enchantment); weapon.wield(); - verify(weaponImpl, times(1)).wieldImp(); - verifyNoMoreInteractions(weaponImpl); + verify(enchantment, times(1)).onActivate(); + verifyNoMoreInteractions(enchantment); weapon.unwield(); - verify(weaponImpl, times(1)).unwieldImp(); - verifyNoMoreInteractions(weaponImpl); + verify(enchantment, times(1)).onDeactivate(); + verifyNoMoreInteractions(enchantment); } - } diff --git a/pom.xml b/pom.xml index 347a6bc15..06148064f 100644 --- a/pom.xml +++ b/pom.xml @@ -467,6 +467,7 @@ builder prototype adapter + bridge