diff --git a/adapter/etc/adapter.png b/adapter/etc/adapter.png index 511bb5880..f43358b04 100644 Binary files a/adapter/etc/adapter.png and b/adapter/etc/adapter.png differ diff --git a/adapter/etc/adapter.ucls b/adapter/etc/adapter.ucls index 8c09f0399..290ff544e 100644 --- a/adapter/etc/adapter.ucls +++ b/adapter/etc/adapter.ucls @@ -1,61 +1,61 @@ - - - + + + - - + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + + - - - - - - - - + + + + - + + + + + - - + + diff --git a/adapter/etc/adapter_1.png b/adapter/etc/adapter_1.png deleted file mode 100644 index 64eb34b84..000000000 Binary files a/adapter/etc/adapter_1.png and /dev/null differ diff --git a/adapter/index.md b/adapter/index.md index 36a2a0ad3..7c7dc15e5 100644 --- a/adapter/index.md +++ b/adapter/index.md @@ -15,7 +15,7 @@ tags: expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces. -![alt text](./etc/adapter_1.png "Adapter") +![alt text](./etc/adapter.png "Adapter") **Applicability:** Use the Adapter pattern when diff --git a/adapter/src/main/java/com/iluwatar/adapter/App.java b/adapter/src/main/java/com/iluwatar/adapter/App.java index d2353eec4..c33780198 100644 --- a/adapter/src/main/java/com/iluwatar/adapter/App.java +++ b/adapter/src/main/java/com/iluwatar/adapter/App.java @@ -1,28 +1,43 @@ package com.iluwatar.adapter; /** - * An adapter helps two incompatible interfaces to work together. This is the real world definition - * for an adapter. Interfaces may be incompatible but the inner functionality should suit the need. - * The Adapter design pattern allows otherwise incompatible classes to work together by converting - * the interface of one class into an interface expected by the clients. + * An adapter helps two incompatible interfaces to work together. This is the + * real world definition for an adapter. Interfaces may be incompatible but the + * inner functionality should suit the need. The Adapter design pattern allows + * otherwise incompatible classes to work together by converting the interface + * of one class into an interface expected by the clients. * - *

There are two variations of the Adapter pattern: The class adapter implements the adaptee's - * interface whereas the object adapter uses composition to contain the adaptee in the adapter - * object. This example uses the object adapter approach. + *

+ * There are two variations of the Adapter pattern: The class adapter implements + * the adaptee's interface whereas the object adapter uses composition to + * contain the adaptee in the adapter object. This example uses the object + * adapter approach. + * + *

+ * The Adapter ({@link BattleFishingBoat}) converts the interface of the adaptee + * class ( {@link FishingBoat}) into a suitable one expected by the client ( + * {@link BattleShip} ). + * + *

+ * The story of this implementation is this.
+ * Pirates are coming! we need a {@link BattleShip} to fight! We have a + * {@link FishingBoat} and our captain. We have no time to make up a new ship! + * we need to reuse this {@link FishingBoat}. The captain needs a battleship + * which can fire and move. The spec is in {@link BattleShip}. We will use the + * Adapter pattern to reuse {@link FishingBoat}. * - *

The Adapter ({@link GnomeEngineer}) converts the interface of the target class ( - * {@link GoblinGlider}) into a suitable one expected by the client ({@link GnomeEngineeringManager} - * ). */ public class App { - /** - * Program entry point. - * - * @param args command line args - */ - public static void main(String[] args) { - Engineer manager = new GnomeEngineeringManager(new GnomeEngineer()); - manager.operateDevice(); - } + /** + * Program entry point. + * + * @param args + * command line args + */ + public static void main(String[] args) { + Captain captain = new Captain(new BattleFishingBoat()); + captain.move(); + captain.fire(); + } } diff --git a/adapter/src/main/java/com/iluwatar/adapter/Engineer.java b/adapter/src/main/java/com/iluwatar/adapter/Engineer.java deleted file mode 100644 index a973cb530..000000000 --- a/adapter/src/main/java/com/iluwatar/adapter/Engineer.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.iluwatar.adapter; - -/** - * - * Engineers can operate devices. - * - */ -public interface Engineer { - - void operateDevice(); -} diff --git a/adapter/src/main/java/com/iluwatar/adapter/GnomeEngineer.java b/adapter/src/main/java/com/iluwatar/adapter/GnomeEngineer.java deleted file mode 100644 index 70e166ac3..000000000 --- a/adapter/src/main/java/com/iluwatar/adapter/GnomeEngineer.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.iluwatar.adapter; - -/** - * - * Adapter class. Adapts the interface of the device ({@link GoblinGlider}) into {@link Engineer} - * interface expected by the client ({@link GnomeEngineeringManager}). - * - */ -public class GnomeEngineer implements Engineer { - - private GoblinGlider glider; - - public GnomeEngineer() { - glider = new GoblinGlider(); - } - - @Override - public void operateDevice() { - glider.attachGlider(); - glider.gainSpeed(); - glider.takeOff(); - } -} diff --git a/adapter/src/main/java/com/iluwatar/adapter/GnomeEngineeringManager.java b/adapter/src/main/java/com/iluwatar/adapter/GnomeEngineeringManager.java deleted file mode 100644 index ff4ddb617..000000000 --- a/adapter/src/main/java/com/iluwatar/adapter/GnomeEngineeringManager.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.iluwatar.adapter; - -/** - * GnomeEngineering manager uses {@link Engineer} to operate devices. - */ -public class GnomeEngineeringManager implements Engineer { - - private Engineer engineer; - - public GnomeEngineeringManager() { - - } - - public GnomeEngineeringManager(Engineer engineer) { - this.engineer = engineer; - } - - @Override - public void operateDevice() { - engineer.operateDevice(); - } - - public void setEngineer(Engineer engineer) { - this.engineer = engineer; - } -} diff --git a/adapter/src/main/java/com/iluwatar/adapter/GoblinGlider.java b/adapter/src/main/java/com/iluwatar/adapter/GoblinGlider.java deleted file mode 100644 index 79a9acef6..000000000 --- a/adapter/src/main/java/com/iluwatar/adapter/GoblinGlider.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.iluwatar.adapter; - -/** - * - * Device class (adaptee in the pattern). - * - */ -public class GoblinGlider { - - public void attachGlider() { - System.out.println("Glider attached."); - } - - public void gainSpeed() { - System.out.println("Gaining speed."); - } - - public void takeOff() { - System.out.println("Lift-off!"); - } -} diff --git a/adapter/src/test/java/com/iluwatar/adapter/AdapterPatternTest.java b/adapter/src/test/java/com/iluwatar/adapter/AdapterPatternTest.java index 866bfb968..c9a1a9bca 100644 --- a/adapter/src/test/java/com/iluwatar/adapter/AdapterPatternTest.java +++ b/adapter/src/test/java/com/iluwatar/adapter/AdapterPatternTest.java @@ -9,60 +9,83 @@ import java.util.Map; import org.junit.Before; import org.junit.Test; +import com.iluwatar.adapter.BattleFishingBoat; +import com.iluwatar.adapter.BattleShip; +import com.iluwatar.adapter.Captain; +import com.iluwatar.adapter.FishingBoat; + /** - * An adapter helps two incompatible interfaces to work together. This is the real world definition - * for an adapter. Interfaces may be incompatible but the inner functionality should suit the need. - * The Adapter design pattern allows otherwise incompatible classes to work together by converting - * the interface of one class into an interface expected by the clients. + * An adapter helps two incompatible interfaces to work together. This is the + * real world definition for an adapter. Interfaces may be incompatible but the + * inner functionality should suit the need. The Adapter design pattern allows + * otherwise incompatible classes to work together by converting the interface + * of one class into an interface expected by the clients. * - *

There are two variations of the Adapter pattern: - * The class adapter implements the adaptee's - * interface whereas the object adapter uses composition to contain the adaptee in the adapter - * object. This example uses the object adapter approach. + *

+ * There are two variations of the Adapter pattern: The class adapter implements + * the adaptee's interface whereas the object adapter uses composition to + * contain the adaptee in the adapter object. This example uses the object + * adapter approach. + * + *

+ * The Adapter ({@link BattleFishingBoat}) converts the interface of the adaptee + * class ( {@link FishingBoat}) into a suitable one expected by the client ( + * {@link BattleShip} ). + * + *

+ * The story of this implementation is this.
+ * Pirates are coming! we need a {@link BattleShip} to fight! We have a + * {@link FishingBoat} and our captain. We have no time to make up a new ship! + * we need to reuse this {@link FishingBoat}. The captain needs a battleship + * which can fire and move. The spec is in {@link BattleShip}. We will use the + * Adapter pattern to reuse {@link FishingBoat} which operates properly * - *

The Adapter ({@link GnomeEngineer}) converts the interface - * of the target class ({@link GoblinGlider}) into a suitable one expected by - * the client ({@link GnomeEngineeringManager} - * ). */ public class AdapterPatternTest { - private Map beans; + private Map beans; - private static final String ENGINEER_BEAN = "engineer"; + private static final String BATTLESHIP_BEAN = "engineer"; - private static final String MANAGER_BEAN = "manager"; + private static final String CAPTAIN_BEAN = "captain"; - /** - * This method runs before the test execution and sets the bean objects in the beans Map. - */ - @Before - public void setup() { - beans = new HashMap<>(); + /** + * This method runs before the test execution and sets the bean objects in + * the beans Map. + */ + @Before + public void setup() { + beans = new HashMap<>(); - GnomeEngineer gnomeEngineer = spy(new GnomeEngineer()); - beans.put(ENGINEER_BEAN, gnomeEngineer); + BattleFishingBoat battleFishingBoat = spy(new BattleFishingBoat()); + beans.put(BATTLESHIP_BEAN, battleFishingBoat); - GnomeEngineeringManager manager = new GnomeEngineeringManager(); - manager.setEngineer((GnomeEngineer) beans.get(ENGINEER_BEAN)); - beans.put(MANAGER_BEAN, manager); - } + Captain captain = new Captain(); + captain.setBattleship((BattleFishingBoat) beans.get(BATTLESHIP_BEAN)); + beans.put(CAPTAIN_BEAN, captain); + } - /** - * This test asserts that when we call operateDevice() method on a manager bean, it is internally - * calling operateDevice method on the engineer object. The Adapter ({@link GnomeEngineer}) - * converts the interface of the target class ( {@link GoblinGlider}) into a suitable one expected - * by the client ({@link GnomeEngineeringManager} ). - */ - @Test - public void testAdapter() { - Engineer manager = (Engineer) beans.get(MANAGER_BEAN); + /** + * This test asserts that when we use the move() method on a captain + * bean(client), it is internally calling move method on the battleship + * object. The Adapter ({@link BattleFishingBoat}) converts the interface of + * the target class ( {@link FishingBoat}) into a suitable one expected by + * the client ({@link Captain} ). + */ + @Test + public void testAdapter() { + BattleShip captain = (BattleShip) beans.get(CAPTAIN_BEAN); - // when manager is asked to operate device - manager.operateDevice(); + // when captain moves + captain.move(); - // Manager internally calls the engineer object to operateDevice - Engineer engineer = (Engineer) beans.get(ENGINEER_BEAN); - verify(engineer).operateDevice(); - } + // the captain internally calls the battleship object to move + BattleShip battleship = (BattleShip) beans.get(BATTLESHIP_BEAN); + verify(battleship).move(); + + // same with above with firing + captain.fire(); + verify(battleship).fire(); + + } }