Adapter Pattern
The Adapter Pattern allows incompatible interfaces to work together. It acts as a bridge between two interfaces.
Example
Problem
The VehicleController
expects to control objects that implement a move()
method. The Car
already has a move()
method, but the Drone
has a fly()
method, which isn't directly compatible. We'll create an adapter to make the Drone's fly()
method compatible with the Vehicle's move()
method.
Solution
Key Concepts:
- Client: The
VehicleController
that controls both theCar
andDrone
. - Target Interface: The interface that the
VehicleController
expects to interact with, which will be something likeVehicle
that canmove()
. - Adapter: The class that adapts a Drone's
fly()
method to themove()
method that the VehicleController can call. - Adaptee: The Drone that has the
fly()
method, but is not directly compatible with themove()
method.
1. Target Interface (Vehicle):
The interface that the VehicleController
expects all vehicles to implement.
// The Target interface
interface Vehicle {
move(): void;
}
2. Adaptee (Drone):
The Drone class has a fly()
method, which is not compatible with the move()
method expected by the VehicleController
.
// The Drone class with the `fly` method
class Drone {
fly(): void {
console.log("The drone is flying in the sky.");
}
}
3. Adapter (DroneAdapter):
The DroneAdapter
will adapt the fly()
method of the Drone
to the move()
method that the VehicleController
can use.
// The Adapter class that adapts the Drone to the Vehicle interface
class DroneAdapter implements Vehicle {
private drone: Drone;
constructor(drone: Drone) {
this.drone = drone;
}
// Adapt the `move()` method to call `fly()` on the Drone
move(): void {
this.drone.fly();
}
}
4. Another Adaptee (Car):
The Car
class already implements the move()
method as required by the Vehicle
interface.
// The Car class implements the Vehicle interface
class Car implements Vehicle {
move(): void {
console.log("The car is driving on the road.");
}
}
5. Client (VehicleController):
The VehicleController
expects to control any Vehicle
that implements the move()
method.
// The VehicleController class that controls the Vehicle interface
class VehicleController {
control(vehicle: Vehicle): void {
console.log("Controlling the vehicle:");
vehicle.move();
}
}
Usage
Now, let’s create both a Car
and a Drone
, adapt the Drone
using the DroneAdapter
, and control both with the VehicleController
.
// Main function to run the example
function main() {
// Create a car and a drone
const car: Vehicle = new Car();
const drone: Vehicle = new DroneAdapter(new Drone()); // Adapter makes Drone compatible
// Create the VehicleController to control both vehicles
const controller = new VehicleController();
// Control the car (directly implements `move()`)
controller.control(car);
// Control the drone (adapted through the DroneAdapter)
controller.control(drone);
}
// Run the main function
main();
Output
Controlling the vehicle:
The car is driving on the road.
Controlling the vehicle:
The drone is flying in the sky.