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

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

by Maximiliano ContieriMarch 24th, 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. They are not required to be fixed per se, though. (You should look into it, though.) Previous Code SmellsYou can find all the previous code smells (Part i - XXXII) here.
featured image - How to Find the Stinky Parts of Your Code [Part XXXIII]
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 - XXXII) here.


Let's continue...


Code Smell 161 - Abstract/Final/Undefined Classes

Your classes are abstract, final, or undefined


TL;DR: If your language has the right tool, your classes should be either abstract or final.

Problems


  • Classes with just one concrete subclass


  • Liskov Substitution Violation


Solutions

  1. Declare all your leaf classes as final and the rest of them as abstract.

Context

Managing hierarchies and composition is the main task of a good software designer.


Keeping hierarchies healthy is crucial to favor cohesion and avoid coupling.

Sample Code

Wrong

public class Vehicle
{
  // the class is not a leaf. Therefore it should be abstract
    
  // an abstract method that only declares, but does not define the start 
  // functionality because each vehicle uses a different starting mechanism
  abstract void start();
}

public class Car extends Vehicle
{
  // the class is a leaf. Therefore it should be final
}

public class Motorcycle extends Vehicle
{
  // the class is a leaf. Therefore it should be final
}

Right

abstract public class Vehicle
{
  // the class is not a leaf. Therefore it must be abstract  
 
  //an abstract method that only declares, but does not define the start 
  //functionality because each vehicle uses a different starting mechanism
  abstract void start();
}

final public class Car extends Vehicle
{
  // the class is a leaf. Therefore it is final
}

final public class Motorcycle extends Vehicle
{
  // the class is a leaf. Therefore it is final
}

Detection

  • [x]Automatic

Since this is enforced by static analysis, we can't do it with most available tools.

Tags

  • Subclassification

Conclusion

We should look back at our classes, and start qualifying them either as abstract or final.


There are no valid cases for two concrete classes, one subclassifying the other.

Relations

Code Smell 11 - Subclassification for Code Reuse

Code Smell 136 - Classes With just One Subclass

Code Smell 37 - Protected Attributes

Code Smell 58 - Yo-yo Problem

More Info

Coupling - The one and only software design problem

Deep Subclasses

Disclaimer

Code Smells are just my opinion.

Credits

Photo by William Bossen on Unsplash


When the final design seems too simple for the amount of work you've put in, then you know you're done.


Brady Clark


Code Smell 162 - Too Many Parentheses

Parentheses are free of charge. Aren't they?


TL;DR: Use as few parentheses as possible.

Problems

  • Readability


  • Syntactic complexity

Solutions

  1. Remove all not necessary parentheses

Context

We read code from left to right (at least, in western culture).


Parentheses often break this flow, adding cognitive complexity.

Sample Code

Wrong


schwarzschild = ((((2 * GRAVITATION_CONSTANT)) * mass) / ((LIGHT_SPEED ** 2)))

Right


schwarzschild = (2 * GRAVITATION_CONSTANT * mass) / (LIGHT_SPEED ** 2)

Detection

  • [x]Automatic

This is a fully automated code smell.


It is based on syntax trees.


Many tools detect it.

Exceptions

On some complex formulas, we can add extra parenthesis for terms’ readability.

Tags

  • Readability


  • Bloaters

Relations

Code Smell 02 - Constants and Magic Numbers

Conclusion

We write code once and read it too many times.


Readability is king.

Credits

Photo by Nick Fewings on Unsplash


If someone claims to have the perfect programming language, he is either a fool or a salesman or both.


Bjarne Stroustrup


Code Smell 163 - Collection in Name

Have you ever seen a CustomerCollection?


TL;DR: Don't use 'collection' in your name. It is too abstract for concrete concepts.

Problems

  • Readability


  • Abstraction Abuse


Solutions

  1. Rename the collection with a specific name.

Context

Naming is very important.


We need to deal a lot with collections.


Collections are amazing since they don't need nulls to model the absence.


An empty collection is polymorphic with a full collection.


We avoid nulls and IFs.


We often use bad and vague names instead of looking for good names in the MAPPER.

Sample Code

Wrong


for (var customer in customerCollection) {

    // iterate with current customer

}



for (var currentCustomer in customersCollection) {

    // iterate with current customer

}

Right


for (var customer in customers) {

    // iterate with current customer

}

Detection

  • [x]Semi-Automatic


All linters can detect a bad naming like this.


It can also lead to false positives, so we must be cautious.

Tags

  • Naming

Conclusion

We need to care for all our clean code, variables, classes, and functions.


Accurate names are essential to understand our code.

Relations

Code Smell 134 - Specialized Business Collections

More Info

What exactly is a name - Part II Rehab

Credits

Photo by Mick Haupt on Unsplash


Alzheimer's Law of Programming: Looking at code you wrote more than two weeks ago is like looking at code you are seeing for the first time.


Dan Hurvitz


Code Smell 164 - Mixed Indentations

Tabs vs Spaces. The most significant computer problem.


TL;DR: Don't mix indentation styles

Problems

  • Readability


  • Code consistency


  • Standards violation

Solutions

  1. Choose one of them.


  2. Stick to it.


  3. Enforce it with code standards tests.


  4. Share the rules on all the codebases.


  5. Use an IDE like VSCode or WebStorm that doesn't include tabs at all.

Context

Whenever I publish an article many people don't care about the sample intent and rush to point out indentation mistakes.


Choosing one standard over the other will be a great solution.


Spaces always count as one.


Tabs can count as many different options.

Sample Code

Wrong


function add(x, y) {

// --->..return x + y;



      return x + y;

}



function main() {

// --->var x = 5,

// --->....y = 7;



    var x = 5,

        y = 7;

}

Right


function add(x, y) {

// --->return x + y;

    return x + y;

}

Detection

  • [x]Automatic

Any parser can enforce this rule.

Exceptions

Some languages like Python consider indent as part of the syntax.


In these languages, indentation is not accidental since it changes code semantics.

Tags

  • Code Standards

Conclusion

There's been so much debate on this subject.


The smell is related to mixing them, not about using one instead of another.


Some IDEs automatically convert one convention to the other one.

Relations

Code Smell 48 - Code Without Standards

More Info


Whatever the device you use for getting your information out, it should be the same information.


Tim Berners-Lee


Code Smell 165 - Empty Exception Blocks

On Error resume next was the first thing I learned in my first job.


TL;DR: Don't avoid exceptions. Handle Them.

Problems

Solutions

  1. Catch the exception, and deal with it explicitly.

Context

In the early programming days, we privileged the systems running before error handling.


We have evolved.

Sample Code

Wrong


# bad

import logging



def send_email(): 

  print("Sending email") 

  raise ConnectionError("Oops")

  

try:

  send_email() 

except: 

  # AVOID THIS

pass

Right


import logging



logger logging.getLogger(__name___)

try:

  send_email()

except ConnectionError as exc:

  logger.error(f"Cannot send email {exc}")

Detection

  • [x]Automatic

Many linters warn us on empty exception blocks

Exceptions

If we need to skip and ignore the exception, we should document it explicitly.

Tags

  • Exceptions

Conclusion

Prepare to deal with the errors.


Even if you decide to do nothing, you should be explicit with this decision.

Relations

Code Smell 132 - Exception Try Too Broad

More Info

Fail Fast

On Error Resume Next Package

Credits

Photo by James Best on Unsplash

Thank you @Jan Giacomelli

Twitter


Optimization hinders evolution. Everything should be built top-down, except the first time. Simplicity does not precede complexity, but follows it.


Alan Perlis

Software Engineering Great Quotes


5 more code smells are coming soon…