Coding Horror

programming and human factors

Head First Design Patterns

I'm beginning to wonder if the book Head First Design Patterns would be better titled Ass Backwards Design Patterns. Here are some quotes from pages 594 and 595 of this 629 page book:

First of all, when you design, solve things in the simplest way possible. Your goal should be simplicity, not "how can I apply a pattern to this problem." Don't feel like you aren't a sophisticated developer if you don't use a pattern to solve a problem. Other developers will appreciate and admire the simplicity of your design. That said, sometimes the best way to keep your design simple and flexible is to use a pattern.

No one ever talks about when to remove a pattern. You'd think it was blasphemy! Nah, we're all adults here, we can take it. So when do you remove a pattern? When your system has become complex and the flexibility you planned for isn't needed. In other words, when a simpler solution without the pattern would be better.

Design patterns are powerful, and it's easy to see all kinds of ways they can be used in your current designs. Developers naturally love to create beautiful architectures that are ready to take on change from all directions.

Resist the temptation. If you have a practical need to support change in a design today, go ahead and employ a pattern to handle that change. However, if the reason is only hypothetical, don't add the pattern. It's only going to add complexity to your system, and you might never need it.

Filling 593 pages with rah-rah pattern talk, and then tacking this critical guidance on at the end of the book is downright irresponsible. This advice should be in 72 point blinking Comic Sans on the very first page.

Beginning developers never met a pattern or an object they didn't like. Encouraging them to experiment with patterns is like throwing gasoline on a fire. And yet that's exactly what this book does. Page 597 outlines how therapeutic it is for beginners to abuse patterns:

The beginner uses patterns everywhere. This is good. The beginner gets lots of experience with and practice using patterns. The beginner also thinks, "The more patterns I use, the better the design." The beginner will learn that this is not so, that all designs should be as simple as possible. Complexity and patterns should only be used where they are needed for practical extensibility.

Do you really want a junior developer using patterns everywhere? It's about as safe as encouraging them to "experiment" with a gas-powered chainsaw. The best way to learn to write simple code is to write simple code! Patterns, like all forms of compexity, should be avoided until they are absolutely necessary. That's the first thing beginners need to learn. Not the last thing.

The book isn't the only thing that's backwards: did you know the Head First girl pictured on the front of the book leads a shocking double life? That's right, student by day, stripper by night. Ok, maybe not ...

Head First Design Patterns book cover   The Head First Girl

... but shocking nonetheless. Perhaps they're referring to the code smell of overcomplicated "explosion at the pattern factory" code this book encourages?

Discussion

A Celebration of The Windows Key

I'm sure everyone knows that the Windows key brings up the Start Menu, but there are also a bunch of standard Windows key shortcuts built into Windows:

windows_key.gif + B

Set focus to first tray icon

windows_key.gif + D

Show Desktop

windows_key.gif + E

Windows Explorer

windows_key.gif + F

Find Files or Folders (aka Search)

 + M

Minimize All windows

windows_key.gif + ShiftM

Undo minimize all windows

windows_key.gif + R

Run...

windows_key.gif + Tab

Select Task

windows_key.gif + Pause/Break

System Properties

windows_key.gif + F1

Windows Help

windows_key.gif + L

Lock workstation

windows_key.gif + U

Utility manager (accessibility)

Where the default Windows key shortcuts end, WinKey* begins. Winkey lets you map additional Windows key shortcuts. It can't override the existing shortcuts, unfortunately, but you're free to map any key that isn't already mapped.

The advantage of the Windows key approach is that all of my most frequently used applications are exactly one key combination away; for example:

windows_key.gif + N

Launches Notepad

windows_key.gif + C

Launches command shell

Of course, you can go a lot further with hotkeys than just overloading the Windows key. That's where something like AutoHotKey comes in. However, I find that leveraging the built-in Windows key shortcuts, plus a handful of Windows key shortcuts I set up myself, covers 98% of my daily computer use.

But then there's that other 2%...

When I can't launch something with the Windows key, I fall back to the Start, Run (Windows+R) dialog. Run is passable, but not as helpful as it could be. Trying to perform a Start, Run, "word" won't launch Microsoft Word, for example. There are a number of third party replacements for Run that attempt to rectify that:

I've tried each and every one of these solutions, but nothing "stuck". I couldn't get myself out of the reflexive habit of Windows+R. Each of these apps has a nice set of additional features far beyond what the run dialog provides, but I never really used them.

