Skip to content

Commit fbf5ffe

Browse files
committed
iluwatar#590 Add explanation for Adapter
1 parent f47dc1e commit fbf5ffe

File tree

11 files changed

+121
-176
lines changed

11 files changed

+121
-176
lines changed

adapter/README.md

Lines changed: 79 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,93 @@ Convert the interface of a class into another interface the clients
1919
expect. Adapter lets classes work together that couldn't otherwise because of
2020
incompatible interfaces.
2121

22-
![alt text](./etc/adapter.png "Adapter")
22+
## Explanation
2323

24-
## General usage of Adapter Pattern:
25-
+ Wrappers used to adopt 3rd parties libraries and frameworks - most of the applications using third party libraries use adapters as a middle layer between the application and the 3rd party library to decouple the application from the library. If another library has to be used only an adapter for the new library is required without having to change the application code.
24+
Real world example
25+
26+
> Consider that you have some pictures in your memory card and you need to transfer them to your computer. In order to transfer them you need some kind of adapter that is compatible with your computer ports so that you can attach memory card to your computer. In this case card reader is an adapter.
27+
> Another example would be the famous power adapter; a three legged plug can't be connected to a two pronged outlet, it needs to use a power adapter that makes it compatible with the two pronged outlet.
28+
> Yet another example would be a translator translating words spoken by one person to another
29+
30+
In plain words
31+
32+
> Adapter pattern lets you wrap an otherwise incompatible object in an adapter to make it compatible with another class.
33+
34+
Wikipedia says
35+
36+
> In software engineering, the adapter pattern is a software design pattern that allows the interface of an existing class to be used as another interface. It is often used to make existing classes work with others without modifying their source code.
37+
38+
**Programmatic Example**
39+
40+
Consider a captain that can only use rowing boats and cannot sail at all.
41+
42+
First we have interfaces `RowingBoat` and `FishingBoat`
43+
44+
```
45+
public interface RowingBoat {
46+
void row();
47+
}
48+
49+
public class FishingBoat {
50+
private static final Logger LOGGER = LoggerFactory.getLogger(FishingBoat.class);
51+
public void sail() {
52+
LOGGER.info("The fishing boat is sailing");
53+
}
54+
}
55+
```
56+
57+
And captain expects an implementation of `RowingBoat` interface to be able to move
58+
59+
```
60+
public class Captain implements RowingBoat {
61+
62+
private RowingBoat rowingBoat;
63+
64+
public Captain(RowingBoat rowingBoat) {
65+
this.rowingBoat = rowingBoat;
66+
}
67+
68+
@Override
69+
public void row() {
70+
rowingBoat.row();
71+
}
72+
}
73+
```
74+
75+
Now let's say the pirates are coming and our captain needs to escape but there is only fishing boat available. We need to create an adapter that allows the captain to operate the fishing boat with his rowing boat skills.
76+
77+
```
78+
public class FishingBoatAdapter implements RowingBoat {
79+
80+
private static final Logger LOGGER = LoggerFactory.getLogger(FishingBoatAdapter.class);
81+
82+
private FishingBoat boat;
83+
84+
public FishingBoatAdapter() {
85+
boat = new FishingBoat();
86+
}
87+
88+
@Override
89+
public void row() {
90+
boat.sail();
91+
}
92+
}
93+
```
94+
95+
And now the `Captain` can use the `FishingBoat` to escape the pirates.
96+
97+
```
98+
Captain captain = new Captain(new FishingBoatAdapter());
99+
captain.row();
100+
```
26101

27102
## Applicability
28103
Use the Adapter pattern when
29104

30105
* you want to use an existing class, and its interface does not match the one you need
31106
* you want to create a reusable class that cooperates with unrelated or unforeseen classes, that is, classes that don't necessarily have compatible interfaces
32107
* you need to use several existing subclasses, but it's impractical to adapt their interface by subclassing every one. An object adapter can adapt the interface of its parent class.
108+
* most of the applications using third party libraries use adapters as a middle layer between the application and the 3rd party library to decouple the application from the library. If another library has to be used only an adapter for the new library is required without having to change the application code.
33109

34110
## Consequences:
35111
Class and object adapters have different trade-offs. A class adapter

adapter/etc/adapter.png

-11.8 KB
Binary file not shown.

adapter/etc/adapter.ucls

Lines changed: 0 additions & 70 deletions
This file was deleted.

adapter/etc/adapter.urm.puml

Lines changed: 0 additions & 37 deletions
This file was deleted.

