Kent Beck introduced the new term “code with smell” to explain the application issues.
It is often used by programmers and testing engineers when they discuss refactoring. “Code smells” is not a bug, it indicates issues in the code. It is a signal that something needs to be improved.
Can refactoring help in this situation?
“Refactoring is the process of changing a software system in such a way that it does not alter the external behavior of the code yet improves its internal structure.” — Martin Fowler, who has shed the light on the refactoring process in his masterpiece Refactoring: Improving the Design of Existing Code.
It should be emphasized that refactoring to abstractions is not always the proper direction as it may generate more complexity in the system and may become a code smell in itself. The code may not be complicated enough to benefit from certain abstractions.
Code that smells can lead to:
- serious defects in the program
- non-reproducible defects that complicate functional testing, safety testing, performance testing and other tests, as well as further project progress
- system malfunction
Therefore, experts engaged in mobile testing, desktop testing and testing sites, usually insist on that a code with a smell is found and removed as soon as possible. Refactoring is done in order to eliminate code smells. But first, you need to find them in the system. There are tools that help determine the code smells, but it is unwise in this case to fully rely on any of the tools. The best way to find code smells is to use the experience and intuition of programmers.
In his wonderful book Refactoring: Improving the Design of Existing Code, Martin Fowler describes a lot of different “code smells”. In this article let’s consider the list of the “smells” proposed by Martin Flower.
It is highly inappropriate to post information in comments that is more convenient to store in other sources: in a source code control systems, version control systems, and other logging systems. For example, the change history only clutters up the source files with long historical and uninteresting text. Metadata (authors, date of last modification, etc.) in the general case is also irrelevant in the comments. Comments should be reserved for technical information about the code and its architecture.
Comments that have lost relevance, is considered outdated. Comments get old pretty quickly. Do not post comments that will become obsolete over time. If you find an outdated comment, update it or get rid of it as soon as possible. Outdated comments often “break away” from the code they once described. So in your code, there are floating islands of unreliability and worthlessness.
Poorly written comment
Please write your comments well. Take the time and take care that this is the best comment you can create. Choose your words carefully. Keep track of spelling and punctuation. Do not write messy. Do not explain the obvious. Be concise.
Redundant is a comment that describes what is so obvious. Comments should say what the code itself cannot say.
The commented code
Who knows when this code was written? Who knows if there is any good from it or not? However, no one removes the commented code – everyone believes that it will be needed by someone else.
This code only wastes place and loses relevance with each passing day. It calls non-existent functions. It uses variables whose names have changed a long time ago. It respects outdated conventions. It pollutes the module in which it is contained, and distracts people who are trying to read it. Commented code is disgusting. After seeing the commented out code, delete it. Don’t worry, the source control system will not forget it. If someone really needs this code, he will be able to return to the previous version. Do not let the commented code spoil your life.
Project building involves several phases
Project building should be one trivial operation. Without sampling numerous fragments from source control. Without a long series of unintelligible commands or context-sensitive scripts for building individual elements. Without searching for additional files in the format of JAR, XML and other artefacts necessary for your system. First, you check the system with one simple command and then enter another simple command to build it.
All other things being equal, a shorter method is easier to read, easier to understand, and easier to troubleshoot. Refactor long methods into smaller methods if you can.
This is one of the most important rules in the book and should be taken very seriously. Dave Thomas and Andy Hunt called it the DRY principle (“Don’t Repeat Yourself”). Kent Beck made it one of the basic principles of extreme programming in the formulation “Once and only once”. Ron Jeffries puts this rule in second place, after the requirement to pass all tests.
Every time a repeating code occurs in a program, it indicates a lost opportunity for abstraction. Perhaps a duplicate could become a function or even a separate class. By “folding” duplication into such abstractions, you expand the programming language lexicon.
Other programmers can take advantage of the abstract concepts you have created. Increasing the level of abstraction speeds up programming and reduces the likelihood of errors. The simplest form of duplication is pieces of the same code. The program looks as if the programmer’s hands are shaking, and he inserts the same piece again and again. Such duplicates are replaced by simple methods.
In fact, most design patterns that have emerged over the past 15 years are well-known ways of dealing with duplication. Normal Codd forms eliminate duplication in database schemas. Object-oriented programming itself can be considered as a strategy for a modular organization of code and the elimination of duplicates.
Large classes, like long methods, are difficult to read, understand, and troubleshoot. Does the class contain too many responsibilities? Can the large class be restructured or broken into smaller classes? Refactoring of these classes spares developers from needing to remember a large number of attributes for a class. In many cases, splitting large classes into parts avoids duplication of code and functionality.
Code smells can be recognised by their visible, physical and metaphysical signatures. Visible signatures include: long method or function bodies, long parameter lists, groups of a variable that appear multiple times in similar patterns–these are symptoms of mixed responsibilities and missing abstractions.
Physical signature is where change involves navigating-through and modifying many files. Metaphysical signature is when you are asking questions like, “why am I inheriting from this parent class when I do not share the same behaviour”.
It takes practice and experience to recognise code smells. There are many exercises and katas to help you practice. Code smells are a symptom; they generally reveal that you are breaking some design principles. Knowing these principles helps to understand what is wrong with your code base.