In lieu of all these fancy solutions.. wouldn't it be nice if the Start, Run dialog was just a little bit smarter? That's when I stumbled across this blog post describing a very clever hack:

  1. Create a folder for your shortcuts under your user folder, eg, c:documents and settingsusernameshortcuts
  2. Right click My Computer, click properties.
  3. Click the advanced tab.
  4. Click the Environment Variables button at the bottom of the tab.
  5. Under user variables, add a new variable named "Path".
  6. Enter %homedrive%%homepath%shortcuts for the variable value.**
  7. Create shortcuts and plop them in the shortcuts folder you created.

Here's a quick snapshot that shows how to set up the per-user Path environment variable for the shortcuts folder:

How to set the user path variable to reference shortcuts from the Start, Run dialog

Now that I've set this up, I can type Windows+R, 2k3, Enter and Visual Studio 2003 launches! The only disadvantage-- and it's a minor one-- is that there's no autocomplete until you've typed the shortcut at least once. But for me, it's the best of both worlds: I can leverage the default Windows key accelerators and also have an unlimited number of "smart keywords" via my workhorse Run menu.

* Every time I see WinKey, I think of Winky Dinky dog. And I say it in that.. voice. I can't help myself.

** Here's a complete list of Windows XP/2000 environment variables the system can populate for you (eg, %date%). Gotta catch 'em all!

Discussion

Don't Make Me Think, Second Edition

A reader recently pointed out that the second edition of Don't Make Me Think is about to be released. I know I've pimped this book ad nauseam, but I can't help myself-- it's just that good. If you only read one book on usability and UI, it should be Krug's Don't Make Me Think. I even gave it to my wife to read, and she enjoyed it too. Is there any higher praise?

Don't Make Me Think, Second Edition

Unfortunately, Steve Krug's website doesn't have any information on what's new in this version. The yellow sidebar indicates "3 new chapters", but beyond that, who knows.

I'll be getting a copy of the new version for sure. I can keep the old one at home and the new one at work, or I can surprise an unsuspecting manager or fellow developer with the first edition. Now if only I could get them to read it..

Discussion

Usability vs. Learnability

In this 1996 Alertbox, Jakob Nielsen champions writing for the web in an inverted pyramid style:

Journalists have long adhered to the inverse approach: start the article by telling the reader the conclusion ("After long debate, the Assembly voted to increase state taxes by 10 percent"), follow by the most important supporting information, and end by giving the background. This style is known as the inverted pyramid for the simple reason that it turns the traditional pyramid style around. Inverted-pyramid writing is useful for newspapers because readers can stop at any time and will still get the most important parts of the article.

On the Web, the inverted pyramid becomes even more important since we know from several user studies that users don't scroll, so they will very frequently be left to read only the top part of an article. Very interested readers will scroll, and these few motivated souls will reach the foundation of the pyramid and get the full story in all its gory detail.

For some reason, the idea that "content should never appear below the fold because users don't scroll" was a very widely held belief well into the millennium. I don't know what user studies Mr. Neilsen is referring to; even the ancient 1998 reference Web Site Usability: A Designer's Guide found no evidence to support this claim:

The Fidelity site, more than any other site we tested, went to great lengths to have many of its pages completely above the fold. The result is lots of pages, each with small amounts of content. There was no evidence to suggest that this strategy helped or hurt.

In fact, we never saw any user frustration with scrolling. For instance, when we counted "first clicks" -- the first place people clicked when they came to a new site -- clicks were just as likely to be above the fold as they were to be below it. If scrolling below the fold was a source of frustration, we would have expected to see some sort of negative correlation between first clicks below the fold and success, but we didn't.

In 2003, Jakob added an addendum to his Alertbox, which reads:

In 1996, I said that "users don't scroll." This was true at the time: many, if not most, users only looked at the visible part of the page and rarely scrolled below the fold. The evolution of the Web has changed this conclusion. As users got more experience with scrolling pages, many of them started scrolling.

You should certainly try to put the most important information at the top of whatever it is you're writing, be it a website, a program, an email, a resume, etc. Believe me, I've learned this the hard way; you're lucky if they read anything, much less the first paragraph.

But to claim that users don't scroll is downright ridiculous, even for 1996. Let's say you had a user who didn't know how to scroll a web page. How long would it take this user, however timid they may be, to learn that they needed to scroll when browsing the web? A user who can't learn to scroll within a few hours certainly won't be using the internet for very long.

In Joel Spolsky's excellent User Interface Design for Programmers, he notes the difference between Usability and Learnability:

It takes several weeks to learn how to drive a car. For the first few hours behind the wheel, the average teenager will swerve around like crazy. They will pitch, weave, lurch, and sway. If the car has a stick shift they will stall the engine in the middle of busy intersections in a truly terrifying fashion.

If you did a usability test of cars, you would be forced to conclude that they are simply unusable.

