[Design Pattern] Adapter Design Pattern - code example

Answer1215 / 2023-05-05 / 原文

interface EnemyAttacker {
  fireWeapon(): void;
  driveForward(): void;
  assignDriver(driverName: string): void;
}

// Target
class EnemyTank implements EnemyAttacker {
  fireWeapon() {
    const attackDamage = Math.round(Math.random() * 10 + 4);
    console.log(`Enemy Tank Does ${attackDamage} Damage`);
  }
  driveForward() {
    const movement = Math.round(Math.random() * 5 + 2);
    console.log(`Enemy Tank moves ${movement} spaces`);
  }
  assignDriver(driverName: string): void {
    console.log(`${driverName} is driving the tank`);
  }
}

// Adaptee
class EnemyRobot {
  smashWithHands() {
    const attackDamage = Math.round(Math.random() * 5 + 1);
    console.log(`Enemy Robot Does ${attackDamage} Damage With its hands`);
  }
  walkForward() {
    const movement = Math.round(Math.random() * 3 + 1);
    console.log(`Enemy Robot walks forward ${movement} spaces`);
  }
  reactToHuman(driverName: string) {
    console.log(`Enemy Robot Tramps on ${driverName}`);
  }
}

// Adapter
class EnemyRobotAdapter implements EnemyAttacker {
  enemyRebot: EnemyRobot;

  constructor(robot: EnemyRobot) {
    this.enemyRebot = robot;
  }

  fireWeapon(): void {
    this.enemyRebot.smashWithHands();
  }
  driveForward(): void {
    this.enemyRebot.walkForward();
  }
  assignDriver(driverName: string): void {
    this.enemyRebot.reactToHuman(driverName);
  }
}

const tank = new EnemyTank();
const robot = new EnemyRobot();
const robotAdapter = new EnemyRobotAdapter(robot);

console.log(`The Robot`);
robot.reactToHuman(`Paul`);
robot.walkForward();
robot.smashWithHands();

console.log("Tank");
tank.assignDriver("Frank");
tank.driveForward();
tank.fireWeapon();

console.log("The Robot with the Adapter");
robotAdapter.assignDriver("Mark");
robotAdapter.driveForward();
robotAdapter.fireWeapon();

 

Client wants to use EnemyRobot the same way as use any other EnemyAttcker.

But EnemyRobot has different interface as EnemyAttcker.

Therefore we need EnemyRobotAdapter to help translate EnemyRobot interface to EnemyAttcker interface.

EnemyRobotAdapater use EnemyRobot and implements EnemyAttacker.