Skip to content

Instantly share code, notes, and snippets.

@shershen08
Last active October 19, 2022 17:08
Show Gist options
  • Save shershen08/232f7518daa8142841c31e061ce91f40 to your computer and use it in GitHub Desktop.
Save shershen08/232f7518daa8142841c31e061ce91f40 to your computer and use it in GitHub Desktop.
Strategy and factory patterns in TypeScript
// see article with examples in JAVA here: https://dzone.com/articles/design-patterns-the-strategy-and-factory-patterns
// example for educational purposes shownig close and mature syntax of modern TypeScript
enum AccountTypes {CURRENT, SAVINGS, HIGH_ROLLER_MONEY_MARKET, STANDARD_MONEY_MARKET}
////////////////////////////////////////
/// the interface that is used by the strategy
////////////////////////////////////////
interface InterestCalculationStrategy {
calculateInterest(accountBalance:Number):Number;
}
////////////////////////////////////////
/// Null object implementation and 4 account type related calculation stategies
////////////////////////////////////////
class NoInterestCalculation implements InterestCalculationStrategy {
calculateInterest(accountBalance:Number):Number {
return 0;
}
}
class CurrentAccountInterestCalculation implements InterestCalculationStrategy {
calculateInterest(accountBalance:Number):Number {
return +accountBalance * (0.02 / 12);
}
}
class SavingsAccountInterestCalculation implements InterestCalculationStrategy {
calculateInterest(accountBalance:Number):Number {
return +accountBalance * (0.04 / 12);
}
}
class MoneyMarketInterestCalculation implements InterestCalculationStrategy {
calculateInterest(accountBalance:Number):Number {
return +accountBalance * (0.06/12);
}
}
class HighRollerMoneyMarketInterestCalculation implements InterestCalculationStrategy {
calculateInterest(accountBalance:Number):Number {
return accountBalance < 100000.00 ? 0 : (+accountBalance) * (0.075/12)
}
}
////////////////////////////////////////
/// select and apply the correct strategy
////////////////////////////////////////
class InterestCalculationStrategyFactory {
//Strategies for calculating interest.
private currentAccountInterestCalculationStrategy:InterestCalculationStrategy = new CurrentAccountInterestCalculation();
private savingsAccountInterestCalculationStrategy:InterestCalculationStrategy = new SavingsAccountInterestCalculation();
private moneyMarketAccountInterestCalculationStrategy:InterestCalculationStrategy = new MoneyMarketInterestCalculation();
private highRollerMoneyMarketAccountInterestCalculationStrategy:InterestCalculationStrategy = new HighRollerMoneyMarketInterestCalculation();
private noInterestCalculationStrategy:InterestCalculationStrategy = new NoInterestCalculation();
public getInterestCalculationStrategy(accountType:AccountTypes):InterestCalculationStrategy {
switch (accountType) {
case AccountTypes.CURRENT: return this.currentAccountInterestCalculationStrategy;
case AccountTypes.SAVINGS: return this.savingsAccountInterestCalculationStrategy;
case AccountTypes.STANDARD_MONEY_MARKET: return this.moneyMarketAccountInterestCalculationStrategy;
case AccountTypes.HIGH_ROLLER_MONEY_MARKET: return this.highRollerMoneyMarketAccountInterestCalculationStrategy;
default: return this.noInterestCalculationStrategy;
}
}
}
@savalazic
Copy link

@shershen08 @joshrizzo

interface InterestCalculationStrategy {
  calculateInterest(accountBalance:Number):Number;
  test(type: AccountTypes): boolean;
}

// and then you implement test function for every strategy
class SavingsAccountInterestCalculation implements InterestCalculationStrategy {
    test(type: AccountType) {
        return type === AccountType.SAVING
    }
    
    calculateInterest(accountBalance:Number):Number {
        return +accountBalance * (0.04 / 12);
    }
}

class InterestCalculationStrategyFactory {
   strategies = [
     new SavingsAccountInterestCalculation(),
     // ...all other strategies
  ]

  getInterestCalculationStrategy(accountType:AccountTypes):InterestCalculationStrategy {
    return this.strategies.find(strategy => strategy.test(accountType));
  }
}

@dijalmasilva
Copy link

dijalmasilva commented Mar 18, 2021

it could be like that too...

interface InterestCalculationStrategy {
  calculateInterest(accountBalance:Number):Number;
}

// and then you implement test function for every strategy
class SavingsAccountInterestCalculation implements InterestCalculationStrategy {
    calculateInterest(accountBalance:Number):Number {
        return +accountBalance * (0.04 / 12);
    }
}

class InterestCalculationStrategyFactory {
  private static strategies = {
     [AccountTypes.SAVING]: new SavingsAccountInterestCalculation(),
     // ...all other strategies
  }

  static getInterestCalculationStrategy(accountType:AccountTypes):InterestCalculationStrategy {
    return InterestCalculationStrategyFactory.strategies[accountType];
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment