VIDEO: Principles of Refactoring

Chapter 2 of “Refactoring, Improving the Design of Existing Code” by Martin Fowler, titled “Principles of Refactoring,” continues to set the stage for the rest of the “recipe book” of refactorings by explaining some of the basics of refactoring, including:

  1. Why you should refactor your code
  2. When you should refactor your code, and
  3. Problems that could arise when refactoring your code

Here’s my perspective on the chapter:

Video Transcription:

Hey what’s up everybody, I’m Andy, the Clean Swifter. Welcome back to the second 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 two of Martin Fowler’s book, “Refactoring, Improving the design of existing code.” The second chapter is titled “Principles of Refactoring.” You can buy the book through my Amazon affiliate link in the description for this video. In this chapter, Fowler covers three important topics, first: why you should refactor your code. Second, when you should refactor your code. And third, potential problems to be aware of when refactoring your code.

Before we jump in, let’s just recap as to the definition of refactoring. Paraphrasing how Fowler puts it at the beginning of this chapter, refactoring is the process of improving code while making no observable changes in behavior. In other words, improving your code, while not changing how it behaves to the end user. You can actually use the word refactor as both a noun and a verb, for example “That refactoring really improved my design” or “let’s go refactor that method to clean it up.”

Now that we’re clear on the definition, let’s dig into the first topic, why you should refactor your code. I know to some people this may be kind of obvious, but let’s talk about it just to be clear. You should refactor your code because it helps you improve its design. By helping improve its design, it will become easier to understand, bugs will be easier to find, and you’ll ultimately be able to add functionality faster. All of these reasons relate to eachother. Messy code will have more bugs. Additionally, because it’s messy, you’ll spend more time trying to find and fix the bugs, and thus spend less time adding end user features. If code is hard to understand, you’ll be slow to enhance it, and when you do, chances are you’ll be adding bugs because you don’t know the true impact of your change. Refactoring aims to solve each of these problems.

Let’s move on to the second important topic, when you should refactor your code. Fowler sums it up simply as “the rule of three.” The first time you do something, you just do it. The second time you do something similuar, you duplicate the first time while wincing. The third time you do something similar, you refactor and remove all the duplication. Think of it as: three strikes and you refactor. I think this is a nice metaphor, but I don’t think I’d live with the first duplication. Any duplication smells to me, I’d probably refactor at that point. When else might you refactor, well any other time that you’re modifying code such as when you’re adding funcitonality, or fixing a bug. Both of those are great times when you can get in and improve the internal structure of your code, while also adding or fixing something in the meantime. Fowler goes on to advocate refactoring during code review. I’m not such a big fan of that, and I think this is another area where the book is showing its age. Today, in a world of github pull requests, code reviews are very common, and I put it on the original author to ensure that the code is in good shape prior creating a pull request for it to be merged into the main code base. In my software collaboration, I’ll usually have worked out the design ahead of time so there aren’t any surprises or really opportunity for further improvement when code review happens.

Finally, the third important topic in the chapter 2 of Fowler’s “Refactoring, Improving the design of existing code” is recognition of some problems that can occur when refactoring. One common thing I run into all the time is a constraint put onto my apps by the backend API. Fowler makes the comparison with a “database” but I’ll move the analogy into something a little more real for apps. As app developers, we need a really solid layer of abstraction between our apps and the backends that you may use, and in my case this is commonly remote web APIs. Otherwise, any refactoring you encounter is going to be constrained by that API and potentially limit what you can do. Similarly, another thing you can run into is if the code you are refactoring is part of a library consumed by others, like a cocoapod, you need to be really careful when performing refactorings that will change that public interface. Doing so will impact any consumers of your API. You need a good migration strategy for them. And another case where you simply shouldn’t refactor, is if the code starts off in a bad or buggy state. If this is your starting point, you should correct any errors first, and then once you have passing tests that cover the error cases, move on to your refactoring.

Those were my big takeaways from chapter two, “principles of refactoring.” Depending on where you are with your refactoring adoption, over time and with practice, it will soon become second nature to constantly be looking for places to improve the structure of your code while ensuring that how it behaves doesn’t change. You’ll even start to integrating refactorings into your thought process while designing your code, before you even write a single line.