This is a crucial distinction. When you sit somebody down in a typical usability test, you're really testing how learnable your interface is, not how usable it is. Learnability is important, but it's not everything. Learnable user interfaces may be extremely cumbersome to experienced users. If you make people walk through a fifteen-step wizard to print, people will be pleased the first time, less pleased the second time, and downright ornery by the fifth time they go through your rigamarole.

Sometimes all you care about is learnability: for example, if you expect to have only occasional users. An information kiosk at a tourist attraction is a good example; almost everybody who uses your interface will use it exactly once, so learnability is much more important than usability. But if you're creating a word processor for professional writers, well, now usability is more important.

And that's why, when you press the brakes on your car, you don't get a little dialog popping up that says "Stop now? (yes/no)."

I was greatly impressed with the expanded book version of Joel's User Interface Design for Programmers page. I sort of assumed that the book was a mildly enhanced reprint of the HTML, but 7 of the 18 chapters are completely new material. Based on a few quick Google searches, they really are new. And the full color printing is fantastic!

I've read a bunch of UI books, and Joel's is easily in my top three. I'll definitely be adding it to my recommended developer reading list.

Discussion

Variable "foo" and Other Programming Oddities

If you've ever viewed UNIX documentation, you've probably encountered variables foo and bar at some point. Here's a Ruby example I found in the newsgroups:

foo = 0
bar = 0

1.times do
  foo = 1
  foo := 2
  bar = foo+1
end

puts foo, bar

O'Reilly's FooCamp ostensibly means "Friends of O'Reilly" but is probably a pun on this same meaningless variable. So why "foo"? I always thought foo and bar were corruptions of the phrase FUBAR, but according to the jargon file, that's not correct:

When 'foo' is used in connection with 'bar' it has generally traced to the WWII-era Army slang acronym FUBAR ('F*cked Up Beyond All Repair' or 'F*cked Up Beyond All Recognition'), later modified to foobar. Early versions of the Jargon File interpreted this change as a post-war bowdlerization, but it it now seems more likely that FUBAR was itself a derivative of 'foo' perhaps influenced by German furchtbar (terrible) – 'foobar' may actually have been the original form.

For, it seems, the word 'foo' itself had an immediate prewar history in comic strips and cartoons. The earliest documented uses were in the Smokey Stover comic strip published from about 1930 to about 1952. Bill Holman, the author of the strip, filled it with odd jokes and personal contrivances, including other nonsense phrases such as "Notary Sojac" and "1506 nix nix". The word "foo" frequently appeared on license plates of cars, in nonsense sayings in the background of some frames (such as "He who foos last foos best" or "Many smoke but foo men chew"), and Holman had Smokey say "Where there's foo, there's fire".

Then there are GUI widgets. I know the word predates computers as a generalized business school expression of "some unit of produced goods", eg, from ACME Corporation. But where did the word "widget" come from?

"Widget" is a deliberately invented word meant (probably) to suggest "gadget". Most dictionaries fail to trace it to its origin. It comes from the 1924 play "Beggar on Horseback", by George Kaufman and Marc Connelly. In the play, a young composer gets engaged to the daughter of a rich businessman, and the next part of the play acts out his nightmare of what his life will be like, doing pointless work in a bureaucratic big business. At one point he encounters his father-in-law at work, and we get the following dialogue:

(Father-in-law): Yes, sir! Big business!

Yes. Big business. What business are we in?

Widgets. We're in the widget business.

The widget business?

Yes, sir! I suppose I'm the biggest manufacturer in the world of overhead and underground aerial widgets.

Part of the point, of course, is that no one ever tells him what "widgets" are.

A play, of all things. It certainly must have been popular in the 1920's for this weird little word to catch on; a google search reveals a bunch of hits for recent productions of Beggar on Horseback.

The Beagle Brothers were one of my favorite Apple // software vendors. They had disks chock full of crazy little programs and demos, all written in Applesoft BASIC. In many of these apps the sentence "Pack my box with five dozen liquor jugs" appears. Just more Beagle Brothers zaniness, I thought. Years later, I realized what this phrase actually is. It's a pangram: it uses all 26 letters of the alphabet in a single sentence.

The wikipedia entry notes that pangrams are typically used in font sample apps. That's what launches in Windows when you double-click on a font in the c:windowsfonts folder. Here are a few examples:

How razorback-jumping frogs can level six piqued gymnasts!Mac, System 7 era
Cozy lummox gives smart squid who asks for job penMac, post-System 7 era
The quick brown fox jumps over the lazy dogWindows, truetype fonts
Pack my box with five dozen liquor jugsBeagle Bros fonts
Jackdaws love my big sphinx of quartzWindows, bitmap fonts
beagle_pack_my_box.png

The pangram Beagle Bros chose is a great expression of their homebrew spirit: it's rather clever and it involves alcohol.

Discussion