May 31, 2006
Peopleware Revisited
Kevin Kelly's Cool Tools list just selected a book from my recommended reading list. And it's one of my favorites, too. It's that perennial evergreen of project management, Peopleware:
Hard-won wisdom fills this small book: How to create a team, place, or company that is productive. First published 20 years ago, and updated once since then, copies of it have quietly served as a guru for many start ups and successful projects in Silicon Valley. Neither academic nor faddish, two veteran consultant authors offer real intelligence. This book has totally informed how I do projects. I learned about the myth of overtime, the need for closure and ceremonies, how teams jell, and why everyone should and can have a window. I first read it decades ago and re-read it every time I embark on anything involving more than one person and several years of my life. Unlike a lot of management lore, it is aim at the project level (where I want to be) rather than the large organization. The message in the book touts productivity, without ever mentioning the dreary idea of time management. It's more about optimizing people, and thus the title, Peopleware.
As if I needed another reason to love Cool Tools. If you don't have a copy of Peopleware yet, what are you waiting for?
May 30, 2006
Touchpad vs. Trackpoint
When it comes to pointing devices on laptops, there are two schools of thought. There's the touchpad..
.. and there's the trackpoint, which was popularized by IBM thinkpads:
I recently switched to a work-provided Thinkpad T40 as my primary laptop, and it has both trackpoint and touchpad-- great for an apples-to-apples comparison.
I'm a touchpad man, myself. This entire post, including the image editing, was performed with the touchpad. At no point was I frustrated or rate-limited by the touchpad. I've had such good results with touchpads lately that I find myself forgetting to use the external USB mouse I regularly carry in my laptop bag. There is no stronger praise for any alternative input device.
The touchpad wins, for me, because it's such a simple input method -- yet it supports some complex, subtle nuances that are surprisingly intuitive:
- click, double-click, and right-click by tapping the pad. In case you were wondering, on the Mac, a right click is a two-finger tap.
- scroll horizontally or vertically by dragging your finger along the edges of the pad.
- press harder to drag items further.
- slide faster to move faster.
A lot of the touchpad's functionality is dependent on the software drivers. And Synaptics has done an incredible job, year after year, of harnessing the touchpad functionality in useful, usable ways. The first thing I do when I get a new laptop is make sure I have the latest Synaptics drivers. In fact, the Synaptics drivers are the only OEM input drivers I ever install.
I noticed that the trackpoint has improved over the years as well. For one thing, I can now press the trackpoint to click. But scrolling is out of the question, of course. And the trackpoint's motion is a lot smoother compared to the old models I remember, which makes it less fiddly. On the new T60's at work, it's so smooth it almost feels like a slider. Still, it speaks volumes that even IBM/Lenovo offers both input methods by default on their laptops. If the trackpoint is such a great input device, why would anyone need a trackpad? But choice is good, I suppose. And the trackpoint is a clear winner if space is at a premium.
If you're looking for an empirical way to prove the superiority of one input method over the other, good luck. This Fitt's law backgrounder, and the related Java test applet, will at least give you some actual data points to support your position.
Before we get too worked up on this topic, I suspect the most common pointing device for most laptop users is an external USB mouse. Which renders the whole touchpad vs. trackpoint debate moot.
Still, the fact that I can use any kind of alternative input device and not feel compelled to immediately plug in an external mouse is pretty amazing to me.
May 29, 2006
Do Modems Still Matter?
One of the key ingredients for Web 2.0 success is pervasive high speed internet access. The latest Pew internet report, which tracks broadband growth, was just released:
At the end of March 2006, 42% of Americans had high-speed at home, up from 30% in March 2005, or a 40% increase. And 48 million Americans -- mostly those with high-speed at home -- have posted content to the internet.
In total, 84 million Americans now have high speed internet connections at home.
At the height of the last dot-com bubble in mid-2000, less than five percent of Americans had access to a high speed internet connection at home. But by the end of 2006, that figure will reach nearly fifty percent.
It's hard to imagine what investors and analysts were thinking back in 2000 with those wildly optimistic dot-com growth curves, because using the internet with a modem truly sucks. It's painful. When 95 percent of users are stuck with a crappy dial-up experience, it's unrealistic to expect widespread adoption of services offered via the internet.
I recently sold my 1997-vintage US Robotics Courier analog modems on eBay, after hanging on to them for years "just in case". I haven't used a dialup connection in at least five years.
As good as the 2006 numbers are, according to Lawrence Lessig, the United States still lags the world in broadband adoption-- at least through 2004:
With broadband adoption at an all-time high in the United States, can we finally assume that all users will have high-speed internet connections-- and by association, an enjoyable, responsive, non-painful way to use the internet? Or do web developers still need to accommodate dial-up users?
May 26, 2006
Pixels, Megapixels, and Desktop Resolutions
I've always wondered why digital cameras express their resolutions in terms of megapixels, rather than the typical pixel height and width numbers you find on computer displays. Nobody buys a 21" LCD with 1.9 megapixels of resolution; they buy a 21" LCD that can display 1600 x 1200. But they're technically the same thing: 1600 x 1200 is 1,920,000 pixels, or 1.9 megapixels. It looks like we're using the old hard drive manufacturer's trick of dividing by powers of ten.
One problem with using the megapixel designation alone is that you have no idea what the aspect ratio of those pixels are-- 16:9? 5:4? 1.33:1? Who knows, maybe that 1.9 megapixel camera is really taking 192 x 10,000 pictures. Pixels are pixels, right?
The wikipedia entry on computer display resolutions has a great chart that contrasts the most common monitor resolutions, along with the ratio line that each falls on:
It's interesting to note that the most common monitor resolutions (800x600, 1024x768, etc) are 4:3. I didn't realize how oddball the 1280x1024 ratio was. The widescreen variants are really catching on quickly, too, if the current LCD monitor selection at Newegg is any indication.
But the alphabet soup of display designations isn't doing anyone a favor, either. I'd much rather know that a display is capable of 1600 x 1200 instead of the cryptic designation UXGA.
You can compare the different resolutions of most common electronic devices (cameras, screens, video, etc) and many common formats using this nifty dynamic megapixel overview tool. Some of the camera models listed tend to have 4:3 aspect ratios, like PC displays. But not all. The 3:2 ratio is also common. Here are a few samples:
- Canon Powershot Pro 1
3264 x 2448 (8 megapixels, 4:3) - Canon EOS 5D
4368 x 2912 (12.7 megapixels, 3:2) - Nikon D70s
3006 x 2000 (6 megapixels, 3:2)
Evidently the 3:2 ratio derives from the native dimensions of classic 35mm film.
May 25, 2006
Is the Command Prompt the New Desktop?
People keep rediscovering the article Don Norman posted a few months ago criticizing what he thinks of as Google's faux simplicity:
"Oh," people rush to object, "the Google search page is so spare, clean, elegant, not crowded with other stuff." True, but that's because you can only do one thing from their home page: search.
Of course, I don't agree. Philipp Lenssen notes that Don completely ignored the search results page UI:
The second point I disagree with in Donald Norman's article is that Google only does one thing. Apparently, Donald doesn't understand Google oneboxes – the query-specific boxes on top of organic search results, interfacing services Google News, Google Maps and so on – or he purposely omits them. While a Google onebox is not a solution to all needs (for one thing, it doesn't allow me to explore, because I need to know what I want in order to form a search query), there's also the "more" link leading to a Google sitemap with an overview of additional services.
But Bill de hra expands the argument in an intriguing direction:
Perhaps the hunt and peck approach of searching (along with gaming) is becoming the dominant computing metaphor, replacing nearly 3 decades of user interfaces based on the metaphor of an office desktop (ironically the metaphor itself being pushed into irrelevancy by desktop computing). If so, usability experts will need to reconsider what they deem to be best and appropriate.
The Google search box could be viewed as the ultimate command prompt; you type what you want, and it provides the answer. Eventually. Once you realize that the Google search box is really a type of command prompt, the criticism that Google "only does one thing" is.. well, downright hilarious. Search is the beginning of every command. You can go anywhere and do anything from there.
I've never been a huge fan of the desktop metaphor. It's easier to see the problems if you take it to an extreme, as General Magic's defunct Magic Cap operating system did:
As much as I dislike the limitations of the desktop metaphor, I'm a little uneasy about the idea that the ultimate user interface we end up with in the next ten years will bear more resemblance to a command prompt ..
.. than to the point and click GUI interfaces pioneered at PARC.
Still, there's a lot to be said for typing stuff to quickly get to what you want. For example, I often bail out when attempting to visually point and click my way around crowded web pages; instead, I search for a relevant word on the page using incremental search. It's nearly always faster than visually scanning the entire page for the right content or link.
May 24, 2006
You may be a victim of software counterfeiting.
Microsoft has finally activated the most aggressive part of their Windows Genuine Advantage program -- active notifications.
After downloading the latest Windows updates, if your Windows cd-key doesn't validate against Microsoft's online database of cd-keys, you may be greeted with this unpleasant five-second mandatory delay dialog at the login page:
On top of that, you get a repeating balloon notification that nags you periodically while you use the operating system:
The warnings also get more dire as time progresses:
This copy of Windows is not genuine and you have not resolved the issue. This computer is no longer eligible to receive select security upgrades from Microsoft. To protect your computer, you must click Get Genuine now.
The language here is a little misleading. Microsoft is socially obligated to provide critical security updates to pirated machines. Otherwise those vulnerable machines will eventually be compromised and potentially used in denial of service attacks and other nefarious schemes. Microsoft does provide so-called "critical" updates to all Windows machines, regardless of whether or not they're genuine.
This is all courtesy of the mandatory "Windows Genuine Advantage Notification" service that is being delivered now through Windows Update. This isn't just a service you can disable, or a process you can kill in task manager, either. You'll have to install some kind of questionable third-party hack to get around it.
I suppose it's only malware if you're a pirate. What's a poor, beleaguered user to do? Microsoft offers five options:
- Purchase a valid Windows XP cd-key online from Microsoft.
- If you can produce high-quality counterfeit media, along with a proof of purchase, you can get a free replacement key from Microsoft.
- Contact your reseller for redress.
- Purchase Windows XP from a local OEM reseller.
- Purchase Windows XP at a retail location.
Notice the word "Purchase" appears in three of those five options. There's almost no way to finagle a free cd-key out of this.
I found a Microsoft presentation on Windows Genuine Advantage (WGA) which goes into a lot more detail. It also provides this graph of WGA validation failure rates across the United States:
All I can say is, get used to increased forms of online discrimination between genuine and pirated versions of software. Windows Vista will have an even more advanced form of WGA; pirated versions of Vista, for example, will not be able to enable the fancy Aero "glass" interface.
Microsoft is certainly entitled to protect their IP by annoying pirates into buying cd keys. But I wonder if they're veering too far into the enforcement side of the optimal piracy rate.
May 23, 2006
Apple Laptops: Good, Cheap, Fast -- pick three
When I wrote that the Mac Mini was an underpowered, expensive box at the beginning of 2005, I had no idea that Apple would do something wonderful to fix this: switch to Intel x86 CPUs.
I guess Apple has conveniently forgotten that whole "supercomputer on a chip" marketing campaign for the G4 processor:
Apple has been promoting the G4 as the world's first "supercomputer on a chip," noting it can process data in 128-bit chunks - double the speed of most traditional computers. Apple officials claim the chip is nearly three times faster than the 600MHz Pentium III chip manufactured by rival Intel Corp.
Today's modern Macs are powered by Intel Core Duo CPUs. And according to Apple, they run nearly five times faster than the G4 models they replace.
That's gotta sting a little.
But no matter. Forget the reality distortion field advertising. Forget the fact that Apple just obsoleted their entire PC line overnight. Again. The important thing is that the new Apple models really are as fast as PCs-- because they are PCs.
Although John Gruber's overbearing Mac zealotry grates on me, I have to agree with him on one very important point:
But second, look at that quote in the context of Apple's iPod strategy. "At the critical juncture […] when they should have gone for market share, they went for profits." Of all the myriad ways that Apple's iPod position today differs from their Macintosh position 20 years ago, perhaps none is greater than this: With the iPod, Apple is going for market share.iPods are certainly premium products, at least in the greater context of "portable audio players" -- handheld audio tape and CD players typically cost around $20 or $30. Go back in time to early 2001, and I wager you'd have a hard time getting most people to believe that they'll soon be purchasing $300 and $400 handheld music players.
But when compared to other digital music players, iPods are not only competitively priced, they're often cheaper. Today's Apple is very different than the old Apple, but many people still haven't caught on.
I cut my computing teeth on the Apple //, and to a lesser extent, the Macintosh. I can personally attest that these were incredibly expensive machines at the time. But the current crop of x86 Apple laptops are cheaper than nearly every other x86 laptop of equivalent spec. That's amazing.
But don't take my word for it. Core Duo news examines the Macbook Pro:
[The Macbook Pro] is actually $500 cheaper then 17″ Dell XPS1710 with similar configuration. Granted, Apple Macbook doesn't have the latest and greatest nVidia 7900 card. But with the ability to run Windows XP, 17″ Apple Macbook Pro looks like a great choice to replace your old Wintel desktop.
.. and the latest MacBooks:
We already told you that the Intel based high end MacBook Pro was very competitive in price with high end Windows based rivals. So we checked the latest 13.3" MacBook with available PC alternatives. And we weren't disappointed:
- Asus W7J with 1.83 GHz chip, 1 GB of memory and 100 GB HDD will cost $1939. MacBook with the same configuration - $1699
- Rock Pegasus 330 with 1.66GHz chip, 512MB of memory, 80GB HDD and TV Tuner - $1343, MacBook with the 1.83GHz chip, same memory and HDD, without TV tuner - $1149
- Fujitsu Lifebook S6310 with 1.66 GHz processor, 512 MB of memory and 80GB HDD - $2033. MacBok with the 2.GHz Intel chip, same memory, HDD and other specs - $1349
If earlier you usually paid premium for Apple's laptops and desktops compared to Wintel PCs of similar performance, now you can get a MacBook cheaper then most of its PC rivals. The Apple MacBook is cheaper as a PC even if you have to purchase standalone Windows XP OS and run it on MacBook via Bootcamp. Is there any reason not to buy a MacBook if you want a highly portable 13" notebook?
I spent quite a bit of time searching for x86 laptops of similar spec and form factor, and there's just no avoiding it: the Apple x86 laptops are a great deal for the price. Sure, you can find a few edge cases where Apple loses, such as the ultraportable category. But the rare few laptops that are comparable in price and specification can't compete with Apple's design chops.
Running Windows on an Apple x86 laptop is relatively easy with Bootcamp, but it still takes some juggling to get a few essential things we take for granted with other x86 laptops, such as proper right-click support, and standard keyboard mappings.
If these kinks get worked out over time-- and I'm sure they will-- my next wintel laptop might just be an Apple.
May 22, 2006
Are Recipes for Novices?
The last post about programmers and chefs reminded me of a point raised in the classic Pragmatic Progammers' presentation Herding Racehorses, Racing Sheep:
|
| vs |
|
Instructions that are appropriate for a novice may be totally inappropriate for an expert. This is something I touched on a while back in Level 5 Means Never Having to Say You're Sorry. As James Bach said:
A maturity model is basically a gang of best practices hooked on crystal meth. In my maturity model of the industry, promoting a maturity model is mere level 2 behavior. By level 3, we outgrow it.
However, I do think Bach's views on this issue are unnecessarily black and white. The idea that a recipe (eg, a best practice, a methodology, or a maturity model) is completely worthless is just as wrongheaded as the idea that everything should be based on a strict recipe. In other words, even an expert chef may occasionally find it helpful to refer to a recipe card.
There's no reason these two models can't coexist. You should always start with the common denominator recipe, of course, but you may want to provide some alternative guidelines and ideas for those cooks who have outgrown traditional recipes, too. The point is to avoid an onerous, religious one-methodology-fits-all view of the world.
The image of the UNIX wizard used in Andy's presentation is striking. I researched the image and found this bit of history at unix.org:
The classic UNIX magic poster by Overacre was distributed at past USENIX conferences and featured a white bearded wizard with UNIX related things around him, for example a spool of thread, a black cat, a boot, a fork, pipes, buckets, a number of containers, labelled with things like tar, null, awk, uucp. There is even a 'C' container, and a partially obscured and broken 'B' container.The wizard is pouring mysterious liquids into a giant shell. Subsequent posters in the series included UNIX wars and UNIX views.
I can't find images of the other two posters, unfortunately, but you can see more of Gary Overacre's amazing art at his website.
May 19, 2006
Programmers and Chefs
From an audio interview with Ron Jeffries:
The reason the kitchen is a mess is not because the kitchen is poorly designed, it's because we didn't do the dishes after every meal.
Michael Feathers recently wrote an eerily similar entry about the professional chef's concept of working clean:
One other thing that I liked about the Pastry Chef's competition was the way that the chefs were judged. There was more to it than just the final judging. All during the preparation, judges walked from station to station with clipboards, making little notes. One of the criteria that they used was working clean. Imagine that.. working clean.. The judges were watching to make sure that the chefs rubbed clean every bowl and utensil immediately after use. If they didn't, well, they were marked off.
Micah Martin left a great comment that illustrates how integral "working clean" is to professionals in the restaurant industry:
In my college years I was a chef/line cook at a few restaurants. Indeed working clean is a common theme in the kitchen. The term I heard over and over was "Clean as you go!". "Clean as you go!" wasn't so much a suggestion, but rather a law. Those cooks who didn't constantly clean would wind up in trouble. Their workspace would become so messy within a matter of an hour or two that the quality of food rapidly diminished. This problem would progress until the other cooks were forced to step in and clean up. This had a negative impact on the entire kitchen and Nobody was happy it happened. Interestingly, line cooks, even without college degrees, were extremely efficient as self-management. Those cook who didn't work clean, were taunted, teased, and pushed around until they cleaned up, or quit.
For software developers, working clean means constant refactoring. If you don't stop occasionally-- frequently, actually-- to revisit and clean up the code you've already written, you're bound to end up with a big, sloppy ball of code. If you forget to regularly clean up behind yourself, things get smelly. Working clean means following your nose and addressing those nagging issues before they become catastrophic.
In addition to working clean, cooks also spend a lot of time thinking about mise en place, how their cooking stations are arranged for optimal work. Michael Feathers explains:
There's an section in [the book Kitchen Confidential] where he talks about what cooks do late at night after the customers have gone home. They generally do what many people after work, they go out for beers and sit around talking about work, but what do they talk about really? Tony says that the subject that always comes up is something called mise en place. Mise en place is a blanket term for how you set up your station.
![]()
Is your tub of butter at the eleven o'clock position or at the one o'clock? Do you have two paring knives, and do you keep them next to your cutting board or next to your garnish bin? When you spend the night churning out meals, these decisions make a difference. Everyone has their favorite theory about the proper miz. Tony says that many cooks get downright mystical about it. According Tony, you'd better run if you are caught messing with another cook's miz. Sharp knives have multiple uses, apparently.
The concept of mise en place should be familiar to software developers. It's why every member of the team has their development system set up identically. It's why we use a common set of development tools. It's why we take advantage of existing frameworks like nUnit and Log4Net instead of writing our own.
Good programmers should be borderline obsessive about their "miz". Our craft changes too rapidly for us to ever be completely satisifed with the way we're working today. There's always something better on the horizon.
May 18, 2006
Code Smells
I'm often asked why the book Refactoring isn't included in my recommended developer reading list. Although I own the book, and I've read it twice, I felt it was too prescriptive-- if you see (x), then you must do (y). Any programmer worth his or her salt should already be refactoring aggressively. It's so essential to the craft that if you have to read a book to understand how it works, you probably shouldn't be a programmer in the first place.
There's nothing wrong with codifying refactoring guidelines in a book. But the most important guideline is to watch for warning signs in your own code-- so called "code smells".
Developing your "code nose" is something that happens early in your programming career, if it's going to happen at all. I combined all the documented code smells I could find into this reference; most of these smells should be familiar to you.
Code Smells Within Classes
| Comments | There's a fine line between comments that illuminate and comments that obscure. Are the comments necessary? Do they explain "why" and not "what"? Can you refactor the code so the comments aren't required? And remember, you're writing comments for people, not machines. |
| Long Method | All other things being equal, a shorter method is easier to read, easier to understand, and easier to troubleshoot. Refactor long methods into smaller methods if you can. |
| Long Parameter List | The more parameters a method has, the more complex it is. Limit the number of parameters you need in a given method, or use an object to combine the parameters. |
| Duplicated code | Duplicated code is the bane of software development. Stamp out duplication whenever possible. You should always be on the lookout for more subtle cases of near-duplication, too. Don't Repeat Yourself! |
| Conditional Complexity | Watch out for large conditional logic blocks, particularly blocks that tend to grow larger or change significantly over time. Consider alternative object-oriented approaches such as decorator, strategy, or state. |
| Combinitorial Explosion | You have lots of code that does almost the same thing.. but with tiny variations in data or behavior. This can be difficult to refactor-- perhaps using generics or an interpreter? |
| Large Class | Large classes, like long methods, are difficult to read, understand, and troubleshoot. Does the class contain too many responsibilities? Can the large class be restructured or broken into smaller classes? |
| Type Embedded in Name | Avoid placing types in method names; it's not only redundant, but it forces you to change the name if the type changes. |
| Uncommunicative Name | Does the name of the method succinctly describe what that method does? Could you read the method's name to another developer and have them explain to you what it does? If not, rename it or rewrite it. |
| Inconsistent Names | Pick a set of standard terminology and stick to it throughout your methods. For example, if you have Open(), you should probably have Close(). |
| Dead Code | Ruthlessly delete code that isn't being used. That's why we have source control systems! |
| Speculative Generality | Write code to solve today's problems, and worry about tomorrow's problems when they actually materialize. Everyone loses in the "what if.." school of design. You (Probably) Aren't Gonna Need It. |
| Oddball Solution | There should only be one way of solving the same problem in your code. If you find an oddball solution, it could be a case of poorly duplicated code-- or it could be an argument for the adapter model, if you really need multiple solutions to the same problem. |
| Temporary Field | Watch out for objects that contain a lot of optional or unnecessary fields. If you're passing an object as a parameter to a method, make sure that you're using all of it and not cherry-picking single fields. |
Code Smells Between Classes
| Alternative Classes with Different Interfaces | If two classes are similar on the inside, but different on the outside, perhaps they can be modified to share a common interface. |
| Primitive Obsession | Don't use a gaggle of primitive data type variables as a poor man's substitute for a class. If your data type is sufficiently complex, write a class to represent it. |
| Data Class | Avoid classes that passively store data. Classes should contain data and methods to operate on that data, too. |
| Data Clumps | If you always see the same data hanging around together, maybe it belongs together. Consider rolling the related data up into a larger class. |
| Refused Bequest | If you inherit from a class, but never use any of the inherited functionality, should you really be using inheritance? |
| Inappropriate Intimacy | Watch out for classes that spend too much time together, or classes that interface in inappropriate ways. Classes should know as little as possible about each other. |
| Indecent Exposure | Beware of classes that unnecessarily expose their internals. Aggressively refactor classes to minimize their public surface. You should have a compelling reason for every item you make public. If you don't, hide it. |
| Feature Envy | Methods that make extensive use of another class may belong in another class. Consider moving this method to the class it is so envious of. |
| Lazy Class | Classes should pull their weight. Every additional class increases the complexity of a project. If you have a class that isn't doing enough to pay for itself, can it be collapsed or combined into another class? |
| Message Chains | Watch out for long sequences of method calls or temporary variables to get routine data. Intermediaries are dependencies in disguise. |
| Middle Man | If a class is delegating all its work, why does it exist? Cut out the middleman. Beware classes that are merely wrappers over other classes or existing functionality in the framework. |
| Divergent Change | If, over time, you make changes to a class that touch completely different parts of the class, it may contain too much unrelated functionality. Consider isolating the parts that changed in another class. |
| Shotgun Surgery | If a change in one class requires cascading changes in several related classes, consider refactoring so that the changes are limited to a single class. |
| Parallel Inheritance Hierarchies | Every time you make a subclass of one class, you must also make a subclass of another. Consider folding the hierarchy into a single class. |
| Incomplete Library Class | We need a method that's missing from the library, but we're unwilling or unable to change the library to include the method. The method ends up tacked on to some other class. If you can't modify the library, consider isolating the method. |
| Solution Sprawl | If it takes five classes to do anything useful, you might have solution sprawl. Consider simplifying and consolidating your design. |
This list was derived from the Smells to Refactorings PDF, and the Smells to Refactorings Wiki, which also provide additional guidance on the specific refactorings that might be helpful in each instance. The important thing, from my perspective, isn't the refactoring-- it's learning to recognize the scent of your own code.
And if you want examples of the stinkiest code imaginable, How to Write Unmaintainable Code is a good place to start.
