paint-brush
How to Find the Stinky Parts of Your Code [Part XXXVI]by@mcsee
150 reads

How to Find the Stinky Parts of Your Code [Part XXXVI]

by Maximiliano ContieriMay 1st, 2023
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

It smells because there are likely many instances where it could be edited or improved. Most of these smells are just hints of something that might be wrong. Therefore, they are not required to be fixed per se… (You should look into it, though.) You can find all the previous code smells (Part i - XXXV) [here]

People Mentioned

Mention Thumbnail
featured image - How to Find the Stinky Parts of Your Code [Part XXXVI]
Maximiliano Contieri HackerNoon profile picture

It smells because there are likely many instances where it could be edited or improved.


Most of these smells are just hints of something that might be wrong. Therefore, they are not required to be fixed per se… (You should look into it, though.)

Previous Code Smells

You can find all the previous code smells (Part i - XXXV) here.


Let's continue...


Code Smell 176 - Changes in Essence

Mutation is good. Things change.


TL;DR: Don't change essential attributes or behavior

Problems



Solutions

  1. Protect essential attributes from change.


  2. Remove setters

Refactorings

Refactoring 001 - Remove Setters

Context

Heraclitus said:

“No man ever steps in the same river twice. For it’s not the same river and he’s not the same man.”


The man stays the same in essence. But his body evolves.

Sample Code

Wrong


const date = new Date();

date.setMonth(4);

Right


const date = new Date("2022-03-25");

Detection

  • [x]Manual

This is a semantic smell. We need to model which attributes/behaviors are essential and which are accidental.

Tags

Conclusion

We need to favor immutable objects.


Objects can mutate in accidental ways; not in essential ones.

Relations

Code Smell 16 - Ripple Effect

More Info

The Evil Power of Mutants

Disclaimer

Code Smells are just my opinion.

Credits

Photo by Nick Fewings on Unsplash


Changes in software design will eventually mean "one step forward, two steps back". It is inevitable.

Salman Arshad


Code Smell 177 - Missing Small Objects

We see small primitive data everywhere

TL;DR: Don't forget to model the smallest ones

Problems

  • Primitive obsession

Solutions

  1. Find responsibilities for small objects in the MAPPER.


  2. Reify them.

Context

Since the early computing days, we map all we see to the familiar primitive data types: Strings, Integers, Collections, etc.


Mapping to dates violates abstraction and fail-fast principles.


in the Wordle TDD Kata, we describe a Wordle word to be different than a String or Char(5), since they don't have the same responsibilities.

Sample Code

Wrong


public class Person {

    private final String name; 

    public Person(String name) {
        this.name = name;
    }
}

Right


public class Name {

    private final String name; 


    public Name(String name) {
        this.name = name;
        // Name has its own creation rules, comparison etc.
        // Might be different than a string
    }

}

  

public class Person {

    private final Name name; 

    public Person(Name name) {
        // name is created as a valid one,
        // we don't need to add validations here 

        this.name = name;
    }
}

Detection

  • [x]Manual

This is a semantic smell. It is related to design activity

Exceptions

In a very small number of mission-critical systems, we have a tradeoff from abstraction to performance.


This is not the usual case. We do premature optimization by not relying on a modern computer and virtual machine optimizations.


As always, we need to stick to evidence in real-world scenarios.

Tags

  • Primitive

Conclusion

Finding small objects is a very hard task requiring experience to make a good job and avoid overdesign.


There's no silver bullet in choosing how and when to map something.

Relations

Code Smell 122 - Primitive Obsession

More Info

Fail Fast

How to Create a Wordle with TDD in Javascript

Disclaimer

Code Smells are just my opinion.

Credits

Photo by Shane Aldendorff on Unsplash


The secret to building large apps is never build large apps. Break your applications into small pieces. Then, assemble those testable, bite-sized pieces into your big application.

Justin Meyer


Code Smell 178 - Subsets Violation

Invisible objects have rules we need to enforce at a single point.

TL;DR: Create Small objects and restrict your domain.

Problems



Solutions

  1. Create small objects and validate the domain.

Context

This is a primitive obsession smell.


EmailAddresses are a subset of string.


