Merge pull request #309 from JuhoKang/adapterdev
Attempt to solve issue #292
This commit is contained in:
commit
e85308fbc4
Binary file not shown.
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
@ -1,61 +1,61 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<class-diagram version="1.1.8" icons="true" automaticImage="PNG" always-add-relationships="false" generalizations="true"
|
<class-diagram version="1.1.9" icons="true" always-add-relationships="false" generalizations="true" realizations="true"
|
||||||
realizations="true" associations="true" dependencies="false" nesting-relationships="true">
|
associations="true" dependencies="false" nesting-relationships="true" router="FAN">
|
||||||
<class id="1" language="java" name="com.iluwatar.adapter.GnomeEngineeringManager" project="adapter"
|
<class id="1" language="java" name="com.iluwatar.adapter.FishingBoat" project="adapter"
|
||||||
file="/adapter/src/main/java/com/iluwatar/adapter/GnomeEngineeringManager.java" binary="false" corner="BOTTOM_RIGHT">
|
file="/adapter/src/main/java/com/iluwatar/adapter/FishingBoat.java" binary="false" corner="BOTTOM_RIGHT">
|
||||||
<position height="106" width="224" x="110" y="210"/>
|
<position height="-1" width="-1" x="656" y="355"/>
|
||||||
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
|
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
|
||||||
sort-features="false" accessors="true" visibility="true">
|
sort-features="false" accessors="true" visibility="true">
|
||||||
<attributes public="true" package="true" protected="true" private="true" static="true"/>
|
<attributes public="true" package="true" protected="true" private="true" static="true"/>
|
||||||
<operations public="true" package="true" protected="true" private="true" static="true"/>
|
<operations public="true" package="true" protected="true" private="true" static="true"/>
|
||||||
</display>
|
</display>
|
||||||
</class>
|
</class>
|
||||||
<interface id="2" language="java" name="com.iluwatar.adapter.Engineer" project="adapter"
|
<class id="2" language="java" name="com.iluwatar.adapter.Captain" project="adapter"
|
||||||
file="/adapter/src/main/java/com/iluwatar/adapter/Engineer.java" binary="false" corner="BOTTOM_RIGHT">
|
file="/adapter/src/main/java/com/iluwatar/adapter/Captain.java" binary="false" corner="BOTTOM_RIGHT">
|
||||||
<position height="88" width="141" x="110" y="356"/>
|
<position height="-1" width="-1" x="228" y="185"/>
|
||||||
|
<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.adapter.BattleFishingBoat" project="adapter"
|
||||||
|
file="/adapter/src/main/java/com/iluwatar/adapter/BattleFishingBoat.java" binary="false" corner="BOTTOM_RIGHT">
|
||||||
|
<position height="-1" width="-1" x="463" y="357"/>
|
||||||
|
<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>
|
||||||
|
<interface id="4" language="java" name="com.iluwatar.adapter.BattleShip" project="adapter"
|
||||||
|
file="/adapter/src/main/java/com/iluwatar/adapter/BattleShip.java" binary="false" corner="BOTTOM_RIGHT">
|
||||||
|
<position height="-1" width="-1" x="466" y="170"/>
|
||||||
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
|
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
|
||||||
sort-features="false" accessors="true" visibility="true">
|
sort-features="false" accessors="true" visibility="true">
|
||||||
<attributes public="true" package="true" protected="true" private="true" static="true"/>
|
<attributes public="true" package="true" protected="true" private="true" static="true"/>
|
||||||
<operations public="true" package="true" protected="true" private="true" static="true"/>
|
<operations public="true" package="true" protected="true" private="true" static="true"/>
|
||||||
</display>
|
</display>
|
||||||
</interface>
|
</interface>
|
||||||
<class id="3" language="java" name="com.iluwatar.adapter.GnomeEngineer" project="adapter"
|
|
||||||
file="/adapter/src/main/java/com/iluwatar/adapter/GnomeEngineer.java" binary="false" corner="BOTTOM_RIGHT">
|
|
||||||
<position height="106" width="141" x="374" y="210"/>
|
|
||||||
<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.adapter.GoblinGlider" project="adapter"
|
|
||||||
file="/adapter/src/main/java/com/iluwatar/adapter/GoblinGlider.java" binary="false" corner="BOTTOM_RIGHT">
|
|
||||||
<position height="142" width="130" x="374" y="356"/>
|
|
||||||
<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>
|
|
||||||
<realization id="5">
|
<realization id="5">
|
||||||
<end type="SOURCE" refId="1"/>
|
<end type="SOURCE" refId="2"/>
|
||||||
<end type="TARGET" refId="2"/>
|
<end type="TARGET" refId="4"/>
|
||||||
</realization>
|
</realization>
|
||||||
<realization id="6">
|
<association id="6">
|
||||||
<end type="SOURCE" refId="3"/>
|
<end type="SOURCE" refId="3" navigable="false">
|
||||||
<end type="TARGET" refId="2"/>
|
<attribute id="7" name="boat"/>
|
||||||
</realization>
|
<multiplicity id="8" minimum="0" maximum="1"/>
|
||||||
<association id="7">
|
|
||||||
<end type="SOURCE" refId="1" navigable="false">
|
|
||||||
<attribute id="8" name="engineer"/>
|
|
||||||
<multiplicity id="9" minimum="0" maximum="1"/>
|
|
||||||
</end>
|
</end>
|
||||||
<end type="TARGET" refId="2" navigable="true"/>
|
<end type="TARGET" refId="1" navigable="true"/>
|
||||||
<display labels="true" multiplicity="true"/>
|
<display labels="true" multiplicity="true"/>
|
||||||
</association>
|
</association>
|
||||||
|
<realization id="9">
|
||||||
|
<end type="SOURCE" refId="3"/>
|
||||||
|
<end type="TARGET" refId="4"/>
|
||||||
|
</realization>
|
||||||
<association id="10">
|
<association id="10">
|
||||||
<end type="SOURCE" refId="3" navigable="false">
|
<end type="SOURCE" refId="2" navigable="false">
|
||||||
<attribute id="11" name="glider"/>
|
<attribute id="11" name="battleship"/>
|
||||||
<multiplicity id="12" minimum="0" maximum="1"/>
|
<multiplicity id="12" minimum="0" maximum="1"/>
|
||||||
</end>
|
</end>
|
||||||
<end type="TARGET" refId="4" navigable="true"/>
|
<end type="TARGET" refId="4" navigable="true"/>
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 29 KiB |
@ -15,7 +15,7 @@ tags:
|
|||||||
expect. Adapter lets classes work together that couldn't otherwise because of
|
expect. Adapter lets classes work together that couldn't otherwise because of
|
||||||
incompatible interfaces.
|
incompatible interfaces.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
**Applicability:** Use the Adapter pattern when
|
**Applicability:** Use the Adapter pattern when
|
||||||
|
|
||||||
|
@ -6,13 +6,22 @@ package com.iluwatar.adapter;
|
|||||||
* The Adapter design pattern allows otherwise incompatible classes to work together by converting
|
* 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.
|
* the interface of one class into an interface expected by the clients.
|
||||||
*
|
*
|
||||||
* <p>There are two variations of the Adapter pattern: The class adapter implements the adaptee's
|
* <p>
|
||||||
|
* 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
|
* interface whereas the object adapter uses composition to contain the adaptee in the adapter
|
||||||
* object. This example uses the object adapter approach.
|
* object. This example uses the object adapter approach.
|
||||||
*
|
*
|
||||||
* <p>The Adapter ({@link GnomeEngineer}) converts the interface of the target class (
|
* <p>
|
||||||
* {@link GoblinGlider}) into a suitable one expected by the client ({@link GnomeEngineeringManager}
|
* The Adapter ({@link BattleFishingBoat}) converts the interface of the adaptee class (
|
||||||
* ).
|
* {@link FishingBoat}) into a suitable one expected by the client ( {@link BattleShip} ).
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* The story of this implementation is this. <br>
|
||||||
|
* 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}.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
public class App {
|
public class App {
|
||||||
|
|
||||||
@ -22,7 +31,8 @@ public class App {
|
|||||||
* @param args command line args
|
* @param args command line args
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
Engineer manager = new GnomeEngineeringManager(new GnomeEngineer());
|
Captain captain = new Captain(new BattleFishingBoat());
|
||||||
manager.operateDevice();
|
captain.move();
|
||||||
|
captain.fire();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
package com.iluwatar.adapter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Adapter class. Adapts the interface of the device ({@link FishingBoat}) into {@link BattleShip}
|
||||||
|
* interface expected by the client ({@link Captain}). <br>
|
||||||
|
* In this case we added a new function fire to suit the interface. We are reusing the
|
||||||
|
* {@link FishingBoat} without changing itself. The Adapter class can just map the functions of the
|
||||||
|
* Adaptee or add, delete features of the Adaptee.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class BattleFishingBoat implements BattleShip {
|
||||||
|
|
||||||
|
private FishingBoat boat;
|
||||||
|
|
||||||
|
public BattleFishingBoat() {
|
||||||
|
boat = new FishingBoat();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fire() {
|
||||||
|
System.out.println("fire!");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void move() {
|
||||||
|
boat.sail();
|
||||||
|
}
|
||||||
|
}
|
14
adapter/src/main/java/com/iluwatar/adapter/BattleShip.java
Normal file
14
adapter/src/main/java/com/iluwatar/adapter/BattleShip.java
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package com.iluwatar.adapter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The interface expected by the client.<br>
|
||||||
|
* A Battleship can fire and move.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface BattleShip {
|
||||||
|
|
||||||
|
void fire();
|
||||||
|
|
||||||
|
void move();
|
||||||
|
|
||||||
|
}
|
33
adapter/src/main/java/com/iluwatar/adapter/Captain.java
Normal file
33
adapter/src/main/java/com/iluwatar/adapter/Captain.java
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
package com.iluwatar.adapter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Captain uses {@link BattleShip} to fight. <br>
|
||||||
|
* This is the client in the pattern.
|
||||||
|
*/
|
||||||
|
public class Captain implements BattleShip {
|
||||||
|
|
||||||
|
private BattleShip battleship;
|
||||||
|
|
||||||
|
public Captain() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Captain(BattleShip battleship) {
|
||||||
|
this.battleship = battleship;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBattleship(BattleShip battleship) {
|
||||||
|
this.battleship = battleship;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fire() {
|
||||||
|
battleship.fire();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void move() {
|
||||||
|
battleship.move();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,11 +0,0 @@
|
|||||||
package com.iluwatar.adapter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Engineers can operate devices.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public interface Engineer {
|
|
||||||
|
|
||||||
void operateDevice();
|
|
||||||
}
|
|
18
adapter/src/main/java/com/iluwatar/adapter/FishingBoat.java
Normal file
18
adapter/src/main/java/com/iluwatar/adapter/FishingBoat.java
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package com.iluwatar.adapter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Device class (adaptee in the pattern). We want to reuse this class
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class FishingBoat {
|
||||||
|
|
||||||
|
public void sail() {
|
||||||
|
System.out.println("The Boat is moving to that place");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fish() {
|
||||||
|
System.out.println("fishing ...");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -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!");
|
|
||||||
}
|
|
||||||
}
|
|
@ -9,29 +9,22 @@ import java.util.Map;
|
|||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
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
|
* Test class
|
||||||
* 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.
|
|
||||||
*
|
*
|
||||||
* <p>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.
|
|
||||||
*
|
|
||||||
* <p>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 {
|
public class AdapterPatternTest {
|
||||||
|
|
||||||
private Map<String, Object> beans;
|
private Map<String, Object> 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.
|
* This method runs before the test execution and sets the bean objects in the beans Map.
|
||||||
@ -40,29 +33,34 @@ public class AdapterPatternTest {
|
|||||||
public void setup() {
|
public void setup() {
|
||||||
beans = new HashMap<>();
|
beans = new HashMap<>();
|
||||||
|
|
||||||
GnomeEngineer gnomeEngineer = spy(new GnomeEngineer());
|
BattleFishingBoat battleFishingBoat = spy(new BattleFishingBoat());
|
||||||
beans.put(ENGINEER_BEAN, gnomeEngineer);
|
beans.put(BATTLESHIP_BEAN, battleFishingBoat);
|
||||||
|
|
||||||
GnomeEngineeringManager manager = new GnomeEngineeringManager();
|
Captain captain = new Captain();
|
||||||
manager.setEngineer((GnomeEngineer) beans.get(ENGINEER_BEAN));
|
captain.setBattleship((BattleFishingBoat) beans.get(BATTLESHIP_BEAN));
|
||||||
beans.put(MANAGER_BEAN, manager);
|
beans.put(CAPTAIN_BEAN, captain);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This test asserts that when we call operateDevice() method on a manager bean, it is internally
|
* This test asserts that when we use the move() method on a captain bean(client), it is
|
||||||
* calling operateDevice method on the engineer object. The Adapter ({@link GnomeEngineer})
|
* internally calling move method on the battleship object. The Adapter ({@link BattleFishingBoat}
|
||||||
* converts the interface of the target class ( {@link GoblinGlider}) into a suitable one expected
|
* ) converts the interface of the target class ( {@link FishingBoat}) into a suitable one
|
||||||
* by the client ({@link GnomeEngineeringManager} ).
|
* expected by the client ({@link Captain} ).
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testAdapter() {
|
public void testAdapter() {
|
||||||
Engineer manager = (Engineer) beans.get(MANAGER_BEAN);
|
BattleShip captain = (BattleShip) beans.get(CAPTAIN_BEAN);
|
||||||
|
|
||||||
// when manager is asked to operate device
|
// when captain moves
|
||||||
manager.operateDevice();
|
captain.move();
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
|
||||||
// Manager internally calls the engineer object to operateDevice
|
|
||||||
Engineer engineer = (Engineer) beans.get(ENGINEER_BEAN);
|
|
||||||
verify(engineer).operateDevice();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user