Wikipedia define adapter pattern as
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.
Lets see this in action. Lets suppose we are building Duck simulator
interface Duck {
quack();
fly();
}
We have a duck interface which consists of two methods.
class MallardDuck implements Duck {
display() {
// displays mallard duck
}
fly() {
// implement swim behaviour
}
quack() {
// implements quack behaviour
}
}
We have MallardDuck
which implements the Duck
interface.
class DuckSimulator {
constructor() {
const duck = new MallardDuck();
this.quackAndFly(duck);
}
quackAndFly(duck: Duck) {
duck.quack();
duck.fly();
}
}
Inside the DuckSimulator
we create a new Duck
instance of MallardDuck
and assign it to the duck
. So far everything is working fine. If we call the quackAndFly
method of the DuckSimulator
it will execute the fly
and quack
method of MallardDuck
Now lets suppose we want to add Turkey
into our DuckSimulator
.
interface Turkey {
gobble();
fly();
}
The Turkey
interface is slightly different from the Duck
's interface so we can not add it directly to our DuckSimulator
.
class WildTurkey implements Turkey {
gobble() {
console.log("gobble!");
}
fly() {
console.log("Fly");
}
}
We can not use Turkey
in DuckSimulator
because DuckSimulator
expects the type objects to be of type Duck
and the interface for Duck
and Turkey
have differences due to which it can not be used.
To overcome this we can use a Adapter
. An Adapter
acts as a bridge between Duck
and Turkey
objects.
We will create a new class called TurkeyAdapter
. This class will act as an adapter between Duck
and Turkey
This class will implement the Duck
interface so we can directly plug it into the Duck
class. Inside the implementation of Duck
’s interface method, we will call the corresponding methods of the Turkey
class. Lets see an example so its more concrete
class TurkeyAdapter implements Duck {
constructor(private turkey: Turkey) {}
quack() {
this.turkey.gobble();
}
fly() {
this.turkey.fly();
}
}
Now we can use this inside the DuckSimulator
class DuckSimulator {
constructor() {
const duck = new MallardDuck();
this.quackAndFly(duck);
const wildTurkey = new TurkeyAdapter(new WildTurkey());
this.quackAndFly(wildTurkey);
}
quackAndFly(duck: Duck) {
duck.quack();
duck.fly();
}
}