Work on improved Bridge example

This commit is contained in:
Ilkka Seppälä 2017-08-22 09:11:18 +03:00
parent ed1a0022b9
commit a5ec376089
20 changed files with 129 additions and 612 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

View File

@ -1,157 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<class-diagram version="1.1.8" icons="true" automaticImage="PNG" always-add-relationships="false" generalizations="true"
realizations="true" associations="true" dependencies="false" nesting-relationships="true">
<class id="1" language="java" name="com.iluwatar.bridge.FlyingMagicWeaponImpl" project="bridge"
file="/bridge/src/main/java/com/iluwatar/bridge/FlyingMagicWeaponImpl.java" binary="false" corner="BOTTOM_RIGHT">
<position height="-1" width="-1" x="515" y="591"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<class id="2" language="java" name="com.iluwatar.bridge.SoulEatingMagicWeaponImpl" project="bridge"
file="/bridge/src/main/java/com/iluwatar/bridge/SoulEatingMagicWeaponImpl.java" binary="false" corner="BOTTOM_RIGHT">
<position height="-1" width="-1" x="791" y="605"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<class id="3" language="java" name="com.iluwatar.bridge.Stormbringer" project="bridge"
file="/bridge/src/main/java/com/iluwatar/bridge/Stormbringer.java" binary="false" corner="BOTTOM_RIGHT">
<position height="-1" width="-1" x="791" y="788"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<class id="4" language="java" name="com.iluwatar.bridge.MagicWeaponImpl" project="bridge"
file="/bridge/src/main/java/com/iluwatar/bridge/MagicWeaponImpl.java" binary="false" corner="BOTTOM_RIGHT">
<position height="-1" width="-1" x="791" y="433"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<class id="5" language="java" name="com.iluwatar.bridge.BlindingMagicWeaponImpl" project="bridge"
file="/bridge/src/main/java/com/iluwatar/bridge/BlindingMagicWeaponImpl.java" binary="false" corner="BOTTOM_RIGHT">
<position height="-1" width="-1" x="1105" y="593"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<class id="6" language="java" name="com.iluwatar.bridge.SoulEatingMagicWeapon" project="bridge"
file="/bridge/src/main/java/com/iluwatar/bridge/SoulEatingMagicWeapon.java" binary="false" corner="BOTTOM_RIGHT">
<position height="-1" width="-1" x="380" y="21"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<class id="7" language="java" name="com.iluwatar.bridge.Excalibur" project="bridge"
file="/bridge/src/main/java/com/iluwatar/bridge/Excalibur.java" binary="false" corner="BOTTOM_RIGHT">
<position height="-1" width="-1" x="1105" y="782"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<class id="8" language="java" name="com.iluwatar.bridge.Mjollnir" project="bridge"
file="/bridge/src/main/java/com/iluwatar/bridge/Mjollnir.java" binary="false" corner="BOTTOM_RIGHT">
<position height="-1" width="-1" x="515" y="788"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<class id="9" language="java" name="com.iluwatar.bridge.BlindingMagicWeapon" project="bridge"
file="/bridge/src/main/java/com/iluwatar/bridge/BlindingMagicWeapon.java" binary="false" corner="BOTTOM_RIGHT">
<position height="-1" width="-1" x="791" y="14"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<class id="10" language="java" name="com.iluwatar.bridge.MagicWeapon" project="bridge"
file="/bridge/src/main/java/com/iluwatar/bridge/MagicWeapon.java" binary="false" corner="BOTTOM_RIGHT">
<position height="-1" width="-1" x="791" y="237"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<class id="11" language="java" name="com.iluwatar.bridge.FlyingMagicWeapon" project="bridge"
file="/bridge/src/main/java/com/iluwatar/bridge/FlyingMagicWeapon.java" binary="false" corner="BOTTOM_RIGHT">
<position height="-1" width="-1" x="1144" y="12"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<generalization id="12">
<end type="SOURCE" refId="8"/>
<end type="TARGET" refId="1"/>
</generalization>
<generalization id="13">
<end type="SOURCE" refId="1"/>
<end type="TARGET" refId="4"/>
</generalization>
<generalization id="14">
<end type="SOURCE" refId="9"/>
<end type="TARGET" refId="10"/>
</generalization>
<generalization id="15">
<end type="SOURCE" refId="2"/>
<end type="TARGET" refId="4"/>
</generalization>
<association id="16">
<end type="SOURCE" refId="10" navigable="false">
<attribute id="17" name="imp">
<position height="0" width="0" x="478" y="284"/>
</attribute>
<multiplicity id="18" minimum="0" maximum="1">
<position height="0" width="0" x="478" y="284"/>
</multiplicity>
</end>
<end type="TARGET" refId="4" navigable="true"/>
<display labels="true" multiplicity="true"/>
</association>
<generalization id="19">
<end type="SOURCE" refId="5"/>
<end type="TARGET" refId="4"/>
</generalization>
<generalization id="20">
<end type="SOURCE" refId="6"/>
<end type="TARGET" refId="10"/>
</generalization>
<generalization id="21">
<end type="SOURCE" refId="7"/>
<end type="TARGET" refId="5"/>
</generalization>
<generalization id="22">
<end type="SOURCE" refId="3"/>
<end type="TARGET" refId="2"/>
</generalization>
<generalization id="23">
<end type="SOURCE" refId="11"/>
<end type="TARGET" refId="10"/>
</generalization>
<classifier-display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</classifier-display>
<association-display labels="true" multiplicity="true"/>
</class-diagram>

