Originally coined by Kent Beck, according to Martin Fowler “a code smell is a surface indication that usually corresponds to a deeper problem in the system”. The idea of code smells is they are patterns or anti-patterns that are easy to identify and show the code needs to be reviewed in that area when refactoring your code.
Research by Tufano et al. found that there is empirical evidence for the consequences of “technical debt” but only anecdotal evidence as to how, when, or why this occurs. Code smells provide a quick way for even junior developers to review their code and find areas they can improve to reduce the technical debt.
A Rose By Any Other Name
Naming conventions will vary depending on the language, framework, and even coding standards at work. However there are a few smells that will alert you to potential debt if not corrected. These typically have to to with too much or too little information in the name.
10:24 Type Embedded in the Name
“Hungarian notation: I don’t know why they dislike Hungarians enough to pin the name on them.”
In these smells the type is part of the method name creating a redundant naming convention. You have to change the name if you change the type which adds complexity to refactoring. Name your methods based on what they do not what they produce
14:25 Uninformative Naming
“Something I did in high school was name my methods and variables so it told a story.”
Method names do not describe what the method does. Other developers should be able to read the method names and have a general idea of what that method does. Rename or rewrite methods to quickly convey the functionality of the method in the name.
18:07 Inconsistent Naming
This occurs when naming does not match throughout the app; Switching naming conventions throughout the code. This is confusing to other developers who may be looking for something based on one naming convention. It can occur because different developers worked on different areas or it could also come from refactoring or adding features later.
Pick a set of standard terminology and stick with it. If working on legacy code look for the standard or most commonly used standard. Decided on a team standard if working with other developers.
Do Something Already!
These dispensable units of code can be removed from the code base without hindering functionality. Absence of these creates cleaner and easier to understand code. These do not have fixes as they just need to be removed.
23:53 Dead Code
“The compiler is removing it anyway, typically.”
Anything that is not being used anywhere in the app. Requirements change and corrections in the app have to be made. Usually old code is commented it out until the new code passed testing yet here nobody took the time to remove the old code. They could also come from branches of conditionals that are no longer reachable.
“I remove commented code every time I see it.”
Delete the old code. If commented out for a reason create a feature branch with the old code. A good IDE can help find dead code.
28:35 Redundancy Again
More than just duplication, this is when two classes or methods do the same thing. Though the easiest to find is duplicate code because it looks the same. More insidious is when two separate areas of code have the same functionality but were written by different developer and have different code.
Usually redundancy happens when multiple developers work on different areas with the same problem unaware of each others efforts to solve the problem. More subtle when the code isn’t duplicated but the functionality is.
“If they both find different StackOverflow articles.”
DRY out your wet code. Combine functionality when possible. Extract the code into a method you can call if within the same class. If it’s in two different classes consider pulling out that code and creating a new class.
30:25 Speculative Generality
“YAGNI: You Ain’t Gonna Need It'”
These are unused classes, methods, parameters, etc that are created as a just in case because you are anticipating future features that never get implemented. Code grows to a point of being impossible to understand and support.
Write your code to solve today’s problems. If you find speculative code remove it. Worry about tomorrow’s problems when they arise.
36:06 Lazy and Data Classes
A data class is one that only contains data. They are simply containers used for other classes and cannot independently operate on the data they own.
“Basically a data class is a bag of state.”
A lazy class is one with minimal functionality. It may have had more then through refactoring diminished. It could also have been speculative or part of future development that never finished.
In both cases reduce the code size by combining these with other classes. Move the data or features to another class that is using them. Collapse inheritance hierarchies if needed.
41:58 Excessive Comments
“Comments are like deodorant masking the smell of fishy code.” ~ sourcemaking.com
This occurs when methods are filled with explanatory comments. Comments should explain the why not the what.
If the code can’t be understood without comments it needs to be refactored. Sometimes you are writing very complex algorithms like GIS conversions that need comments to help explain the math. Split up complexity to avoid over commenting to explain it.
Bloated or Too Much Useful Code
“It’s like a smell in your house. If you live in filth you’re used to it but if a guest comes over…”
These are classes or methods that have grown to such a large size they are difficult to understand and work with. The smells here aren’t the most obvious at first as they tend to grow over time. You’ll find them more in older code bases than in newer code.
48:37 God Class
God classes are classes with too much code or too much control. Classes started off small but over time grew out of control or more accurately grew to control everything. These break the single responsibility principle in Object Oriented Programming.
“You’ll see this with utility classes a lot.”
Split up the responsibility of these classes to allow for more readable code so developers don’t have to remember a lot of attributes for a single class. This also helps to avoid duplication of code within the large class.
50:48 Long Methods
“You kinda have to adjust this based on language.”
If it has more than 10 lines of code it smells and you should start looking into breaking it up. Like God Classes these grow over time. It’s easier to write code than to read it. There is a mentality that it is harder to create a new method.
“It’s easier to write code than to read it.”
Extract out code in the method that does it’s own thing and create a new method. Shorter methods and functions are easier to understand and last longer. Long methods can hide replication of functionality.
53:51 Long Parameter List
You’ll notice this smell when too many parameters are passed into a method. If passing more than three or four the list starts to smell.
This can come about in several ways. Several algorithms were merged into a single method or it could be the byproduct of making classes more independent.
Instead of a long list of parameters pass in objects with the parameters in them. Be careful when fixing this that you don’t create a bunch of temporary fields. Use the data in the method’s object where possible.
TinkerKit is a tool based on Arduino that simplifies the process of making interactive products. It’s a platform designed for education that simplifies the process of programming an Arduino. No need for advanced knowledge of physics or engineering, kids and hobbiest can get in and start playing around with preassembled sensors and actuators.
Tricks of the Trade
Avoid giving too much detail even outside of coding. For example if your manager is not a coder going into implementation details will likely bore them and could make you look like you are not confident. You will appear to be attempting to baffle them with technical detail.