Looking ahead to chapter 3, it’s title is “bad smells in code.” Fowler puts some definition around things to look for in code that should be refactored. I hope you enjoyed this video from cleanswifter.com. until next time, happy cleaning.

Chris Eidhof on Table View Controllers

Are you following Chris Eidhof? If you’re not, you should be. He first came across my radar a couple years ago when was part of the founding team behind objc.io. I loved the monthly issues of objc.io, and I definitely recommend going to check out their back catalog if you haven’t already (despite some of it being written in Objective-C). I also really like Deckset, an app Chris made for easily creating beautiful presentations. And finally, I also read his book Functional Swift which honestly might have been my first formal introduction to real world functional programming outside of some academic exercises during my education.

Recently, Chris gave a talk at try! Swift in Japan titled Table View Controllers in Swift. I wanted to bring the talk to your attention because I think it’s a good example of refactorings and improvements you can make while implementing a table view controller in Swift. Go take a look.

My Highlights

Custom Initializers For View Controllers

It’s so easy to get sucked into the world of Interface Builder. Don’t forget that there is life outside it. Chris provides some solid examples of how you can leverage custom initializers for UITableViewControllers to provide the initial set of data, and even closures for populating table view cells. Nothing revolutionary here, but again, something easy to forget if you are always living in a world of Interface Builder.

Fix All In Scope

Do you know about this magical Xcode tool? I didn’t until I watched this talk. In a lot of ways, this is why watching talks are worth their time in gold. Even if the talk itself isn’t on a topic you’re totally into, just watching someone else code can yield so many little tips and tricks that will help you improve your own development. During this presentation, I learned from Chris of the option in Xcode to “Fix All In Scope.” I’ve only tried this in a couple cases, and it is magical. As you are coding, you’ll forget to force unwrap an optional, or something that was originally declared a constant with let now needs to be a variable with var. Xcode can automatically fix a lot of these issues for you, and there’s actually a menu option with an accompanying keyboard shortcut- Command-Option-Control-F. Give it a try.

Screen Shot 2016-05-26 at 8.58.48 PM

Refactoring View Controllers Crosses a Line

Watching this video with a co-worker, he said something that I agreed with. A lot of videos you watch, and blog posts you read, about refactoring view controllers, eventually cross a line from being useful to academic. I feel like this happened in the later part of this talk. Eventually the generalizing and refactoring led to a point where no two screens in an app are going to be so similar that you can use a single view controller implementation and be able to entirely reuse it. Despite that, there are plenty of things to be learned from “academic” implementations.

Refactor Out State

One pattern I really love in Swift that comes from functional programming is being able to use computed properties to help define the “truth.” Here’s an example:

var history:[String]? = nil
var canUndo: Bool {
  get {
    return (history == nil)
  }
}

This is similar to what Chris shows in his presentation for managing a history of changes to an editable table view. What I like about this, is that pre-functional programming, and back in Objective-C, I would create a instance boolean variable canUndo that gets set to true or false throughout the flow of code based on changes to the table view’s contents. That code is super prone to bugs, particularly because ensuring that canUndo is the correct value in all cases. By using a computed property like this to consolidate the truth in one place helps remove that uncertainty and proneness to bugs.

Refactoring A Complicated Initializer

As Chris moves through his refactoring of a table view controller, at one point he arrives at a custom initializer for the table view controller that has many parameters. Besides being hard to read, it also doesn’t really lend itself to testing that well. Chris’s refactoring creates a struct that represents each parameter in the custom initializer. Now, just one thing to pass as a value to the initializer whether from calling code, or the tests. Easy, and concise.

Try It Yourself

I’d love to hear what you think after watching the video, what were your takeaways?

Happy cleaning.

“Refactoring, Improving the Design of Existing Code” Chapter 1 Highlights

I’m really excited to announce the cleanswifter.com online book club! Participate by reading, or just follow along as I go through the best books in programming, chapter by chapter, week by week. Each Monday, I’ll post a video recap of the latest chapter. The video will include both my personal commentary, as well as live coding examples. For the first book, I’ll be re-reading “Refactoring, Improving the Design of Existing Code” by Martin Fowler. Here’s episode one!

Video Transcription:

Hey, what’s up everybody, I’m Andy, the Clean Swifter. If you haven’t seen it yet, check out my blog at cleanswifter.com where I share tips, tricks, articles, and commentary on how to write cleaner Swift code.

