Thursday, August 30, 2012

Recordings Are Coming, I Promise

I've given this Clean Code presentation of mine at work a couple of times. It's pretty simple, just a sort of intro into Robert Martin's book, and it's mainly targeting junior developers. But it's been very well-received at work and so I figured I'd do a screencast of it to share more widely. Indeed, I've been wanting to do screencasts of other things as well, so this will be a good first step into that medium.

As it turns out, this is really bloody difficult to do. I've been recording take after take, always finding something wrong. Editing isn't exactly a perfect process either, since I'm not satisfied with it if it doesn't seamlessly line up. So I continue to try these takes over and over.

A phone rings in the background, the kids come into the room and require attention, I stammer or make a mistake, the battery on my presentation tool runs down, I try taking the laptop somewhere else to do a quick recording attempt but the battery runs low, other system notifications pop up, etc.

This is hard. By comparison, actual public speaking is a piece of cake. You just do it and it's done. But privately recording something for public consumption, that's a whole other beast entirely. When standing up in front of an audience, a stammer quickly becomes a forgotten thing of the past or a mistake can be corrected. On a persisted medium like a video, that's not acceptable. It's there forever for all to see. Perfection is more critical.

This is going to take longer than I expected.

Friday, August 17, 2012

Addresses in a Post-Google World

It comes up a lot in business applications... How should we design a form to accept addresses? We see all kinds of examples. There's the baseline simple approach:
  • Address
  • City
  • State
  • Zip
Then of course people want to add a second address line, so you end up with the very poorly-named variant:
  • Address1
  • Address2
  • City
  • State
  • Zip
And then, almost inevitably, it spirals out of control from there. Should we separate street number from street name? Street type? County? Country? Should we pre-populate from a table of zip codes? Where do we get that data? How do we keep it up to date? What about other address elements? What about international addresses? Strange middle-of-nowhere addresses that don't fit this model? How does the post office do it? Can we copy their format? Can that format work without the miles of red tape and bureaucracy to support it?

It goes on and on. And, thinking about it now, it's all terribly silly. Why are we still trying to solve this same problem over and over? Every company ends up with its own formats, every format gets broken by some edge case at some point, etc. It ends up being a lot of work, and what's the gain?

Is there a simpler, more universal way?

Well, yes. Google already did it. (And Bing, and MapQuest, etc.) The form is actually quite simple and intuitive:
  • Address
Done. That's it. The user knows how to type their address. They've done it a million times. You don't have to instruct them on the various components that you think their address should have. Just let them type what they've written for years. And you have their address. The address they use as they know it.

But what about the components? What if I want to report on this data somehow and filter records by state or zip or some other metric? Well, that's your problem. It's not the user's problem. Don't give them an ugly form that might not even work for them just because you have some back-end requirement that isn't meaningful to their user experience.

This doesn't mean you can't get this granular data. It just means that you don't need to get it from the user. There are plenty of address locating and geocoding services out there which will give you a hell of a lot more structured data than whatever random business user you assigned to this project would have designed in their bad UX form. Get this data behind the scenes. Don't trouble the user with it.

For example, let's look at the data you get from Google when searching an address:
{
   "results" : [
      {
         "address_components" : [
            {
               "long_name" : "1600",
               "short_name" : "1600",
               "types" : [ "street_number" ]
            },
            {
               "long_name" : "Amphitheatre Pkwy",
               "short_name" : "Amphitheatre Pkwy",
               "types" : [ "route" ]
            },
            {
               "long_name" : "Mountain View",
               "short_name" : "Mountain View",
               "types" : [ "locality", "political" ]
            },
            {
               "long_name" : "Santa Clara",
               "short_name" : "Santa Clara",
               "types" : [ "administrative_area_level_2", "political" ]
            },
            {
               "long_name" : "California",
               "short_name" : "CA",
               "types" : [ "administrative_area_level_1", "political" ]
            },
            {
               "long_name" : "United States",
               "short_name" : "US",
               "types" : [ "country", "political" ]
            },
            {
               "long_name" : "94043",
               "short_name" : "94043",
               "types" : [ "postal_code" ]
            }
         ],
         "formatted_address" : "1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA",
         "geometry" : {
            "location" : {
               "lat" : 37.42310540,
               "lng" : -122.08239880
            },
            "location_type" : "ROOFTOP",
            "viewport" : {
               "northeast" : {
                  "lat" : 37.42445438029150,
                  "lng" : -122.0810498197085
               },
               "southwest" : {
                  "lat" : 37.42175641970850,
                  "lng" : -122.0837477802915
               }
            }
         },
         "types" : [ "street_address" ]
      }
   ],
   "status" : "OK"
}
That sure is a lot of very structured data. Was your random business user who defines the requirements for that form going to be able to get all of that out of the user? What would that form have looked like? It even gives back a "formatted address" in response to something otherwise unformatted based on what it found. So even if the user puts in something that looks messy you can replace it with something cleaner. You even get coordinates for God's sake.

Seriously, stop having your users enter their address components separately. It's as bad as giving them multiple text inputs for the components of a phone number. You don't need that level of granularity in your data, and if you do there are much more comprehensive and much more reliable services to give you that data based on what your users enter into the form.