VIDEO: Bad Smells in Code

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:

Video Transcription:

Hey what’s up everybody, I’m Andy, the Clean Swifter. Welcome to the third video episode from my blog, 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 until next time, happy cleaning.

TDD in Xcode – Can’t Refactor Swift Code

Red. Green. Refactor. That’s how I’ve memorized the steps for test driven development. Uncle Bob breaks them into a little more detail if you’re interested in something a little more long form. TDD in Xcode is pretty seamless, until you get to the refactor step. Xcode can’t automatically can’t refactor Swift code.

Refactoring Is Broken For Swift Code

Xcode does not currently support any refactoring of Swift code. If you attempt to use Xcode’s builtin refactoring tools, you see this:

Can't Refactor Swift Code

. From my earliest days of writing Swift, this has gotten under my skin. This is friction to my flow. I want my IDE to make it feel like I’m coasting downhill, rather than going up an incline.

Can't Refactor Swift Code

Additionally, I also take this as a sign at Swift’s maturity. I’ve since come to see the light, and no longer question Swift’s long term viability, but either way an error message like this should be embarrassing for Apple. And then the fact that it hasn’t changed in almost 2 years…

For more context, if you right click in Swift code to bring up the context menu, any of the options in the Refactor menu show that error message.

Can't Refactor Swift Code

Consider An Alternative – AppCode

This weekend I downloaded App Code by JetBrains. I’ve never tried it. Recently it specifically caught my eye that two people I respect, Orta Therox and Jon Reid, evangelize it and use it. JetBrain’s IDEs are renown for the abilities to support test driven development and refactoring. I’m looking forward to giving it a go. I’m in the 30-day trial right now, and I’m committed to learning all it has to offer to make my own impression. So far, I’ve been able to open a non-trivial project and run it in the iOS simulator, no issues. Next, I’m going to do some research about how to best use it, what it offers, and immerse myself in it. I’ll report back here along the way with my findings. I’m just hoping that while Xcode can’t refactor Swift code, I have better luck with AppCode.

Happy cleaning.