Skip to content

Instantly share code, notes, and snippets.

@A-Maged
Last active July 5, 2022 16:03
Show Gist options
  • Save A-Maged/d63e002ae6f9d82b29fda7e70f57f12f to your computer and use it in GitHub Desktop.
Save A-Maged/d63e002ae6f9d82b29fda7e70f57f12f to your computer and use it in GitHub Desktop.
/*
Strategy Pattern
Co-Author: https://github.com/WaseemMansour
reference: https://refactoring.guru/design-patterns/strategy
*/
/* Strategies context */
class Context<Strategy> {
/* reference to concrete strategy */
private strategy: Strategy;
constructor(strategy: Strategy) {
this.strategy = strategy;
}
setStrategy(strategy: Strategy) {
this.strategy = strategy;
}
/* TODO: describe this better */
callStrategyMethod(fnName: string, params: any[]) {
// @ts-ignore
this.strategy[fnName](...params);
}
}
function ContextFactory<Strategy>(strategy: Strategy) {
const context = new Context<Strategy>(strategy);
const contextProxy = new Proxy(context, {
get: function (
context: Context<Strategy>,
fnName: keyof Context<Strategy>
) {
return function (...params: any) {
/* if fnName not found on context, delegate to strategy */
if (fnName in context) {
if (typeof context[fnName] === "function") {
// @ts-ignore
return context[fnName](...params);
} else {
return context[fnName];
}
}
context.callStrategyMethod(fnName, params);
};
},
});
return contextProxy as Context<Strategy> & Strategy;
}
/* ********* */
/* Usage */
/* Strategy interface */
interface AuthStrategy {
login: () => boolean;
logout: () => boolean;
}
/* Concrete strategy */
class JWTStrategy implements AuthStrategy {
constructor() {}
login() {
console.log("login with jwt");
return true;
}
logout() {
console.log("logout with jwt");
return true;
}
}
/* Concrete strategy */
class OAuthStrategy implements AuthStrategy {
constructor() {}
login() {
console.log("login with OAuth");
return true;
}
logout() {
console.log("logout with OAuth");
return true;
}
}
const jwtStrategy = new JWTStrategy();
const oAuthStrategy = new OAuthStrategy();
const authContext = ContextFactory<AuthStrategy>(jwtStrategy);
authContext.login();
authContext.logout();
authContext.setStrategy(oAuthStrategy);
authContext.login();
authContext.logout();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment