Middle Aged Software

September 30th, 2012

Software ages. Yes, all software goes obsolete, usually within just a few years, but the developers usually update their software to keep up with changing hardware and operating systems. I’m talking about the aging process that takes place as a piece of software evolves from Version 1.0 to Version 2.0 to 3.0, 4.0 and so on. This comprises an aging process.

Software ages like a man: it grows more mature with age, smoother, and more capable, but it also gets flabby around the waist. The spare tire gets larger, the muscle tone of youth fades, and it slows down. All good software begins life as an athletic youth, bursting with potential. As it ages, the shine wears off and it becomes just another middle-aged application. It’s still good, mind you, but it doesn’t arouse the excitement that it did in its youth.

Partly this is part of the sociology of the development process. Version 1.0 is developed by hotshots with big, bold ideas. As the software moves up through the versions, it becomes more important that it properly handle stuff created with earlier versions, and the requirement that it be bug-free becomes more oppressive. The hot shots leave to do something more exciting and maintenance of the program is turned over to safer, more conservative programmers.

Another force is at work: the user community. Every application has a user community spanning a range of expertise with the program. At the bottom end is a large mass of tyros who piddle around with the program, get it to do simple things, and never really understand how to make it sing. At the top end are the pros, the enthusiasts who explore every nook and cranny of the program, mastering all the little tricks.

The beginners are pretty quiet, but the pros are loud and insistent: they want more power. They want more nooks and crannies to explore, special doodads that would allow them to expand their capabilities. They crowd the developer’s bulletin board with complaints about microscopic bugs and demand more features.

Suppose that you’re the software developer. To whom do you pay more heed: the thousands of embarrassed beginners who never utter a peep, or the few hundred noisy pros always suggesting new ideas? And why shouldn’t you add a new idea, so long as it doesn’t intrude on the rest of the program? Why not just pack the features in like you would stuff a suitcase? How can you say no to good suggestions?

Incremental versus Intrinsic Progress
You should say no to most of those ideas. The users don’t see the big picture of the program. They have no idea of its internal structures. And the program’s user model (the perceived workflow required to do things in the program) is so native to the pros that they don’t even realize that it’s a model; they think of it as the only way to do things. If only it had this one little incremental feature added to it, it would be perfect. That’s what they say.

And they’re right: one little incremental feature doesn’t do any harm, and if it helps out a few users, then go for it. The problem is that it’s never just one incremental improvement; they come in a steady stream, and if you don’t fight them, your program will become like a barnacle-encrusted ship hull: slow, inefficient, and desperately in need of a cleanup.

A good example of this process is demonstrated by the evolution of plug-ins. These are extra little programs that can be plugged into a main program to augment its feature set. Lots of programs accept plug-ins, and in theory it’s a great idea. Moreover, they give the developer an opportunity to engage in a kind of user testing. Some plug-ins will never gain any attention; a few will soar in the appreciation of the users. Those few plug-ins can then be incorporated into the main program without risk.

Plug-ins are just fine when taken individually, but in aggregate, they’re a disaster. Once more than a few plug-ins have been installed, they start interacting with each other in unexpected ways, usually leading to some sort of malfunction.

Plug-ins have a long history. Both Windows and the Macintosh operating systems have used plug-ins (called extensions in that context). In the early years, system extensions were a major source of problems for users and developers. Incompatibilities between system extensions and just about everything else on the computer drove everybody crazy. Printer drivers were particularly bad in this regard. After years of frustration, Apple and Microsoft both learned to impose harsh constraints on system extensions.

But applications began including system extensions. I don’t know if Adobe Photoshop was the first, but they were certainly an early adopter of the methodology, and plug-ins for Adobe Photoshop greatly expanded its range. Nowadays quite a few applications, and even some games, permit plug-ins. And these people are learning the same harsh lessons that Apple and Microsoft learned. In the early days plug-ins are great and loads of fun; but once people start combining them, the shit hits the fan. Applications developers will learn to tightly constrain the freedom of their plug-ins.

The Example of Apple
Apple is the only major software developer to demonstrate serious concerns for the aging of software. The history of the Macintosh OS is a tale of dramatic changes executed by astounding feats of programming legerdemain. Apple has never hesitated to rethink fundamental aspects of its operating system and to completely redesign major components. All the while they have maintained excellent legacy performance. The real trick behind Apple’s success was the rigorous definition of its operating system API. By forcing programmers to honor their rules, Apple gave itself the freedom to modify the underlying operating system. And the ruthlessness with which Apple discarded developers who refused to honor its rules served to insure that everybody toed the line.

The result is an operating system that has undergone profound changes in its underlying processor: first from the Motorola 680X0 CPUs to the RISC processors of the 1990s, then to the Intel processors, then multi-core processors. Apple’s jump from OS 9 to OS X was even more astounding, yet they pulled it off smoothly.

A common practice in earlier years was to break apart programs as they aged. If the feature list grew too bloated, they’d split the program into two versions, a “Lite” version and a “Pro” version. There were a lot of experiments along these lines; most ended in tears. A few worked well; Adobe’s splitting off of Photoshop Elements from Photoshop is the poster girl of this process. But there were a lot more failures along the way. The problem comes from the user model. A user model that’s really great for one level of complexity seldom works well at a different level of complexity. My understanding is Adobe made some substantial changes in the user models for the original Photoshop and Photoshop Elements. Unless you can do the same, mitosis is a risky strategy.

I therefore urge software developers to learn some basic lessons about managing their aging software:

Klotzen, nicht kleckern!
German for “Boot ‘em, don’t spatter ‘em!” Don’t fiddle around with petty incremental improvements. Sure, those are necessary as part of the bug-fixing process, but new releases should always involve substantial changes to the design. Instead of incrementally piling on individual suggestions from the pros, take the time to reflect on the underlying problems those suggestions refer to. Remember, users aren’t designers, and their solutions are always wrong in specifics but right in intent. So assemble your list of feature requests and ask, “How can we modify the basic model to address these ideas in a unified manner?” Remember, change issues from the user model, not the code!

Address legacy problems with a built-in converter.
Don’t accommodate old design elements that hold you back — dump ‘em! Write a software translator that will convert old documents into the new format. 

Work with your developers, but firmly.
If you have plug-ins, any substantial problems with discommode your developers. They’ll scream bloody murder and threaten to abandon you if you pull the rug out from underneath them. Don’t budge. Work with them to ease the transition, but make it clear that, if the platform doesn’t evolve, you and they will all become dinosaurs.