Chapter 3 of “Refactoring, Improving the Design of Existing Code” by Martin Fowler, titled “Bad Smells in Code” puts definition on when you know to refactor your code.
Here’s my perspective on the chapter:
Hey what’s up everybody, I’m Andy, the Clean Swifter. Welcome to the third video episode from my blog cleanswifter.com, where I share tips, tricks, articles, and commentary on how to write cleaner Swift code. In this video, I’ll be providing some commentary on chapter three of Martin Fowler’s book, “Refactoring, Improving the design of existing code.” The third chapter is titled “Bad smells in code.” You can buy the book through my Amazon affiliate link in the description for this video. In this chapter, Fowler covers a list of specific things, called smells, that should catch your eye and tell you that it’s time to perform a refactoring. I think “Smell” is such an effective word. Often, you won’t know in black and white terms that it’s time to refactor. Instead, your intuition that something isn’t quite right will start to poke at you. Leveraging some semi-formal definition for these “smells” will help you be able to identify them in your code. Throughout the chapter, Fowler actually goes as far to actually suggest specific refactorings in response to various smells. Since we haven’t actually read about what those refactorings are, I’m not going to mention them in any detail yet myself. I was also happy to find that in the back of the book, literally inside on the back cover, is a table reference that lists these specific refactorings that can be performed to correct a bad smell. Here’s a quick tour through some of the code smells that jumped out at me.
The first smell, duplicated code. I bet you’ve seen this one yourself, especially if you’re a liberal copy and paster. It’s name is straight forward. Seeing the same pieces of code sprinkled in more than one place is a clear indication that a refactoring is possible and should happen. One common example might be styling a UILabel. Say some group of UILabels on a page all need a certain look. It’s very easy to copy and paste the common lines of code that set the font, color, and abbreviation style. Unfortunately, when you need to change one attribute of the style, you need to do it in many places, and are likely to miss at least one, thus leaving some labels without the change. Duplicate code is easy to spot. If you see it, you need to address it.
The second smell I wanted to call out is actually three in one: Long methods, long parameter lists, and long classes. Fowler actually lists these are three separate smells, but I’m going to summarize them as one. While there are some slight nuances in how they can be treated, they ultimately represent a piece of code that is trying to do too much. The more lines of code any one “unit” is, whether it’s a method or a class, the harder to understand it will be. Later in the book, we’ll learn refactorings that will help extract common behavior, and break these long pieces of code into separate parts.
The third smells I wanted to mention are shotgun surgery and divergent change. Again, these are granular variation of a common theme: where the need to make one change, results in needing to make many other changes. Divergent change refers to this happening within a single class, where shotgun surgery refers to this happening across many classes. When this smell starts to stink, it’s usually a sign that the single responsibility principle has been violated, or that there is weak encapsulation of behavior. We’ve all gone through this, where we get a request to add a tiny feature, only to find out that there is this cascading amount of changes that are required to implement it.
Feature envy is another common smell. This happens when one class or method, heavily leverages another class, repeatedly, for a wide variety of help in completing a task. See where the name comes from? The class is envious of the features in the other class. This creates an unnecessarily strong coupling between the two classes, which should be avoided when detected. We’ll eventually look at refactorings that help prevent this.
Refused bequest is an interesting smell, one that I’ve come across a bunch with UI code. Refused bequest is when a subclass wants all of the behavior of its parent class, except a certain piece. This happens a lot when subclassing UIKit classes, especially when you start to introduce multiple levels of hierarchy in your own code. Eventually, you’ll create a subclass, where you don’t want the subclass to have all of the behavior of its parent. This is a smell, and rather than code empty methods to override the parental behavior with essentially no ops, you should look to refactor this in a better way.
The last smell Fowler identifies is simply called, comments. And it’s just that, comments in code. I can totally relate to this one. I love how Fowler says that “comments are just deodorant on code smell.” If you find yourself needing to write an extraordinary amount of comments for a piece of code, take that as a sign that there’s probably a refactoring to be done that will help add clarity to the code. That being said, don’t let this stop you from writing comments in your code, just be aware when you all of a sudden write way more than usual for a piece of code.
There were actually a couple more subtle code smells I omitted, and I encourage you to go grab a copy of the book and check them out for yourself.
Looking ahead to chapter 4, it’s title is “building tests.” Fowler puts some clarification around how to build your tests to best support your refactoring. I hope you enjoyed this video from cleanswifter.com. until next time, happy cleaning.