Bob on Development

February 17, 2007

Seeing What your Users See: User Interfaces And Limited Choice

Filed under: Techniques,UI Design — Bob Grommes @ 11:18 am

Raymond Chen’s The Old New Thing is a must read for anyone creating software that interacts with users. Chen was one of the developers of Windows 95 and the surface reason his book is provocative and interesting is because it exposes a lot of the thinking behind the Windows UI and answers questions that bug people, such as “why do you press the Start button to stop the computer”?

The more compelling usefulness of the book, however, is Chen’s deep experience with how users respond to the user interface. I recently remarked about how a dialog box on the United Parcel Service web site probably is ignored by most users. Chen explains why. In the first chapter of his book, he has the following priceless mock dialog that shows what a user perceives when a dialog interrupts their work:

What a user sees when they read your dialogs.

Chen does not point this out to make fun of users. As he puts it, the problem is that “all the user wants to do is surf the web and send emails to their grandchildren.” The dialog is in the way of that, so it gets swatted away like an annoying fly.

This is a blow to the pride of many developers, who easily forget that their software is not the center of its user’s universe. It is simply a tool, a means to an end.

Developers throw up dialogs because it’s generally easier to let users make decisions than to figure out what needs to be done at a given moment. It is also easier than designing software that is forgiving, resourceful and resilient.

In my original story, I explained that if a UPS shipper specifies a shipment value over some threshold amount, a dialog appears explaining in some detail that because of the shipment’s high value they must obtain an acceptance signature for the shipment from an actual UPS employee. If the shipper doesn’t do this, any loss claims will be invalid. I opined that most users will never register this info, will swat the dialog aside, and buy worthless insurance.

How might this have been better implemented? I would have put it right in the workflow of the wizard that was managing the shipment, rather than interrupt with a notification and an OK button. Then I would give them the choice of reducing the valuation, requesting a pickup, or locating a company store to drop off at — all without losing the context of what they are working on, mysteriously completing the shipment, or otherwise doing anything unexpected. In this case, I’d require more decisions from the user, because it’s the only way to insure they are not just throwing money down a hole.

In most cases, though, it’s better to take some reasonable default action and say nothing at all. For example, usually if a users closes an open document without saving, they meant to save the changes up to that point, so at the very least, the default choice, if you present one at all, should be to save the changes. Instead what we see in most applications is a dangerous default such as not saving changes, or backwards questions that ask if you want to discard changes rather than keep them. Remember, the user isn’t really reading this, so if they just hit the Enter key you probably should err on the side of caution, and not risk throwing away the last forty minutes of work.

Come to think of it, this is why auto save features were probably born; I have long been in the habit of saving my work every minute or two but not all users have that healthy paranoia; a configurable auto-save feature, turned on by default, does that for them.

Users usually don’t want all the nifty choices we think to offer them. Often, these choices cause more harm than good. They should be absent, or hidden behind some kind of “expert” mode.

Think through the features in your user interaction and make them as free of “friction” and fluff and endless choices as you can. Let the user get the critical path of their work done with ease. Save your “interruption capital” for those times when there is something the user truly neeeds to stop and make a decision about … a decision that matters to the user.

January 26, 2007

How to Use Team Foundation Server Source Control with Visual Studio 2003

Filed under: Products,Techniques — Bob Grommes @ 9:33 pm

I’ve just begun work on extending a product that was authored in VS 2003 and is now three years old. The developers wanted to port it to VS 2005 but ran into a brick wall when it was discovered that the client’s old version of Citrix could not cope with .NET 2.0 being installed on the same machine; apparently it caused a complete meltdown requiring a from-scratch reinstall.

In the meantime the developers had standardized on Team Foundation Server (TFS). Rather than face losing the benefits of TFS source control while being stuck (hopefully temporarily) in the VS 2003 world, they came up with a pretty interesting workaround.

1. Put the VS 2003 project into a TFS workspace.

2. In the VS 2005 client, open the Source Control Explorer (View | Other Windows | Source Control Explorer). Right click on the root of the VS 2003 project and do a Get Latest. This downloads all the code to the client system without attempting to open the solution or any of its projects, which would trigger the VS 2003 to VS 2005 conversion wizard, which, if run, would render the projects unusable in VS 2003.

