Strategy Design Pattern - DeanHristov/ts-design-patterns-cheat-sheet GitHub Wiki
The Strategy pattern is a behavioral design pattern that gives us the ability to select an algorithm at runtime. Instead of implementing a single algorithm directly (in the code), code receives run-time instructions as to which in a family of algorithms to use. A simple UML diagram can be seen here
A Great fit when:
- Algorithms can be selected on the fly, using composition
Example:
Public contracts
export interface IPaymentService {
pay(amount: number): number;
isValid(): boolean;
}
Auxiliary classes
A class which represents credit card
class Card {
cardNumber: string;
cardHolder: string;
cvv: number;
balance: number;
constructor(
cardNumber: string,
cardHolder: string,
cvv: number,
balance: number,
) {
this.cardHolder = cardHolder;
this.cardNumber = cardNumber;
this.cvv = cvv;
this.balance = balance;
}
}
A class which represents PayPal user
class PayPalUser {
username: string;
password: string;
balance: number;
constructor(username: string, password: string, balance: number) {
this.username = username;
this.password = password;
this.balance = balance;
}
}
Simple implementation
The Context class. It is not familiar what kind of strategy is used
class PaymentService {
private strategy: IPaymentService;
constructor(strategy: IPaymentService) {
this.strategy = strategy;
}
setStrategy(strategy: IPaymentService) {
this.strategy = strategy;
}
processOrder(amount: number) {
if (this.strategy.isValid()) {
this.strategy.pay(amount);
return true;
}
return false;
}
}
The Concrete strategy 1
CreditCardPayment implements IPaymentService {
private readonly owner: Card;
constructor(owner: Card) {
this.owner = owner;
}
isValid(): boolean {
// TODO Do some code
return true;
}
pay(amount: number): number {
return this.owner.balance - amount;
}
}
The Concrete strategy 2
class PayPalPayment implements IPaymentService {
private readonly user: PayPalUser;
constructor(user: PayPalUser) {
this.user = user;
}
pay(amount: number): number {
return this.user.balance - amount;
}
isValid(): boolean {
// TODO Do some code
return true;
}
}
Code in action
// Processing the order via creditCard
const creditCard: Card = new Card('374245455400126', 'John', 123, 1000);
const strategy: PaymentService = new PaymentService(
new CreditCardPayment(creditCard),
);
strategy.processOrder(10);
// Processing the order via PayPal
const payPalUser: PayPalUser = new PayPalUser('John', '1234', 1000);
strategy.setStrategy(new PayPalPayment(payPalUser));
strategy.processOrder(20);
More info can be found on the wiki page.