In the world of software design, flexibility and maintainability are crucial. One of the best ways to achieve this is through the Strategy Patternβa behavioral design pattern that allows us to define a family of algorithms, encapsulate each one, and make them interchangeable.
Letβs break it down using a car example! π
What is the Strategy Pattern?
The Strategy Pattern enables an objectβs behavior to be selected at runtime. Instead of hardcoding logic inside an object, we delegate it to separate strategy classes that encapsulate different behaviors. This promotes the Open-Closed Principleβwhere code is open for extension but closed for modification.
Real-World Example: Cars and Their Behaviors πβ‘οΈβ½
Consider a car that can have different transmission types (manual, automatic, semi-automatic) and fuel types (gasoline, diesel, electric). Instead of tightly coupling the carβs logic to these behaviors, we use the Strategy Pattern to define separate classes for each.
πΉ Implementing Transmission Strategies
Each transmission type is an independent class that implements the TransmissionStrategy
interface:
export interface TransmissionStrategy {
changeGear(): void;
}
export class ManualTransmission implements TransmissionStrategy {
changeGear(): void {
console.log("Changing gear manually.");
}
}
export class AutomaticTransmission implements TransmissionStrategy {
changeGear(): void {
console.log("Changing gear automatically.");
}
}
export class SemiAutomaticTransmission implements TransmissionStrategy {
changeGear(): void {
console.log("Changing gear semi-automatically.");
}
}
πΉ Implementing Fuel Strategies
Similarly, different fuel types adhere to a FuelStrategy
interface:
export interface FuelStrategy {
refuel(): void;
}
export class Gasoline implements FuelStrategy {
refuel(): void {
console.log("Refueling gasoline...");
}
}
export class Diesel implements FuelStrategy {
refuel(): void {
console.log("Refueling diesel...");
}
}
export class Electric implements FuelStrategy {
refuel(): void {
console.log("Charging the battery...");
}
}
πΉ The Car Class Using Strategies
The Car
class now delegates behavior to the appropriate strategy:
export class Car {
private transmission: TransmissionStrategy;
private fuel: FuelStrategy;
constructor(transmission: TransmissionStrategy, fuel: FuelStrategy) {
this.transmission = transmission;
this.fuel = fuel;
}
setTransmission(transmission: TransmissionStrategy): void {
this.transmission = transmission;
}
setFuel(fuel: FuelStrategy): void {
this.fuel = fuel;
}
refuel(): void {
this.fuel.refuel();
}
changeGear(): void {
this.transmission.changeGear();
}
}
Why Use the Strategy Pattern? π€
β
Flexibility: We can change the carβs transmission and fuel type dynamically at runtime.
β
Encapsulation: Each behavior is encapsulated separately, making it easy to add new strategies.
β
Maintainability: Avoids complex if-else conditions, making the code clean and modular.
β
Reusability: Strategies can be reused across different contexts without modifications.
Example Usage π
Now, letβs create different cars and modify their behaviors at runtime:
const manualCar = new Car(new ManualTransmission(), new Gasoline());
manualCar.changeGear(); // Output: Changing gear manually.
const automaticCar = new Car(new AutomaticTransmission(), new Electric());
automaticCar.changeGear(); // Output: Changing gear automatically.
const semiAutomaticCar = new Car(new SemiAutomaticTransmission(), new Diesel());
semiAutomaticCar.changeGear(); // Output: Changing gear semi-automatically.
manualCar.setTransmission(new AutomaticTransmission()); // Switching to automatic
semiAutomaticCar.setFuel(new Electric()); // Switching to electric
manualCar.changeGear(); // Output: Changing gear automatically.
semiAutomaticCar.refuel(); // Output: Charging the battery...
Final Thoughts π‘
The Strategy Pattern is a powerful tool for designing flexible and reusable software. By decoupling behaviors into independent strategies, we make our applications more adaptable to change.
If you found this insightful, drop a like and share this with your network! ππ¬
Top comments (0)