DEV Community

Cover image for Code Smell | Shotgun surgery
Jesús Mejías Leiva for Product Hackers

Posted on • Edited on • Originally published at blog.susomejias.dev

Code Smell | Shotgun surgery

Hello, today we are back with the code smells refactoring series and in this case we are going to talk about code smell called Shotgun Surgery, this smell can be detected if making a change have to replicate this change in different parts of our code


Cause

A single responsibility has been split up among a large number of sites. This can happen after the overzealous application of Divergent Change


Example

We can see that the minimum balance check is being duplicated in both methods

class Account {
  private amount: number;

  constructor(amount: number) {
    this.amount = amount;

    //...
  }

 debit(debitAmount: number): void {
    if (this.amount <= 1000) {
      throw new Error('Minimum balance should be over 1000');
    }

    //...
  }

  transfer(from: Account, to: Account, transferAmount: number): void {
    if (from.amount <= 1000) {
      throw new Error('Minimum balance should be over 1000');
    }

    //...
  }
}

Enter fullscreen mode Exit fullscreen mode

Solution

Extract minimum balance checks to method to be able to reuse it in the different methods of the class

class Account {
  private amount: number;

  constructor(amount: number) {
    this.amount = amount;

    //...
  }

  assertMinimumBalance(amount: number): void {
    const MINIMUM_AMOUNT = 1000;

    if (amount <= MINIMUM_AMOUNT) {
      throw new Error(`Minimum balance should be over ${MINIMUM_AMOUNT}`);
    }
  }

  debit(debitAmount: number): void {
    this.assertMinimumBalance(this.amount);

    //...
  }

  transfer(from: Account, to: Account, transferAmount: number): void {
    this.assertMinimumBalance(from.amount);

    //...
  }
}
Enter fullscreen mode Exit fullscreen mode

Bonus track

Shotgun surgery in CSS? 🤔

Yes, see the next example:

.button-primary {
  background-color: #ec407a;
}

.button-secondary {
  background-color: #b4004e;
}

.navbar-primary {
  background-color: #ec407a;
}

.navbar-secondary {
  background-color: #b4004e;
}
Enter fullscreen mode Exit fullscreen mode

If now they ask us to modify the primary color for another, what is the solution? Search globally in all our CSS and replace it? NOOO!! ⛔️

The solution is use CSS variables:

We can declare variables in CSS globally with the pseudo-class :root and thus use them in any part of our CSS, in this way we centralize the possible changes in only the variables, thus avoiding having to replace each color value


:root {
  --primary-background: #ec407a;
  --secondary-background: #b4004e;
}

.button-primary {
  background-color: var(--primary-background);
}

.button-secondary {
  background-color: var(--secondary-background);
}

.navbar-primary {
  background-color: var(--primary-background);
}

.navbar-secondary {
  background-color: var(--secondary-background);
}
Enter fullscreen mode Exit fullscreen mode

Thanks for reading me 😊

thanks

Top comments (2)

Collapse
 
sefatanam profile image
Sefat Anam

looking forward to next.....🚀

Collapse
 
susomejias profile image
Jesús Mejías Leiva

Thanks! 😊