View File

@ -1,92 +0,0 @@
@startuml
package com.iluwatar.bridge {
class App {
+ App()
+ main(args : String[]) {static}
}
class BlindingMagicWeapon {
+ BlindingMagicWeapon(imp : BlindingMagicWeaponImpl)
+ blind()
+ getImp() : BlindingMagicWeaponImpl
+ swing()
+ unwield()
+ wield()
}
abstract class BlindingMagicWeaponImpl {
+ BlindingMagicWeaponImpl()
+ blindImp() {abstract}
}
class Excalibur {
- LOGGER : Logger {static}
+ Excalibur()
+ blindImp()
+ swingImp()
+ unwieldImp()
+ wieldImp()
}
class FlyingMagicWeapon {
+ FlyingMagicWeapon(imp : FlyingMagicWeaponImpl)
+ fly()
+ getImp() : FlyingMagicWeaponImpl
+ swing()
+ unwield()
+ wield()
}
abstract class FlyingMagicWeaponImpl {
+ FlyingMagicWeaponImpl()
+ flyImp() {abstract}
}
abstract class MagicWeapon {
# imp : MagicWeaponImpl
+ MagicWeapon(imp : MagicWeaponImpl)
+ getImp() : MagicWeaponImpl
+ swing() {abstract}
+ unwield() {abstract}
+ wield() {abstract}
}
abstract class MagicWeaponImpl {
+ MagicWeaponImpl()
+ swingImp() {abstract}
+ unwieldImp() {abstract}
+ wieldImp() {abstract}
}
class Mjollnir {
- LOGGER : Logger {static}
+ Mjollnir()
+ flyImp()
+ swingImp()
+ unwieldImp()
+ wieldImp()
}
class SoulEatingMagicWeapon {
+ SoulEatingMagicWeapon(imp : SoulEatingMagicWeaponImpl)
+ eatSoul()
+ getImp() : SoulEatingMagicWeaponImpl
+ swing()
+ unwield()
+ wield()
}
abstract class SoulEatingMagicWeaponImpl {
+ SoulEatingMagicWeaponImpl()
+ eatSoulImp() {abstract}
}
class Stormbringer {
- LOGGER : Logger {static}
+ Stormbringer()
+ eatSoulImp()
+ swingImp()
+ unwieldImp()
+ wieldImp()
}
}
MagicWeapon --> "-imp" MagicWeaponImpl
BlindingMagicWeapon --|> MagicWeapon
BlindingMagicWeaponImpl --|> MagicWeaponImpl
Excalibur --|> BlindingMagicWeaponImpl
FlyingMagicWeapon --|> MagicWeapon
FlyingMagicWeaponImpl --|> MagicWeaponImpl
Mjollnir --|> FlyingMagicWeaponImpl
SoulEatingMagicWeapon --|> MagicWeapon
SoulEatingMagicWeaponImpl --|> MagicWeaponImpl
Stormbringer --|> SoulEatingMagicWeaponImpl
@enduml

