DEV Community

Emi Castellano
Emi Castellano

Posted on

JavaScript - Strategy pattern 🧠

Do you want to avoid writing multiple if/else if or switch statement with a bunch of cases inside?

The strategy pattern can help us with that.

Imagine we have a use case where the user can sign up using different methods:

  • Google Auth
  • Facebook Auth
  • Form submission

We want to avoid this:

const AUTH_METHODS = {
  GOOGLE: 'GOOGLE',
  FACEBOOK: 'FACEBOOK',
  FORM_SUBMISSION: 'FORM_SUBMISSION'
}

const googleAuth = _ => {
  // ... Google auth code here
}

const facebookAuth = _ => {
  // ... Facebook Auth code here
}

const formSubmissionAuth = _ => {
  // ... Form submission code here
}

const handleAuthentication = method => {
  if (method === AUTH_METHODS.GOOGLE) {
    googleAuth()
  } else if (method === AUTH_METHODS.FACEBOOK) {
    facebookAuth()
  } else {
    formSubmissionAuth()
  }
}
Enter fullscreen mode Exit fullscreen mode

How can we improve this using the strategy pattern?

const AUTH_METHODS = {
  GOOGLE: 'GOOGLE',
  FACEBOOK: 'FACEBOOK',
  FORM_SUBMISSION: 'FORM_SUBMISSION'
}

const googleAuth = _ => {
  // ... Google auth code here
}

const facebookAuth = _ => {
  // ... Facebook Auth code here
}

const formSubmissionAuth = _ => {
  // ... Form submission code here
}

const authenticationStrategy = method => ({
  [AUTH_METHODS.GOOGLE]: googleAuth,
  [AUTH_METHODS.FACEBOOK]: facebookAuth,
  [AUTH_METHODS.FORM_SUBMISSION]: formSubmissionAuth
})[method]

const strategy = authenticationStrategy(AUTH_METHODS.GOOGLE)
strategy()
Enter fullscreen mode Exit fullscreen mode

And if we want to pass parameters to some of the strategy functions, we can do it like this:

const authenticationStrategy = method => ({
  [AUTH_METHODS.GOOGLE]: googleAuth,
  [AUTH_METHODS.FACEBOOK]: facebookAuth,
  [AUTH_METHODS.FORM_SUBMISSION]: () => formSubmissionAuth({ username: 'javascript', password: 'strategyPattern' })
})[method]
Enter fullscreen mode Exit fullscreen mode

The strategy pattern, returns an object with key/value pair and what determines which key is the one to be "executed" is the [method] at the end, this is the dependency of our function, whatever value we pass there it will be mapped to the corresponding object key.

Discussion (2)

Collapse
halbano profile image
halbano

Nice article Emi!
I tipically use the same approach for picking the right component based in conditions working with React and React Native too. Despite this would be not as aligned as your use case with the "strategy" term, the usage improves from my point of view readability and clarity.

Collapse
emi_castellano profile image
Emi Castellano Author

Thanks dude, yeah that’s also a good scenario to take advantage of this pattern and increase code readability. 😁