Today I’m really excited to kick something new for cleanswifter.com, videos! Specifically, I’m starting an online book club with you, where each week, I’ll read a chapter in a book, and then post a video demonstrating important topics from the chapter. If you want to read along with me, great, if not, no worries. We can still have a great conversation about the book and the topics regardless.

For the first book, I’m going to be covering “Refactoring, Improving the Design of Existing Code” by Martin Fowler. You can buy it on Amazon, just use the link in the description for this video. I actually read this book years ago in a different world when I was writing server side Java code for a giant web application. I love this book, aside from it being a kind of recipe book for refactorings, it comes with this really cool ribbon that you can use as a bookmark. I have no idea why more books don’t have these ribbons.

I just finished reading Chapter 1, and like most programming books, it doesn’t really teach anything yet, as much as it sets the stage for the rest of the book. One thing I want to get out the way right off the bat is recognition that this book is OLD! It was published in 1999, and now going back to re-read it, certain things in the book are showing their age, not including the technical information. For example, in Chapter 1 Fowler sets up a problem domain where you are building a system for use in a movie rental store. I don’t about you, but I can’t even remember the last time I was in an actual movie rental store. Additionally, at one point, he also mentions “limitations of Java 1.1.” Umm, I think Java is on version 8 now. Regardless, this book is about the patterns and recipes, not the technology used for implementation. Keep that in mind as we go through the book because what’s taught in it, absolutely applies to the Swift code you are writing for your iOS apps.

Another thing that Fowler comes right out and recognizes in chapter 1, is the difficulty in choosing a sample project to use for a refactoring book. Often, refactoring is most important in large, complex systems. Unfortunately, using a project of such magnitude in a book isn’t feasible. You would spend the majority of the time just describing the project itself. On the other end of the spectrum, with simplistic code bases, refactoring seems trivial and pointless. One thing that Fowler asks the reader to keep in mind, and I’m going to ask you to as well, is to imagine the examples we go through as part of a larger and more complicated system.

Throughout chapter one, Fowler goes through a whirlwind tour of several refactorings to improve an initial structure of the video rental system. Since the book will later go through these refactorings in detail, I’m don’t think it’s worth mentioning at this point.

As Fowler sets up the rest of the book, four important points about software design stuck with me: what Fowler calls: “the first step in refactoring,” the need to rename variables and methods as refactoring progresses, how refactoring can actually increase the size of your code base, and finally the need to force yourself not to abort a refactoring because you are prematurely optimizing your code.

Diving into the what Fowler calls “the first step in refactoring.” If you’ve been following me at cleanswifter.com you could probably guess what this is: writing tests. Just like anytime that you are setting out to write or change code, the first thing you need to do is write a test. This follows two categories: tests for the existing code, and writing a test for the expected result of the change. Now when refactoring, you often aren’t changing behavior, so an existing test base can be sufficient, as long as you’re confident that it’s comprehensive. And then, as you move forward with each small change in your refactoring, absolutely run your test suite with each code change to make sure you didn’t break anything, as well as figure out if there’s additional tests you can write for further verification.

The second thing that Fowler mentions in chapter 1 that resonated with me, was the need to rename variables and methods as you move forward with your refactoring. Specifically, he says, “Code that communictes its purpose is very important.” I absolutely agree with this. Please don’t use a variable named “i” – it gives no indication what it does. Additionally, name your tests well. My proposed format for test names captures: what is being tested, what is the expected outcome, and under what conditions. For example, “testViewDidLoad_SetsNameLabel_WhenNameProvided.” And just as good clean code communicates its purpose well, good clean tests do the same. Tests serve as functional documentation.

The third topic Fowler identifies in chapter 1 that I like is how one of his refactorings actually increased the number of lines of code in the project. This is totally valid, and something I’ve seen time and time again. Sometimes you start out with a 1000 line UIViewController, and after a number of refactorings, you get that view controller down to 250 lines of code, but created an additional 1000 new lines in addition to the other 750 lines that also got moved. This is a good thing. The goal isn’t to write less code, it’s to write clean code. I’ve seen single lines of Perl code that do more things than you can imagine, but it’s entirely complicated and difficult to mentally parse.

