GAZAR

Principal Engineer | Mentor

Refactoring Bad Smells in Code

Refactoring Bad Smells in Code

Bad Smell is a term that has been used for messy or dirty coding, this term says there is part of the code that needs to be cleaned in term of future.

In this article after publishing what refactoring is, I want to describe what are the known smell codes, then you can find them and fix them.

“If it stinks, change it.”

— Grandma Beck, discussing child-rearing philosophy

Mysterious Name

Puzzling over some text to understand what’s going on is a great thing if you’re reading a detective novel, but not when you’re reading the code.

Duplicated Code

If you see the same code structure in more than one place, you can be sure that your program will be better if you find a way to unify them.

Long Functions

In our experience, the programs that live best and longest are those with short functions. Programmers new to such a code base often feel that no computation ever takes place — that the program is an endless sequence of delegation.

Long Parameter List

In our early programming days, we were taught to pass in as parameters everything needed by a function. This was understandable because the alternative was global data, and global data quickly becomes evil. But long parameter lists are often confusing in their own right.

Global Data

The problem with global data is that it can be modified from anywhere in the code base, and there’s no mechanism to discover which bit of code touched it.

Mutable Data

Changes to data can often lead to unexpected consequences and tricky bugs. I can update some data here, not realizing that another part of the software expects something different and now fails — a failure that’s particularly hard to spot if it only happens under rare conditions.

Divergent Change

We structure our software to make change easier; after all, software is meant to be soft. When we make a change, we want to be able to jump to a single clear point in the system and make the change.

Shotgun Surgery

Shotgun surgery is similar to divergent change but is the opposite. You whiff this when, every time you make a change, you have to make a lot of little edits to a lot of different classes.

Feature Envy

When we modularize a program, we are trying to separate the code into zones to maximize the interaction inside a zone and minimize interaction between zones.

Data Clumps

Data items tend to be like children: They enjoy hanging around together. Often, you’ll see the same three or four data items together in lots of places: as fields in a couple of classes, as parameters in many method signatures.

Primitive Obsession

Most programming environments are built on a widely used set of primitive types: integers, floating point numbers, and strings. Libraries may add some additional small objects such as dates. We find many programmers are curiously reluctant to create their own fundamental types which are useful for their domain — such as money, coordinates, or ranges. We thus see calculations that treat monetary amounts as plain numbers or calculations of physical quantities that ignore units.

Repeated Switches

We now focus on the repeated switch, where the same conditional switching logic (either in a switch/case statement or in a cascade of if/else statements) pops up in different places. The problem with such duplicate switches is that, whenever you add a clause, you have to find all the switches and update them.

Loops

Loops have been a core part of programming since the earliest languages. But we feel they are no more relevant today than bell-bottoms and flock wallpaper. We disdained them at the time of the first edition — but Java, like most other languages at the time, didn’t provide a better alternative. These days, however, first-class functions are widely supported, so we can use Replace Loop with Pipeline

Lazy Element

Sometimes, it’s a class that used to pay its way, but has been downsized with refactoring. Either way, such program elements need to die with dignity.

Speculative Generality

You get it when people say, “Oh, I think we’ll need the ability to do this kind of thing someday” and thus add all sorts of hooks and special cases to handle things that aren’t required. The result is often harder to understand

Temporary Field

Sometimes you see a class in which a field is set only in certain circumstances. Such code is difficult to understand because you expect an object to need all of its fields.

Message Chains

You see message chains when a client asks one object for another object, which the client then asks for yet another object, which the client then asks for yet another object, and so on.

Middle Man

This can go too far. You look at a class’s interface and find half the methods are delegating to this other class.

Insider Trading

Modules that whisper to each other by the coffee machine need to be separated by using Move Function and Move Field to reduce the need to chat.

Large Class

When a class is trying to do too much, it often shows up as too many fields. When a class has too many fields, the duplicated code cannot be far behind.

Alternative Classes With Different Interfaces

One of the great benefits of using classes is the support for substitution, allowing one class to swap in for another in times of need. But this only works if their interfaces are the same.

Data Class

These are classes that have fields, getting and setting methods for the fields, and nothing else. Such classes are dumb data holders and are often being manipulated in far too much detail by other classes.

REFUSED BEQUEST

The smell of refused bequest is much stronger if the subclass is reusing behavior but does not want to support the interface of the superclass. We don’t mind refusing implementations — but refusing interface gets us on our high horses.

COMMENTS

Comments lead us to bad codex Our first action is to remove the bad smells by refactoring. When we’re finished, we often find that the comments are superfluous.

When you feel the need to write a comment, first try to refactor the code so that any comment becomes superfluous.

To Conclude

Writing clean code feels good and knowing how professionals are doing it helps us to write better code.

In the future, I will write an article about refactoring methods.

“Programs must be written for people to read, and only incidentally for machines to execute.”

― Harold Abelson

Most of these contents are coming from my reading of Martin Fowler book for refactoring. I summarised and pointed to paragraphs of the book!

Once in a while, I review this article for myself to memorize these methods. Happened to be so useful for me.

Enjoyed the article? Follow me!

Have an opinion or comment? Type it!