Last active
July 5, 2022 16:03
-
-
Save A-Maged/d63e002ae6f9d82b29fda7e70f57f12f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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