View File

@ -22,40 +22,42 @@
*/ */
package com.iluwatar.bridge; package com.iluwatar.bridge;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* The Bridge pattern can also be thought of as two layers of abstraction. With Bridge, you can * Composition over inheritance. The Bridge pattern can also be thought of as two layers of abstraction.
* decouple an abstraction from its implementation so that the two can vary independently. * With Bridge, you can decouple an abstraction from its implementation so that the two can vary independently.
* <p> * <p>
* In Bridge pattern both abstraction ({@link MagicWeapon}) and implementation ( * In Bridge pattern both abstraction ({@link Weapon}) and implementation (
* {@link MagicWeaponImpl}) have their own class hierarchies. The interface of the implementations * {@link Enchantment}) have their own class hierarchies. The interface of the implementations
* can be changed without affecting the clients. * can be changed without affecting the clients.
* <p>
* 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 { public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/** /**
* Program entry point * Program entry point
* *
* @param args command line args * @param args command line args
*/ */
public static void main(String[] args) { public static void main(String[] args) {
BlindingMagicWeapon blindingMagicWeapon = new BlindingMagicWeapon(new Excalibur()); LOGGER.info("The knight receives an enchanted sword.");
blindingMagicWeapon.wield(); Sword enchantedSword = new Sword(new SoulEatingEnchantment());
blindingMagicWeapon.blind(); enchantedSword.wield();
blindingMagicWeapon.swing(); enchantedSword.swing();
blindingMagicWeapon.unwield(); enchantedSword.unwield();
FlyingMagicWeapon flyingMagicWeapon = new FlyingMagicWeapon(new Mjollnir()); LOGGER.info("The valkyrie receives an enchanted hammer.");
flyingMagicWeapon.wield(); Hammer hammer = new Hammer(new FlyingEnchantment());
flyingMagicWeapon.fly(); hammer.wield();
flyingMagicWeapon.swing(); hammer.swing();
flyingMagicWeapon.unwield(); hammer.unwield();
SoulEatingMagicWeapon soulEatingMagicWeapon = new SoulEatingMagicWeapon(new Stormbringer());
soulEatingMagicWeapon.wield();
soulEatingMagicWeapon.swing();
soulEatingMagicWeapon.eatSoul();
soulEatingMagicWeapon.unwield();
} }
} }

View File

@ -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;
/**
*
* BlindingMagicWeapon
*
*/
public class BlindingMagicWeapon extends MagicWeapon {
public BlindingMagicWeapon(BlindingMagicWeaponImpl imp) {
super(imp);
}
@Override
public BlindingMagicWeaponImpl getImp() {
return (BlindingMagicWeaponImpl) imp;
}
@Override
public void wield() {
getImp().wieldImp();
}
@Override
public void swing() {
getImp().swingImp();
}
@Override
public void unwield() {
getImp().unwieldImp();
}
public void blind() {
getImp().blindImp();
}
}

View File

@ -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();
} }

View File

@ -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 @Override
public void wieldImp() { public void onActivate() {
LOGGER.info("wielding Excalibur"); LOGGER.info("The item begins to glow faintly.");
} }
@Override @Override
public void swingImp() { public void apply() {
LOGGER.info("swinging Excalibur"); LOGGER.info("The item flies and strikes the enemies finally returning to owner's hand.");
} }
@Override @Override
public void unwieldImp() { public void onDeactivate() {
LOGGER.info("unwielding Excalibur"); LOGGER.info("The item's glow fades.");
}
@Override
public void blindImp() {
LOGGER.info("bright light streams from Excalibur blinding the enemy");
} }
} }

View File

@ -22,38 +22,39 @@
*/ */
package com.iluwatar.bridge; package com.iluwatar.bridge;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* FlyingMagicWeapon * Hammer
* *
*/ */
public class FlyingMagicWeapon extends MagicWeapon { public class Hammer implements Weapon {
public FlyingMagicWeapon(FlyingMagicWeaponImpl imp) { private static final Logger LOGGER = LoggerFactory.getLogger(Hammer.class);
super(imp);
}
public FlyingMagicWeaponImpl getImp() { private final Enchantment enchantment;
return (FlyingMagicWeaponImpl) imp;
public Hammer(Enchantment enchantment) {
this.enchantment = enchantment;
} }
@Override @Override
public void wield() { public void wield() {
getImp().wieldImp(); LOGGER.info("The hammer is wielded.");
enchantment.onActivate();
} }
@Override @Override
public void swing() { public void swing() {
getImp().swingImp(); LOGGER.info("The hammer is swinged.");
enchantment.apply();
} }
@Override @Override
public void unwield() { public void unwield() {
getImp().unwieldImp(); LOGGER.info("The hammer is unwielded.");
enchantment.onDeactivate();
} }
public void fly() {
getImp().flyImp();
}
} }

View File

@ -1,47 +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;
/**
*
* MagicWeapon
*
*/
public abstract class MagicWeapon {
protected MagicWeaponImpl imp;
public MagicWeapon(MagicWeaponImpl imp) {
this.imp = imp;
}
public abstract void wield();
public abstract void swing();
public abstract void unwield();
public MagicWeaponImpl getImp() {
return imp;
}
}

View File

@ -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();
}

View File

@ -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");
}
}

View File

@ -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 @Override
public void wieldImp() { public void onActivate() {
LOGGER.info("wielding Stormbringer"); LOGGER.info("The item spreads bloodlust.");
} }
@Override @Override
public void swingImp() { public void apply() {
LOGGER.info("swinging Stormbringer"); LOGGER.info("The item eats the soul of enemies.");
} }
@Override @Override
public void unwieldImp() { public void onDeactivate() {
LOGGER.info("unwielding Stormbringer"); LOGGER.info("Bloodlust slowly disappears.");
}
@Override
public void eatSoulImp() {
LOGGER.info("Stormbringer devours the enemy's soul");
} }
} }

View File

@ -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();
}

View File

@ -22,39 +22,39 @@
*/ */
package com.iluwatar.bridge; 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) { private static final Logger LOGGER = LoggerFactory.getLogger(Sword.class);
super(imp);
}
@Override private final Enchantment enchantment;
public SoulEatingMagicWeaponImpl getImp() {
return (SoulEatingMagicWeaponImpl) imp; public Sword(Enchantment enchantment) {
this.enchantment = enchantment;
} }
@Override @Override
public void wield() { public void wield() {
getImp().wieldImp(); LOGGER.info("The sword is wielded.");
enchantment.onActivate();
} }
@Override @Override
public void swing() { public void swing() {
getImp().swingImp(); LOGGER.info("The sword is swinged.");
enchantment.apply();
} }
@Override @Override
public void unwield() { public void unwield() {
getImp().unwieldImp(); LOGGER.info("The sword is unwielded.");
enchantment.onDeactivate();
} }
public void eatSoul() {
getImp().eatSoulImp();
}
} }

View File

@ -24,11 +24,14 @@ 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();
} }

View File

@ -42,14 +42,14 @@ public class BlindingMagicWeaponTest extends MagicWeaponTest {
*/ */
@Test @Test
public void testExcalibur() throws Exception { public void testExcalibur() throws Exception {
final Excalibur excalibur = spy(new Excalibur()); // final Excalibur excalibur = spy(new Excalibur());
final BlindingMagicWeapon blindingMagicWeapon = new BlindingMagicWeapon(excalibur); // final Hammer blindingMagicWeapon = new Hammer(excalibur);
//
testBasicWeaponActions(blindingMagicWeapon, excalibur); // testBasicWeaponActions(blindingMagicWeapon, excalibur);
//
blindingMagicWeapon.blind(); // blindingMagicWeapon.blind();
verify(excalibur, times(1)).blindImp(); // verify(excalibur, times(1)).blindImp();
verifyNoMoreInteractions(excalibur); // verifyNoMoreInteractions(excalibur);
} }
} }