adapter/src/main/java/com/iluwatar/adapter/App.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,14 @@
3434
* object. This example uses the object adapter approach.
3535
*
3636
* <p>
37-
* The Adapter ({@link BattleFishingBoat}) converts the interface of the adaptee class (
38-
* {@link FishingBoat}) into a suitable one expected by the client ( {@link BattleShip} ).
37+
* The Adapter ({@link FishingBoatAdapter}) converts the interface of the adaptee class (
38+
* {@link FishingBoat}) into a suitable one expected by the client ( {@link RowingBoat} ).
3939
*
4040
* <p>
4141
* The story of this implementation is this. <br>
42-
* Pirates are coming! we need a {@link BattleShip} to fight! We have a {@link FishingBoat} and our
42+
* Pirates are coming! we need a {@link RowingBoat} to flee! We have a {@link FishingBoat} and our
4343
* captain. We have no time to make up a new ship! we need to reuse this {@link FishingBoat}. The
44-
* captain needs a battleship which can fire and move. The spec is in {@link BattleShip}. We will
44+
* captain needs a rowing boat which he can operate. The spec is in {@link RowingBoat}. We will
4545
* use the Adapter pattern to reuse {@link FishingBoat}.
4646
*
4747
*/
@@ -53,8 +53,8 @@ public class App {
5353
* @param args command line args
5454
*/
5555
public static void main(String[] args) {
56-
Captain captain = new Captain(new BattleFishingBoat());
57-
captain.move();
58-
captain.fire();
56+
// The captain can only operate rowing boats but with adapter he is able to use fishing boats as well
57+
Captain captain = new Captain(new FishingBoatAdapter());
58+
captain.row();
5959
}
6060
}

adapter/src/main/java/com/iluwatar/adapter/Captain.java

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,33 +23,26 @@
2323
package com.iluwatar.adapter;
2424

2525
/**
26-
* The Captain uses {@link BattleShip} to fight. <br>
26+
* The Captain uses {@link RowingBoat} to sail. <br>
2727
* This is the client in the pattern.
2828
*/
29-
public class Captain implements BattleShip {
29+
public class Captain implements RowingBoat {
3030

31-
private BattleShip battleship;
31+
private RowingBoat rowingBoat;
3232

33-
public Captain() {
33+
public Captain() {}
3434

35+
public Captain(RowingBoat rowingBoat) {
36+
this.rowingBoat = rowingBoat;
3537
}
3638

37-
public Captain(BattleShip battleship) {
38-
this.battleship = battleship;
39-
}
40-
41-
public void setBattleship(BattleShip battleship) {
42-
this.battleship = battleship;
43-
}
44-
45-
@Override
46-
public void fire() {
47-
battleship.fire();
39+
public void setRowingBoat(RowingBoat rowingBoat) {
40+
this.rowingBoat = rowingBoat;
4841
}
4942

5043
@Override
51-
public void move() {
52-
battleship.move();
44+
public void row() {
45+
rowingBoat.row();
5346
}
5447

5548
}

adapter/src/main/java/com/iluwatar/adapter/FishingBoat.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,16 @@
2727

2828
/**
2929
*
30-
* Device class (adaptee in the pattern). We want to reuse this class
30+
* Device class (adaptee in the pattern). We want to reuse this class.
31+
* Fishing boat moves by sailing.
3132
*
3233
*/
3334
public class FishingBoat {
3435

3536
private static final Logger LOGGER = LoggerFactory.getLogger(FishingBoat.class);
3637

3738
public void sail() {
38-
LOGGER.info("The Boat is moving to that place");
39-
}
40-
41-
public void fish() {
42-
LOGGER.info("fishing ...");
39+
LOGGER.info("The fishing boat is sailing");
4340
}
4441

4542
}

adapter/src/main/java/com/iluwatar/adapter/BattleFishingBoat.java renamed to adapter/src/main/java/com/iluwatar/adapter/FishingBoatAdapter.java

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,30 +27,22 @@
2727

2828
/**
2929
*
30-
* Adapter class. Adapts the interface of the device ({@link FishingBoat}) into {@link BattleShip}
31-
* interface expected by the client ({@link Captain}). <br>
32-
* In this case we added a new function fire to suit the interface. We are reusing the
33-
* {@link FishingBoat} without changing itself. The Adapter class can just map the functions of the
34-
* Adaptee or add, delete features of the Adaptee.
30+
* Adapter class. Adapts the interface of the device ({@link FishingBoat}) into {@link RowingBoat}
31+
* interface expected by the client ({@link Captain}).
3532
*
3633
*/
37-
public class BattleFishingBoat implements BattleShip {
34+
public class FishingBoatAdapter implements RowingBoat {
3835

39-
private static final Logger LOGGER = LoggerFactory.getLogger(BattleFishingBoat.class);
36+
private static final Logger LOGGER = LoggerFactory.getLogger(FishingBoatAdapter.class);
4037

4138
private FishingBoat boat;
4239

43-
public BattleFishingBoat() {
40+
public FishingBoatAdapter() {
4441
boat = new FishingBoat();
4542
}
4643

4744
@Override
48-
public void fire() {
49-
LOGGER.info("fire!");
50-
}
51-
52-
@Override
53-
public void move() {
45+
public void row() {
5446
boat.sail();
5547
}
5648
}

adapter/src/main/java/com/iluwatar/adapter/BattleShip.java renamed to adapter/src/main/java/com/iluwatar/adapter/RowingBoat.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,11 @@
2424

2525
/**
2626
* The interface expected by the client.<br>
27-
* A Battleship can fire and move.
27+
* A rowing boat is rowed to move.
2828
*
2929
*/
30-
public interface BattleShip {
30+
public interface RowingBoat {
3131

32-
void fire();
33-
34-
void move();
32+
void row();
3533

3634
}

0 commit comments

Comments
 (0)