Variables - No magic strings duplication

by César SantosSep 14th, 20204 min read
Also available in: Spanish

This is the second post in a serie of posts about improving variable usages in general.

Note: Code example in this post is in JavaScript, but the concepts and suggestions can be applied to any language. This example doesn't make sense functionally, but it works to explain the concepts of this post.

Index

These are the topics discussed on each post:

  1. Using constants
  2. Avoiding magic strings duplication
  3. Using variables to simplify code

Avoiding magic strings duplication

Let's take a look at the following code:

function onLoad(pageType) {
  if (pageType === 'MAIN') {    console.log('Main page loaded')
  } else {
    console.log('Other pageType')
  }
}

function onFocus(pageType) {
  if (pageType === 'MAIN') {    console.log('Focused on main page')
  } else {
    console.log('Focus on other pageType. The MAINSTREAM is amazing')
  }
}

// Invoking those functions (in the same file or in another file).
function callOnLoad() {
  onLoad('MAIN')}

function callOnFocus() {
  onFocus('MAIN')}

As you can see, 'MAIN' is being used for multiple things: to decide what to do when the functions are called, and to call those functions. This code does what it needs to do, but having those values hard-coded in multiple places is a big issue because your code has those values duplicated everywhere. This gets much harder in the future if you (or your teammates) needs to make changes to it.

For example, imagine your app is much larger than the code above, and you're using 'MAIN' in multiples files and components, and you need to do one of the following actions:

  • Replace 'MAIN' to 'MAIN_PAGE'.
  • Identify all the places where 'MAIN' is being referenced for estimating the scope of a change that is coming.

You will need to find all those strings across the codebase, verify those are the ones you need and not others completely different (ex MAINSTREAM). Yes, you could use "Find all" or "Replace all" in your preferred IDE, but there is always a risk of making the wrong change, and you will need to ensure one by one you modified the right place.

Now, let's see how that code could be improved:

const MAIN_PAGE_TYPE = 'MAIN'
function onLoad(pageType) {
  if (pageType === MAIN_PAGE_TYPE) {    console.log('Main page loaded')
  } else {
    console.log('Other pageType')
  }
}

function onFocus(pageType) {
  if (pageType === MAIN_PAGE_TYPE) {    console.log('Focused on main page')
  } else {
    console.log('Focus on other pageType. The MAINSTREAM is amazing')
  }
}

// Invoking those functions (in the same file or in another file).
function callOnLoad() {
  onLoad(MAIN_PAGE_TYPE)}

function callOnFocus() {
  onFocus(MAIN_PAGE_TYPE)}

This way you gain multiple benefits:

  • You only have to touch one line of code to replace 'MAIN' for 'MAIN_PAGE'.
  • It helps your IDE to index all constant references across your entire codebase.
  • You can safely identify where that value/constant is being referenced by using your IDE "Find All References" or "Find usages" features.
  • If you need it, you could also rename the constant name safely by using your IDE "Refactor - Rename" or "Refactor - Change Signature" or "Change All Occurrences" features as it will find all references and update them for you.
  • Having configured helpers in your IDE such as intelliSense (and eslint for javascript), the IDE will autocomplete the constant names, identify if you're referencing non-existing constants, etc.

Code standards (Personal preference)

  • Only if you're using a typed language (such as Java or TypeScript) you can group constants in objects or enums:
enum PAGE_TYPE {  MAIN = 'MAIN',  LOGIN = 'LOGIN',}
function onLoad(pageType: PAGE_TYPE) {
  if (pageType === PAGE_TYPE.MAIN) {    console.log('Main page loaded')
  } else {
    console.log('Other pageType')
  }
}
  • If you're using a non-typed language (like JavaScript without TypeScript) I recommend having independent constants, otherwise you might have typos in your code, and the IDE won't be able to help you:
const PAGE_TYPE = {
  MAIN: 'MAIN',
  LOGIN: 'LOGIN',
}

function onLoad(pageType: PAGE_TYPE) {
  // The IDE can't know whether MAIN2 exists or not  if (pageType === PAGE_TYPE.MAIN2) {    console.log('Main page loaded')
  } else {
    console.log('Other pageType')
  }
}

Help you and your teammates to have better coding experience by writing code that enables nice IDE features such as IntelliSense.

You won't be the only person touching that codebase for ever!