Finally, the fourth thing that jumps out at me as chapter 1 sets the stage for the rest of the book, is recognition of the urge to prematurely optimize your code. In one example, Fowler refactors a method with a single loop. The new implementation results with two additional while loops. As important as it is to recognize the POTENTIAL performance impact this could have, it’s also just as important to understand that it is only a POTENTIAL performance impact, and that when refactoring, don’t necessarily let a potential performance impact stop you from the refactoring. If anything, move forward with the incremental step towards code cleanliness while following it up with actual performance testing to quanitify its impact on speed.

In closing chapter 1, Fowler recaps that refactoring leads to “better distributed responsibilities and easier to maintain code.” Me, I just call this, “clean code.” One other thing I wanted to call out, a lot of these refactorings are done in light of object oriented design. Keep in mind, these all apply to your Swift iOS code. Just because Swift can support functional language paradigms, doesn’t mean that that’s the only way to write it. These are are all just tools in our toolbox to writing cleaner swift.

Looking ahead to Chapter 2, it’s title is “Principles of Refactoring” and moves towards establishing some common language and rationale for refactoring. I hope you enjoyed this video, the VERY first one from cleanswifter.com. Until next time, happy cleaning.

Blending Cultures: The Best of Functional, Protocol-Oriented, and Object-Oriented Programming

realm.io recently posted a video that really resonated with me. The video was of a presentation by Daniel Steinberg at the 2016 try! Swift conference. His presentation was titled “Blending Cultures: The Best of Functional, Protocol-Oriented, and Object-Oriented Programming.”

What I Liked

I’ve been having some self doubt lately, specifically around what feels like an overwhelming mountain to climb to re-program my mind to think in a functional way.

blending cultures

I’ve certainly made progress, and as I’ve written before, one of the main reasons I started this blog was to capture my learnings along the way in that area. A year ago, reading Functional Swift by Chris Eidhof, Florian Kugler, and Wouter Swierstra I kind of had my world turned upside down. It was really what first opened my eyes to this new way of programming. Fast forward to today, as these new functional techniques gain more and more appeal in my mind, I start to wrestle with the question, “Well what about all that object oriented stuff I learned and have so much experience with?” I spent many many years in Object Oriented languages (Java and Objective-C). It’s where a lot of my go to tools in my toolbox are still based. So, are those all just obsolete in this new way of programming? While no one is saying so specifically, I do hear a lot of things like “Try to write code in the Swift way.” Or I see sample Swift code that is heavily functional. And I’m still unsure what a monad is, and forget about a monoid. It quickly becomes over my head.

It was very refreshing to hear someone I respect, Daniel Steinberg, present a compelling argument that these programming paradigms not only can live together, but also lead to a more compelling system design. Each tool should be appropriately used.

When all you have is a hammer, everything looks like a nail. And maybe that’s where, before really making the functional (or even protocol-oriented) shift, you see a problem and immediately think: composition! Or, inheritance! Watching this video, now I feel reassured that there’s room and even good purpose for some of those older trusty tools (object oriented programming).

I Owe A Lot To Daniel

Back in 2008, when I was just diving into iOS programming, I attended a course by the Pragmatic Studio taught by Daniel Steinberg and Bill Dudney. It provided a critical foundation of learning, and really introduced me to the community of iOS development. I loosely maintained a relationship with Daniel too. About a year later, I hired him through Pragmatic Studio to come teach a similar course on iOS engineering at my employer for others to learn as part of our efforts to kickstart mobile development. Then fast-forward about five years, and we crossed paths again at CocoaConf 2014 in Boston where he put on a spectacular day long introduction to Swift, and then gave an incredibly passioned keynote during the conference. Thank you Daniel for everything, if it wasn’t for you, I wouldn’t be where I’m at right now. I continue to learn from you.

Happy cleaning.

WWDC 2013 – Testing in Xcode 5

Ya’ll have it so easy with the tools that come with Xcode 7 to enable high quality code. Back in the day, Apple didn’t even recognize automated testing during WWDC (though tools were available in Xcode). It wasn’t until 2013 that a dedicated session to automated testing made the WWDC agenda. For posterity, go take a look:

WWDC 2013 – Testing in Xcode 5

or if you prefer, you can read it here.