The latest Basecamp for iPhone release involved an immense amount of refactoring with how HTTP requests and HTML pages were rendered. In a previous release, my coworker Sam wrote several methods that didn’t serve to reduce duplication, but instead their purpose was to increase clarity. Since the focus is on comprehension rather than just reusability, it’s easier to understand what is going on and jump in to solve the next problem.

This pattern has been eye-opening, and I’ve been using it to hide implementation details and remove comments explaining what chunks of code are doing. Instead, the name of the method explains what is going on. The gist here to communicate Intention Not Algorithm:

The most important thing about any (without loss of generality) method is what it accomplishes or why one would call it, not how it does whatever it does.

Here’s one example from Basecamp for iPhone of this. Since we make heavy use of web views, we need to keep track of when the page loaded with content. How we accomplish this actually doesn’t matter, but the why matters greatly.

In this method that is mixed into every UIViewController that makes requests via AFNetworking, the intent of remembering when the page loaded feels tangled up with the code surrounding it:

module Browser def enqueue(request) operation = client.HTTPRequestOperationWithRequest(request, success: lambda { |operation, response| normalRenderer.new(self, operation).render(response) @pageLoaded = true }, failure: lambda { |operation, error| fallbackRenderer.new(self, operation).render }) client.enqueueHTTPRequestOperation(operation) end end

All we need is an instance variable to keep track of when a page has been loaded, but if you come back to where that variable is set on its own, it’s confusing. The how doesn’t matter here, but the why does. Let’s try pulling that out into its own intention revealing method:

module Browser def enqueue(request) operation = client.HTTPRequestOperationWithRequest(request, success: lambda { |operation, response| normalRenderer.new(self, operation).render(response) markPageAsLoaded }, failure: lambda { |operation, error| fallbackRenderer.new(self, operation).render }) client.enqueueHTTPRequestOperation(operation) end def markPageAsLoaded @pageLoaded = true end end

Now, the intention is clear and the implementation is just details. A simple attr_writer :pageLoaded could have accomplished the same job, but it still doesn’t give a clear message as to why it was called.

Our recent release focused heavily on improving offline detection. This module’s viewWillAppear method listens for two custom NSNotificationCenter events that fire when the device goes on and offline:

module Offline def viewWillAppear(animated) super on "WentOffline" do |notification| showOffline end on "BackOnline" do |notification| restoreFromOffline end end def showOffline if isPageEmpty OfflineRenderer.new(self).render markPageAsLoaded end end def restoreFromOffline request if client.isInactive end end

I could have shoved the code for what happens when the device switches states into their respective blocks, but now the intent is clear. Did the device go offline? Show the offline page (unless if something was on the page previously). We’re back online? Restore the controller from the offline state by requesting the page again.

Give this a try the next time you come across some code or a comment that covers What But Not The Why, instead of leaving it as a knot to unravel months later.