3. From here you work with the project using an instance of VS 2003, using the separate VS 2005 instance to do your check-outs and check-ins.

This is not a bad solution but I wondered … hasn’t someone solved this more elegantly? A quick Google search led me to a Microsoft download that not only allows you to access TFS from VS 2003, but from VS 6, or even FoxPro, Sybase or Toad!

This is heartening in a world where Microsoft doesn’t even support running many of these older but still very much in-use tools on the latest release of its own operating system. I was astounded that they’d even consider telling developers that as recent a product as VS 2003 isn’t and won’t be supported under Vista (although, oddly, VB6 is supported). I was even more surprised that even VS 2005 support will not really be here for months yet, when SP2 is released. Yet, somehow they have managed to support a number of old and even 3rd party tools in TFS. Could it be that at least some people at Microsoft have managed to overcome the Pointy-Haired Ones?

Then it stuck me that supporting these old environments will help sell significantly more TFS licenses, whereas supporting them in Vista will not sell significantly more copies of Vista. Think about it: development teams are 100% of the market for TFS, but probably just a small percent of the total market for Vista licenses. And Microsoft’s thinking is that developers know how to run VMs within Vista anyway, to support old products using old operating systems. Penny-wise and pound foolish, in my view — but no one is asking me.

January 6, 2007

Writing Polite Code

Filed under: Communication,Techniques — Bob Grommes @ 7:09 pm

I ran across a generally excellent essay by Michael Feathers on what he calls Offensive Coding. The essence of his argument is that if you find yourself frequently writing defensive code (he uses checking for null as an example), the root cause may be that the code you’re working on is called by offensive code. In other words, code that forces you to write defensively.

This resonates with me. Some of my clients have been with me for as long as a decade, so I maintain a heck of a lot of code. Some of it is mine, and some of it is not. I’ve never minded maintenance and refactoring as much as most of my colleagues appear to, but one thing I don’t like about maintaining code is the inordinate amount of time I spend either coding defensively, or doing forensic work to document what the heck is going on so that I don’t have to code defensively.

The opposite of offensive code might be called polite code. And it strikes me that one of the features of polite code is that it’s as self-evident as possible and accurately documented. Good code is self-evident as to the “how” of what it’s doing, and documentation in the form of comments and external documents provides the “why”.

I just spent a couple of hours reverse-engineering some code that handles an automatic product version upgrade because I did not want to risk hosing a production system without being sure about how some items in an application config file were set. I shouldn’t have had to do that, but every reference I could find to these configuration items were vaguely worded and not written with the question in mind, “what will be the concerns of the user reading this”?

That happens a lot … documentation frequently answers questions a user would never ask or give a fig about. It states the obvious, or beats the irrelevant to death, but it never addresses a likely real-world question. To be concrete: the meaning of “InstallMemberRole=true” was I’m sure quite obvious to the original author at the time he was in the throes of creating it. And it seems most likely that this item, in the context of the section of a portal framework configuration most likely means that during the installation process, the member role feature will be installed.

What isn’t ever stated is whether this applies to version upgrades, and if so, whether it will blow away an existing user base. God bless Google, I found some people discussing it who said that it would in fact blow away the existing user base. But, those people may or may not know what they are talking about, and besides, isn’t it odd to default this setting on and thus put people’s user bases at risk? And maybe it involves upgrades to functionality that I’d want to weigh the benefits of.

Well, no matter … with over 1500 impatient active users at stake I can’t afford to guess, so I plowed into the code and tracked down the called T-SQL scripts and made damned sure. This is a defensive action I should not have had to undertake.

As I have said elsewhere, English is a programming language too, and this is another example of why that’s so.

December 27, 2006

Proper Casing a String in .NET

Filed under: C#,Techniques — Bob Grommes @ 2:22 pm

Rick Strahl saved me a minor headache today by pointing out a somewhat hidden and arguably misplaced method in the BCL for proper casing strings. Combining that with a small fix provided by one of his respondents (the method doesn’t work if the input string is all upper cased), you get:

private string ProperCase(string s) {
  return System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(s.ToLower());
}

As he aptly points out, it’s all there somewhere in the dogpile, if only you can find it.

Blog at WordPress.com.