Valid Ages are a subset of Real.


Ports are a subset of Integers.


A wordle word is a subset of String.

Sample Code

Wrong


destination = "[email protected]"
  

destination = "destination.example.com"

// No error thrown

Right


public class EmailAddress {

    public String emailAddress;


    public EmailAddress(String address) {

        string expressions = @"^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$";

        if (!Regex.IsMatch(email, expressions) {

          throw new Exception('Invalid address');

        }

        this.emailAddress = address;

    }

}



destination = new EmailAddress("[email protected]");

Not to be confused with the anemic Java version

Detection

  • [x]Manual

This is a semantic smell.

Tags

  • Primitive Obsession

Conclusion

We need to be loyal to the bijection of the real world.


Subsets are very important for early validations and fail fast principle.

Relations

Code Smell 122 - Primitive Obsession

More Info

Fail Fast

Disclaimer

Code Smells are just my opinion.

Credits

Photo by Mona Eendra on Unsplash


Every craftsman starts his or her journey with a basic set of good-quality tools.

Andrew Hunt


Code Smell 179 - Known Bugs

Every software has a list of known bugs. Why?

TL;DR: Don't track bugs. Fix them.

Problems

  • Hard to-track lists


  • Technical Debt


  • Functional Debt

Solutions

  1. Stop calling it a Bug


  2. Reproduce the Defect.


  3. Cover the scenario with automation.


  4. Make the most straightforward fix (even hardcoding solutions)


  5. Refactor


Welcome to TDD!

Context

We don't like to be interrupted.


Then, we create lists and delay fixes and solutions.


We should be able to change software easily.


We need to improve our software if we can't do quick fixes and corrections.


Not by creating To-Fix lists.

Sample Code

Wrong

<?

function divide($numerator, $denominator) {
  return $numerator / $denominator;  
  // FIXME denominator value might be 0
  // TODO Rename function
}

Right

<?

function integerDivide($numerator, $denominator) {
  if (denominator == 0) {
    throw new DivideByZero();
  }
  return $numerator / $denominator;  
}

// we pay our debts

Detection

  • [x]Automatic

We need to avoid creating bugs and issues.

Tags

  • Technical Debt

Conclusion

We need to discourage bugs and issue trackers on the engineering side.


Of course, customers need to track their findings, and we need to address them ASAP.

Relations

Code Smell 148 - ToDos

More Info

Famous Bugs

Stop Calling them 'Bugs'

Disclaimer

Code Smells are just my opinion.

Credits

Photo by Justin Lauria on Unsplash


In general, the longer you wait before fixing a bug, the costlier (in time and money) it is to fix.

Joel Spolsky


Code Smell 180 - BitWise Optimizations

Bitwise operators are faster. Avoid these micro-optimizations.

TL;DR: Don't use bitwise operators unless your business model is bitwise logic.

Problems

  • Readability


  • Cleverness


  • Premature Optimization


  • Maintainability


Solutions

  1. Improve readability

Context

Some clever programmers solve problems we don't have.


We should optimize code based on evidence and use the scientific method.


We should benchmark only if necessary and improve code only if really necessary and bear the cost of changeability and maintainability.

Sample Code

Wrong

const nowInSeconds = ~~(Date.now() / 1000)

Right

const nowInSeconds = Math.floor(Date.now() / 1000)

Detection

  • [x]Semi-Automatic

We can tell our linters to warn us and manually check if it is worth the change.

Exceptions

  • Real-time and mission-critical software.

Tags

  • Premature Optimization

Conclusion

If we find this code in a pull request or code review, we need to understand the reasons. If they are not justified, we should do a rollback and change it to a normal logic.

Relations

Code Smell 20 - Premature Optimization

Code Smell 165 - Empty Exception Blocks

Code Smell 06 - Too Clever Programmer

Code Smell 129 - Structural Optimizations

More Info

Tilde Operator ~~

Javascript BitWise Operators

Disclaimer

Code Smells are just my opinion.

Credits

Photo by Frédéric Barriol on Unsplash


Original Article Here.


Watch the little things; a small leak will sink a great ship.

Benjamin Franklin


5 more code smells are coming soon…