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
VehicleControllerthat controls both theCarandDrone. - Target Interface: The interface that the
VehicleControllerexpects to interact with, which will be something likeVehiclethat 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.