View File

@ -42,14 +42,14 @@ public class FlyingMagicWeaponTest extends MagicWeaponTest {
*/ */
@Test @Test
public void testMjollnir() throws Exception { public void testMjollnir() throws Exception {
final Mjollnir mjollnir = spy(new Mjollnir()); // final Mjollnir mjollnir = spy(new Mjollnir());
final FlyingMagicWeapon flyingMagicWeapon = new FlyingMagicWeapon(mjollnir); // final FlyingMagicWeapon flyingMagicWeapon = new FlyingMagicWeapon(mjollnir);
//
testBasicWeaponActions(flyingMagicWeapon, mjollnir); // testBasicWeaponActions(flyingMagicWeapon, mjollnir);
//
flyingMagicWeapon.fly(); // flyingMagicWeapon.fly();
verify(mjollnir, times(1)).flyImp(); // verify(mjollnir, times(1)).flyImp();
verifyNoMoreInteractions(mjollnir); // verifyNoMoreInteractions(mjollnir);
} }
} }

View File

@ -41,24 +41,24 @@ public abstract class MagicWeaponTest {
* @param weaponImpl The spied weapon implementation where actions are bridged to * @param weaponImpl The spied weapon implementation where actions are bridged to
* @param weapon The weapon, handled by the app * @param weapon The weapon, handled by the app
*/ */
protected final void testBasicWeaponActions(final MagicWeapon weapon, protected final void testBasicWeaponActions(final Weapon weapon,
final MagicWeaponImpl weaponImpl) { final Enchantment weaponImpl) {
assertNotNull(weapon); // assertNotNull(weapon);
assertNotNull(weaponImpl); // assertNotNull(weaponImpl);
assertNotNull(weapon.getImp()); // assertNotNull(weapon.getEnchantment());
//
weapon.swing(); // weapon.swing();
verify(weaponImpl, times(1)).swingImp(); // verify(weaponImpl, times(1)).swingImp();
verifyNoMoreInteractions(weaponImpl); // verifyNoMoreInteractions(weaponImpl);
//
weapon.wield(); // weapon.wield();
verify(weaponImpl, times(1)).wieldImp(); // verify(weaponImpl, times(1)).wieldImp();
verifyNoMoreInteractions(weaponImpl); // verifyNoMoreInteractions(weaponImpl);
//
weapon.unwield(); // weapon.unwield();
verify(weaponImpl, times(1)).unwieldImp(); // verify(weaponImpl, times(1)).unwieldImp();
verifyNoMoreInteractions(weaponImpl); // verifyNoMoreInteractions(weaponImpl);
//
} }
} }

View File

@ -42,14 +42,14 @@ public class SoulEatingMagicWeaponTest extends MagicWeaponTest {
*/ */
@Test @Test
public void testStormBringer() throws Exception { public void testStormBringer() throws Exception {
final Stormbringer stormbringer = spy(new Stormbringer()); // final Stormbringer stormbringer = spy(new Stormbringer());
final SoulEatingMagicWeapon soulEatingMagicWeapon = new SoulEatingMagicWeapon(stormbringer); // final Sword soulEatingMagicWeapon = new Sword(stormbringer);
//
testBasicWeaponActions(soulEatingMagicWeapon, stormbringer); // testBasicWeaponActions(soulEatingMagicWeapon, stormbringer);
//
soulEatingMagicWeapon.eatSoul(); // soulEatingMagicWeapon.eatSoul();
verify(stormbringer, times(1)).eatSoulImp(); // verify(stormbringer, times(1)).eatSoulImp();
verifyNoMoreInteractions(stormbringer); // verifyNoMoreInteractions(stormbringer);
} }
} }

View File

@ -467,6 +467,7 @@
<param>builder</param> <param>builder</param>
<param>prototype</param> <param>prototype</param>
<param>adapter</param> <param>adapter</param>
<param>bridge</param>
</skipForProjects> </skipForProjects>
</configuration> </configuration>
</plugin> </plugin>