Monday, January 14, 2008

Curious Perversions in Usability

We've all seen them, and we've all used them: applications foisted upon us by the well-meaning management masses who wanted us to conform to the standard in order to boost our productivity, or the latest whiz-bang website promising to revolutionize its niche market. While the product itself might actually solve a unique problem, or offer a plethora of enticing, well designed features under the hood, its user interface frustrates, confuses, obscures, and clutters.

When it comes to user interfaces, drill this one simple idea into your mind: Simple, clean interfaces will win out over flash, pomp and circumstance every single time. Why? Because a user interface should get out of a user's way, it should not impede them, confuse them, obscure the information they need to find, or be cluttered with crap they're really not interested in.

We all have different views about what makes any given piece of software more usable. But certain things tend to peeve users fairly consistently. These tend to be mine when it comes to Web pages:

  • Don't make me wait. Don't make the mistake of thinking that performance isn't a part of your user interface. There are always numerous ways to display the same piece of information, and some are faster than others. Given a choice between having to wait for a Flash or PDF download of a pretty picture, or a flat GIF/JPEG, which do you think most users would prefer? (And if you think Flash hasn't been proposed for this, think again.) Use the smallest, most compact presentation format that will get the job done right.
  • Don't make me scroll. Especially not horizontally. Smaller pages work better. Horizontally scrolling pages are counter-intuitive, and people tend to have a hard time shifting into a mode where they're comfortable scrolling in that direction. Sometimes, you simply can't get around it, and that's the exception rather than the rule. In those cases, under no circumstances should you move the main navigational controls off the screen. In Web applications, embed the scrolling content in scrolling DIVs (or other suitable controls) to ensure that users can still reach your navigational controls without having to page through the document.
  • Don't make me squint. Use a reasonable font size that even the visually impaired can comfortably read. Better yet, use a font size that scales when the user chooses a different size in the browser. Don't force your font size on the user, simply because not everyone has 20/20 vision.
  • Don't make me guess what language you've written that document in. Use a clear, legible, font. You may like your decorative fonts, but they're not suitable for body text, forms, or general deployment on Web pages. Most users won't have them, and they won't look the same. Use standard fonts.
  • Don't make me wonder if there's something written in any area of the page or screen. Don't use dark text on a dark background. Don't use light text on a light background. Strong contrast enhances legibility.
  • Don't hide important information from me. Place important information at eye level. Use font weights, color, and styles to emphasize important information. Place this information prominently on the page, where I can easily see it. Don't obscure it in the page.
  • Don't hyperlink everything on the page. A hyperlink should indicate that there's something worth investigating. If everything on the page is hyperlinked, the hyperlink loses its value, and I'll tend to ignore them. Hyperlink the important topics. If you need to hyperlink lots of topics, provide a section at the bottom of the page called See Also or References and include those links there.
  • Don't obscure or complicate hyperlinks. If you change the style of a hyperlink so that I don't know it's a hyperlink, I won't know what to look for. Don't overly complicate them. Hyperlinks are an established navigational paradigm for the Web (and even desktop software) and everyone knows what they are and how they work. Leave them alone. Users already know how to use them.
  • Don't make me jump through hoops to find the commands or features I need to use. Don't invent an entirely new way of navigating your web site or application. There are a number of existing navigational paradigms that are well established and with which users are very familiar: drop down menus, tree views, bread crumbs, tabs and commands, and so forth. Don't confuse users by making them learn something completely new.
  • Don't surprise me by reconfiguring the user interface when I do something. If I click a button or a menu command and the entire user interface changes, or entire menus disappear, we've got a problem. The user interface, and the navigational system in particular, needs to be consistent and predictable. If it's not, users will be playing a constant guessing game about what they can and should do next. Users playing a guessing game are dangerous users.
  • Don't baffle me with technical jargon or confusing messages.  When something goes wrong, or when I've done something wrong, communicate it clearly and concisely. Tell me what I can do about it. Recover gracefully. Don't just throw up some message box that announces "An error occurred. Press OK to continue." Duh. What should I do next? Should I tell someone? If so, whom? Is my data safe? Do I need to start over?
  • Use consistent language. Don't call it Cancel on one screen and Abort on another. Don't use Logon Name on one screen and Sign In on another. Be consistent. Establish a vocabulary and stick to it.
  • Don't waste my time prompting me in an intrusive way to take part in your survey. I'm not interested in taking part in your survey. Put the offer to take part in a prominent place in your site or program that isn't intrusive. If I'm interested, I'll take you up on the offer. Otherwise, I'm going to close the DIV because you were rude enough to cover up the content that I was looking for with your intrusive popup. The same goes for popup ads. (But we all know how well that's going to go over.)
  • Don't play sound or streaming video as soon as the page loads. If I want to see it, I'll start it myself. You're chewing up my bandwidth, thank you very much. If I'm from an area where that's a precious commodity, that's the height of rudeness. Give me the opportunity to start the sound or video when I want to and if I choose to do so. This includes all forms of linked and embedded media, including Flash.
  • Don't order me to get a better browser. You don't know what browser is best for me. I may like FireFox, IE, Safari, Opera, Navigator, or some as yet unnamed browser still emerging. You may be able to say that your site doesn't support browsers outside a certain set, but it is gauche to insist that your browser of choice is the one and only true browser, whichever browser that may be. Competition is actually good for the industry.
  • Don't assume that my monitor is as big as your monitor. Just because your company has a standard video configuration that supports 1024×768 doesn't mean that's what your users are configured for. A vast amount of users are still set at 800×600. This resolution isn't a matter of laziness, but of simple visual acuity: they can't see anything if it's at a higher resolution. Design for 800×600. Ensure your pages fit on a monitor at that resolution. Doing so means users don't have to scroll horizontally. It also means that your pages will print properly if the user hits the Print button from the browser and is printing in landscape mode.

Yes, this is surely opinionated. Yes, I'm sure I'll take heat for it. But here's where I'm coming from: I've both used lots of Web sites, and I've had to design lots of Web pages for The Average Computer User(tm). For those users, all of these things have turned out to be true. Ask yourself why Google's search engine is insanely popular. It's not just that their search engine covers the vast majority of the Internet; most people don't know how to effectively use the search engine to get the results they really want. It's because their search page is so simple that it's almost pristine. It's foolproof. Type what you want in the box and click Search. The results pages come up and show you what matches your search criteria. It's simplicity defined.

Apple's computers have always been lauded as a breathtaking departure from the technical complexity inherent in Windows. Their user interfaces are simple, clean, and easy to use. They're the hallmark of Apple's software. One could argue that the simplicity of Apple's user interfaces is what defines them more than their hardware. Again, simplicity prevails, because the user interface gets out of the user's way, and lets the user get her job done.

This is what we should be striving for. Design a Web page that is simple, clean, and gets out of the user's way. Don't confuse them. Be predictable in the way you behave. Be forthright and clear in the way you communicate. Use strong contrasting colors, legible fonts and sizes, don't reinvent the Web navigation paradigm, keep the navigation system where users can reach it, and avoid technologies that will degrade the user's experience.

A Web site can do all that and still be beautiful. CSS allows us to do that. There's no reason you can't be clean, predictable, communicative, unobtrusive, and beautiful all at the same time. You just have to choose to do so. And you have to put your users' needs above your own desire to use the latest flashy, slow, whiz-bang technologies that don't really get you anything more than older, stable, less impressive technologies that accomplish the same thing.

Who's Testing Your Software?

There's a common mistake in software development: trusting the developers to test the software. Historically speaking, developers are the worst kind of testers, because we tend to use the software only as we designed it to be used. It takes a special kind of developer to be able to think outside the box and think like a user with little or no computer savvy.

In the comment thread to the article, Microsoft Admits Vista Update Glitch, one poster made this point:

Beta testing is not getting the bugs out of software because they got the wrong people doing it. Don't use computer savy [sic] people to beta test, use people like my wife who don't have a clue what makes the computer work. She can discover any glitch in software code, guaranteed. Her gift also applies to use of TV remote controls, etc.

To which came this reply (edited for brevity):

This is the best answer I have read for several years. Beta testers are people who do not do things that cause problems, rather, they look for features and bugs that are sometimes not there...The best Beta testers are people who are not knowledgeable and those who don't know the difference of double or single click.

These folks are referring specifically to Microsoft's beta tests for its operating systems (more specifically, for Windows Vista). But the general sentiment is true and universal: users who have never been exposed to your software in the first place, and have had little exposure to technology are frequently the best ones to determine whether or not it actually works. They have a disturbingly accurate ability to ferret out bugs that borders on the psychic.

As developers, we like to believe that our software is rock solid, easy to use, painfully obvious, and bulletproof. A user who can't tell the difference between clicking and double clicking, or why it's a bad idea to keep lots of applications open at once on a machine with limited resources, is the prime candidate for testing your software. If it's a Web application, find someone who's rarely used the Web or who only uses it for the basics: IM and email. One thing that they'll be able to tell you right away is whether or not the user interface is actually usable. And if you think for one minute that you shouldn't be designing clean, minimalist interfaces for the lowest common denominator of user, you've probably never met the average computer user. There are far more of them than there are of us.

We have some pretty interesting users for our Web applications. Some of them are fond of ignoring on-screen instructions. Tooltips, online help, field prompts, clearly written button text, user training...not much of that seems to make a difference. When all of that fails, what does the application do? How robust is it? How gracefully does it handle bad user behavior? For that matter, how gracefully does it recover from bad application, network, or hardware behavior? And does it alert the user to that kind of thing in a clear, friendly, and meaningful way?

You can't determine that sort of behavior by trusting your developers or your unit tests to find them. Inexperienced users will find far more than your tech savvy users will. That's not to say that your testing team shouldn't include tech savvy users; it absolutely should. But make sure that you include novice computer and Web users in your testing team.

Sunday, January 13, 2008

Software Release Engineering

In his Coding Horror post titled How Should We Teach Computer Science?, Jeff Atwood blogs about the lack of coverage of release engineering in computer science courses. At best, he points out, it's given cursory coverage in these courses.

Now, I'm a self-taught developer. I started programming computers in 1985 or so, and I've taught myself everything I know. So I can't really comment about what the courses in a college or university are like. But I can say this: experience has taught me that a few things he says are absolutely, undeniably true. So in this article, I'm going to enumerate those things I think are really important, and how I built a software release process at the company I worked for.

The Ugly Truth About Release Engineering

  1. Release Engineering is not simply deploying your product. There's a reason it's called engineering. It involves getting the latest version of the build from source code control, building the software, executing unit tests, building installers, and labeling the build if it's correctly built. It may involve pinning or branching the build. It requires a daily "good code" check-in time policy. It requires daily builds to ensure that you have software the compiles every day, and a means of notifying folks when the build is broken, and fixing the build-breaking code right away. It's NOT simple.
  2. Consistent, disciplined use of source-code control is the bedrock of release engineering. At any given time, you might need to fix bug in the prior release. That's hard to do if you've already started changing the code for the new release. Branched builds allow you to do that. Also, versioned files in the repository allow you to view the history of changes to a file to recover from unintentional changes. You can also develop for multiple platforms while using many of the same files, sharing them across projects without having to worry if they're out of synch. Labels on files and projects tell you exactly which version of a file was used to create any given build so that you can recreate a project from the repository if you need to.
  3. Building for your environment is not enough. You need a test environment that mimics your client's environment as closely as you can make it, down to the OS, the browser, the applications and the add-ons. Just because it runs on your machine when you press F5 from Visual Studio does not mean it's going to run on the client's machine. If you're developing for multiple browsers, install those browsers and test for them.
    (Ugly true story: our company accidentally allowed IE7 through the group policies. We had IE7 deployed everywhere. Our clients don't plan to upgrade to IE7 for another year, at least. Our product must run on IE6. I had to create a separate machine that was safe from IE7 downloads and strictly ran IE6 to be certain the product ran correctly.)
  4. F5 is not enough. Every build should be a clean build. Every build. Don't ship files to the customer that aren't required to run the software. Create a build script that does the job. Excluding a file from a Visual Studio project doesn't delete the file from the folder, but does leave it in source code control (a good thing for versioning). To ensure  clean release, have your release script remove files you aren't using prior to shipment.
  5. You need a checkin-time policy. All good source code must be checked in by a certain time every day. Code that isn't checked in does not make it into the daily build. This check-in time should be early enough that the release manager can start the daily build (if it's a manual process), or make the rounds and make sure that all code is checked in prior to it. I favor end-of day check-ins (around 4 PM) for nightly builds, but each organization is different.
  6. The software must successfully build every day. A successful build is a good sign of project health. An automated build tool can be set up to execute the build in the off hours after everyone has gone home, and after all files are checked in. Once the build is complete, the pass/fail report is sent to your release manager. However, just because it compiles doesn't mean that it's entirely healthy or bug-free. Therefore...
  7. Automated unit tests should be executed on every build. If you aren't using automated unit tests, you should be. They're not hard to learn, the tools to create them are freely available and they can improve the stability and quality of your code immeasurably. Incorporate the unit tests into your build script so that they're executed every time you build the software. Correctly written unit tests alert you to build-breaking defects quickly and immediately.
  8. Build-breaking defects must be resolved before anything else. This includes any defect that causes the software to fail to compile or any defect that causes a unit test to fail. The team must adopt a "drop everything and fix the build" mentality. In my own personal experience, this view is not easily accepted in the early stages of a project, but during the later stages, when there's typically a "crunch" mode, and the build isn't riddled with build-breaking defects, developers are thankful that those defects simply aren't there.
  9. You need a release manager. While you might have many people who contribute to the build, checking in changes and adding new content, you need one person whose primary responsibility is to ensure that the software builds properly every day. That individual is also responsible for your installer, and for identifying the code that breaks the build and ensuring that it gets resolved. The release manager doesn't resolve the defects himself unless he checked in the build-breaking defect (since he doesn't know anything about the defect); rather, he must play the role of the hard-nosed drill sergeant ensuring that the coder who checked it in drops everything to fix the build right now. If you can't build the product, you can't ship the product, and anything else that developer might be working on is a moot point. It's an ugly, painful job, but it's crucial.
  10. You need a dedicated build server. This machine is clean, and does nothing but build your software. This guarantees that it injects no artifacts into your final product. It runs the daily build, executes the unit tests, and sends out the notifications when the build passes or fails. It might also house archived copies of each build's source code and binaries. It must be on the network, and should be backed up regularly. The Release Manager should have access to it, but no one else on the development team.

My Own Personal Release Process

It bears noting here that I've done the release process for two different companies. At one, it was for a full team of developers (about twenty of them), and the release process there was a nightmare. At that time, we couldn't get a release out in a month if we tried. So I volunteered to take on the job, and redesigned the process. It took about a week to get the process reengineered and everyone on board, but after two weeks we had daily builds working and everything was going much more smoothly.

I took many of those same principles and applied them to my new job. Clearly, some of them don't apply in a single-developer shop. But the basic principles are the same.

Source Code Control
  1. All developers must use source code control.
  2. All working, compilable code that does not break the build must be checked in by 3 PM every day. Code that is not checked in at this time does not make it into the daily build.
  3. User names and passwords are required for accessing source code control.
  4. The admin password is written on a piece of paper, sealed in an envelope, and stored in the CIO's desk. No one else has it.
  5. Minimal rights to access the repository based on need are granted.
  6. The main tree has the following subprojects: Build, Dev. Each tree's subprojects are mirrors of each other. Build is where the branched and pinned copies of the successful builds are. Mainline development takes place under the Dev tree.
  7. Every file that is required to create or ship the project is included in source code control: source files, SQL scripts, Web pages, images, build scripts, unit tests, test plans, requirements documentation, etc.
  8. Because we use SourceSafe, every weekend, during off-peak hours, regularly scheduled maintenance is performed on the repository to keep it in tip-top shape.
  9. The repository is stored on on the network. This folder is backed up incrementally nightly, and fully weekly.
Build Process
  1. Every afternoon, at 3 PM, all developers must have code they want included in the build checked into the repository.
  2. The release manager does a final verification at 3:15 to ensure that all code is checked in.
  3. An automated script fires off the build at 3:30 PM. It does the following:
    1. Clean the build folders on the build server. This involves deleting all files and folders from the project's build folder, ensuring a clean build.
    2. Get the latest version of the software from the DEV tree in the repository.
    3. Compiles the software and all of its dependencies. If the compilation fails, an email with high importance is sent to the release manager, notifying him of the failure, and the script aborts.
    4. Executes the unit tests. The unit test results are output to a text log file which are then sent to the release manager in an email.
    5. Executes a cleanup batch file that ensures that any files that should not be shipped with the product are removed.
    6. Creates the installer or archives the build into a ZIP file.
    7. Labels the build in the repository.
    8. If the build was successful, sends a "Build success" message to the release manager.
  4. Note that step 3 may execute multiple times depending on whether you are targeting multiple platforms or releases (such as Debug and Release, or various browsers, or various OSes).
  5. Upon receipt of a build failure email, the Release Manager reviews its contents, and identifies the offending source code. He then determines who checked that code in, and contacts that developer and asks them to resolve the defect as soon as possible.

    Important: Except in the direst of circumstances, the release manager should not attempt to fix someone else's defects. He should ask the developer to fix his own defects. If the release manager takes this task on himself, he'll quickly become inundated trying to fix all the build-breaking defects, and won't have time to do his own work.

  6. The developer resolves the build-breaking defect and checks in the change for inclusion in the next daily build.
  7. If enough build-breaking defects were present, the Release Manager may choose to manually rebuild the software once defect corrections are checked in.
  8. If the build is shipped to the customer, it is labeled, pinned and branched into the BUILD tree in the source code repository.
In closing

We're a Microsoft shop. Although I've worked in Java houses, my limited experiences have largely focused on the Microsoft stack, and the process that I've outlined above is primarily geared for Microsoft Visual Studio and SourceSafe. But the basic principles should be pretty universal. You should be able to take them and apply them to just about any combination of source code repository tools, unit testing tools, and IDE (or text editor).

The primary thing to remember is this: if you can't build it reliably, predictably, and on a moment's notice, you're in trouble. When a development team knows they can't build the software, and when the testing team is sitting around for days or weeks at a time wondering when they're going to get a new release to test, morale suffers, tempers flare, and things rapidly go downhill. I've been there. I've seen it. It ain't pretty.

Every project needs a good, solid release process. I'm tempted to say that any release process is better than no release process, but that wouldn't be entirely true. A release process needs to be trim, make sense, bolster confidence in the project, and help propel the team forward towards success. That's what this process is designed to do.

I'm sure that others have some ideas on how to improve the process above. I'd love to hear those ideas. I'm sure that others have different ways of doing things. I'd love to hear that too. There is no silver bullet, and I'm not anywhere stupid enough to think that this plan is perfect. But I hope it's enough to help someone, somewhere get a little bit closer to a project that gets out the door a bit faster, healthier, and with its developers' sanity in tact.

 

Friday, January 11, 2008

A Return to Blogging

So it's been a long time since I've blogged, and a lot has happened in that time. I've been on hiatus, reassessing many things in my life.

One of the foremost among those things was whether I should be blogging at all. My last post was berated by one reader as badly written. It hit me pretty hard, and is probably the primary reason I stopped blogging at all.

For me, writing is a passion, something I do because I enjoy it, and because it flows naturally out of me. The reader in this case went on to state that the intent of my article was to claim that all software should be open source. That was never the point of the article; rather, the point was that you should strive for the kind of quality and responsible behavior in your code that instilled the confidence that, should anyone actually have the opportunity to view it, you would fear nothing, knowing you weren't doing anything you shouldn't be.

But his criticism struck a resounding chord in me. All to frequently, I fail to get my point across. I am too wordy. I dance around the point, rather than just coming out and saying it. So, perhaps, "badly written" has the unsettling ring of truth to it.

This caused me to reevaluate what I write, and how I write it. If I'm going to write, I want to do it well, and I want to make sure that my point gets across clearly. I haven't always done that. What's difficult for me, however, is that many of the ideas in my mind aren't easily conveyed with step-by-step instructions, or clear cut language. I have a tendency to see things through metaphors, analogies, and the like. My writing has always tended to reflect that.

As an aspiring fiction writer, those are strengths. As a technology writer, I'm not convinced they are. I'm fairly certain people read tech blogs for clear guidance and opinion, not mystical, philosophical musings. That, perhaps, has been my biggest mistake. I need to be clearer. And I will strive in the future to do so.

But there is a caveat to all that. This isn't strictly a tech blog. It wasn't originally intended to be so. While software development is a great passion of mine, it is not my only passion. And so, I would ask that those who read here have patience with me when I choose to blog about nontechnical topics. My emotions will surely shine through when I discuss writing, politics, gaming, society, religion, or any of the other nontechnical aspects of our lives.

Overall, things are improving for the better. For those who knew me, or followed my blog before, I hope that this will mark a return to steady blogging that is enjoyable for both my readers and myself. I've given it some thought, and blogging is just good therapy.

Wednesday, October 17, 2007

NValidate: Newest Developments

And here, you all thought I had just dropped off the face of the earth or something.

The truth is that between my work, my family life, having to put an epileptic cat to sleep, turning 40, quitting smoking, and trying to get NValidate ready for its initial Alpha release, things have been pretty crazy. There hasn't been a lot of time for posting on my blog. I've been terribly remiss, and for all of that, I apologize.

Now, enough about me. On to the good stuff.

Alpha Status. NValidate will officially achieve Alpha status tonight. I'm building the source files as well. This will be version 0.0.0.10177. (The build number reflects today's date; it's a nifty convention I'm borrowing from Jeff Atwood over at Coding Horror.)

You can download the source code here and get the binaries here. Unfortunately, the source code is only available in a Visual Studio 2003 solution right now. I'm hoping to fix that by the next release. You should be able to upgrade the project to Visual Studio 2005 without any problems (I've done it myself with no problems on a test machine here). I have not tested it on Visual Studio 2008 yet.

The binaries consist of the DLL and the PDB file. This is a debug release; you won't want to be using it in production code. To use the framework, simply add a reference to it to your application and import the NValidate.Framework namespace. For more information, see the Quick Start, and peruse the API Reference. 

It is vitally important that you note that this is ALPHA CODE. Do not use it for production work.

Updated API Reference: Online & Downloadable. I'm uploading the updated API Reference to the web site tonight. If you want to peruse the API Reference, you can quickly get to it by clicking here. For those of you who like downloads, I've also created a downloadable Compiled HTML Help File that you can get here.

Community Forums. Over the last few days, I've managed to get the community forums up and running, so there are places for any interested parties to comment on the source code. I cannot begin to tell you how much I want to hear from you guys. Critique the code. Tell me all the ways that it sucks; tell me how to make it better. Suggest new tests, better techniques, ways to improve the documentation. Help me make it more extensible.

Unfortunately, I have no idea how to market this thing. I'm hoping that it will survive and prosper on word of mouth. Aside from that, who knows?

Have fun with it guys. I certainly have.

Thursday, September 13, 2007

Stealth Updates and the Group Mentality

So we've all heard about Microsoft slipping updates onto machines through Windows Update without alerting folks. (If you haven't heard about it, read about it here. Microsoft discusses it here.)

The gist of the issue is that, on or around August 24th, a mysterious update appeared on XP and Vista machines without warning. The update was a patch to the Windows Update service and several other DLLs (the specific DLLs depended on your operating system).

Reading the comments on Digg, you'll find that people generally (but not absolutely) tend to fall into three camps. For brevity's sake, we'll dub them Microsoft Sympathizers, Linux and Apple Fanbois, and the Naive.

Microsoft Sympathizers

This group feels that Microsoft is absolutely entitled to do whatever it wants to the operating system since they own the OS and you're just licensing it.

There may be a great deal of legal truth to this statement; however, as many have pointed out, it is quite frustrating and is tantamount to Microsoft using its massive legal power to coerce its customers into giving it a free reign on its computer systems. This fact alone is problematic.

Consider the countless users in corporate environments who have no choice over which operating system they must use. Microsoft Windows is the de facto standard in the vast majority of corporate environments. In development environments, knowing what patches are installed on your system at any given time is a critical aspect of software testability. You can't very well reproduce an end-user's environment with certainty if you aren't running the same patches that they are. That's why it's critical that the end-user have control over what patches are installed and when.

But this move by Microsoft (which, admittedly, may have been happening all along and only recently come to light) removes that control from the end-user and introduces a degree of uncertainty into the mix. You don't know what you're running, and you don't know that it matches the end-user's environment, because it could change behind your back. There's no notification to alert you to the fact that it did.

At some point, Microsoft must admit that their software is playing in our sandbox, and managing our data, our bits. Sure, we are licensing the operating system from them, but we're also granting them permission to run their half-baked operating system on our machine. It's a cooperative agreement. Our acceptance of the license agreement is not an explicit agreement to grant them free reign to do whatever they want whenever they want. Our hardware is not Middle-earth, and Windows is not Sauron, despite the alarming similarities in behavior.

Linux and Apple Fanbois

Any time Microsoft does anything that smacks remotely of foul play the Apple and Linux Fanbois line up to shout at the top of their lungs. They tout their wares, proclaiming that everyone should just drop everything and switch to Apple or Linux. Linux fanbois are the most egregious fanbois; it is, after all, the Silver Bullet of Operating Systems. It's free, after all, and patched daily, and you can get the source code and patch it yourself.

My god, people, wake up.

First off, the average home user isn't going to have the technical skills to be able to use any of the xNix operating systems (excluding OS X). These operating systems tend to be complex, having been built up over 40 years and counting. Their vast feature set is daunting, even to advanced IT professionals. You cannot expect the average home user to turn in an operating system like Windows, which shields them from the complexities inherent in an operating system and expect them to switch gears without introducing a whole new set of problems. The frustration from learning a new operating system alone would likely drive them bonkers.

Second, you have to take application selection into consideration. Are your favorite applications even available in that operating system? Can you get Microsoft Office for it? PageMaker? Adobe Acrobat? Decent video or music editing software? And of the software that is available for it, can the average home user go to Best Buy, Circuit City, or CompUSA and purchase it in a nice shrink-wrapped box (complete with documentation, mind you), or does he or she have to go to some obscure website that he or she may or may not trust and download it (possibly with a complimentary virus)? And if they download it, will it work and can they get product support for it?

Third, how about device support? Can they plug all of their peripherals in it and have them just work? Or will they have to go on a mad search for device drivers again, like they had to back in the days before Windows XP? Sure, if they're IT professionals, that's a snap. But if they're the Average Home User (TM), that's more than they're usually able to deal with. It's probably going to tick them off royally, and they're going to wonder why in the heck they bothered with this operating system in the first place. They'll be wondering, "Where's my plug-n-play support?"

Fourth, how good is the font support? Does it support true WYSIWYG? Or does the type look completely different between the screen and the printer? The same could be asked of the colors. That's going to be really important for the average home user who's working with videos and photos, printing calendars, Christmas cards, and invitations, you know.

Fifth, if they need to do their office work on it, will they be able to do so? If so, how difficult will it be to do that? Will they have to be rocket scientists? And if it breaks, who do they call? I mean, if they were able to call their brother or their kid before, because he was a Windows guru at his company, will they still be able to do that? They've just switched operating systems, and now no one knows anything about it. They're now an island in the middle of a Windows ocean. They've effectively isolated themselves from everyone. How long do they have to wait before they can get meaningful support in an emergency?

Now. Ask yourself a really serious question and think hard before you spit out a really ludicrous answer. Are you really going to tell someone to risk losing all that support just because the browser isn't that cool, or because there are a few security loopholes? Or because you found out about these stealth updates from Microsoft?

Sure, we live in a Microsoft world. Are all their products perfect? Heck no. I work with Microsoft products every day, and I can testify to the fact that they aren't. I also own a Mac computer at home, and I happen to be a big fan of OS X. I've also had the occasion to use Linux. Each of them has their pros and cons. But I'm here to tell you that there is no silver bullet. Statements like those being made in these comments are asinine, short-sighted, and utterly ridiculous. Linux is not the solution to everyone's problems because it isn't the ideal operating system for the average home user.

Average home users need an operating system that's easy to use, has a large selection of over-the-counter applications, is secure but not intrusive, supports all of their peripherals, and has great product support. In my opinion, the one that comes closest to that is Mac OS X. However, it's pricey nature makes it cost-prohibitive for the average home user; and that's one of the reasons we live in a Microsoft-dominated world.

Sure, Linux is cheap. But the over-the-counter application support just isn't there, and the GUIs, in my opinion, still look like their in their infancy. And they're still targeted at tech-heads. When all the Linux variants start targeting the average home user, and the over-the-counter application support gets there, and they get really good device driver support, things might change. But there's no way on earth I'd ever recommend it to my family or any of my non-technical friends. They'd go out of their minds trying to figure it out.

So, in the end, I'll continue to read these kinds of posts from Linux advocates and shake my head. In my personal opinion, statements like these demonstrate a complete lack of comprehension when it comes to the average home user's computing needs.

The Naive

The last group believes that the patch from Microsoft is just a patch to the Windows Update service, and that, consequently, nothing could possibly go wrong. We're all blowing things way out of proportion, and everyone should just forget about it. I mean, really, what could POSSIBLY go wrong?

Well, let's think about that. Anyone with even a passing familiarity with DLL Hell knows from experience that any number of things could go wrong.

The notion that Windows Update isn't an integral part of Windows, and that patching it won't screw up something else is naive and shortsighted. Just ask anyone who was recently screwed over by the WGA flap when their perfectly valid Windows licenses were suddenly declared invalid due to programmer error.

If Windows Update can download software onto your machine without your knowledge, and if it can do so without notifying you, it can download buggy software onto your machine without notifying you. In a corporate environment where software must be vetted through the IT department before it's released to the masses, this is particularly worrisome. It's not the IT Staff that we're worried about here: it's some bloke at Microsoft accidentally releasing prerelease software through this stealth update mechanism.

Yes, it's a theory, and a hypothetical situation at best. But here's the scary part: it can happen, and it already has, at least once, and it affected a LOT of users. So those who casually dismiss it as "nothing to worry about" are viewing the situation with rose colored glasses.

So while I won't tell everyone that they should be panicking and seeing conspiracies everywhere, I would tell them that they shouldn't so easily dismiss a very real concern, and that they should definitely view the situation with its due gravity. Windows components are tightly integrated; patching one of them could easily break others, and assuming that a patch to Windows Update is a perfectly safe operation is misguided and a sure way to set yourself up for a nasty surprise down the road.

Thursday, September 6, 2007

The Joy of Slowing Down

A couple of things happened when I decided to go public with NValidate. First, I decided to rewrite it from scratch. There were suggestions I'd received from others that I really wanted to incorporate, and I didn't want to do them piecemeal. I also wanted to review the design and architecture, and that gave me the opportunity to decide exactly what it was that I was trying to accomplish, who my users were going to be, and what I wanted them to be able to do with it once I released it.

I also decided to switch languages. I'm in the process of porting NValidate from VB.NET to C#, and I'm enjoying the experience thoroughly. While I'm doing that, I'm fully embracing test-driven development.

All of these things together have combined themselves to force me to slow down in my approach to the development of NValidate. It's startling to reflect back on my professional experience as a software developer and realize just how haphazard much of it has been. Part of that haphazardness has been my own doing, but a very large part of it has been due to the rushed nature of software development in general.

We always seem to be in such a big hurry to get things done that we cut corners in all the wrong places. A vague statement describing a problem somehow becomes the vision statement which in turn becomes the requirements specification. We slap together a prototype, and somehow the prototype becomes the product. We shortchange testing, shortchange defect resolution times, shortchange staffing ratios, and yet still want it out the door on time. We cut features, go cheap on the aesthetics and documentation, and rush a piece of crap out the door just to beat the competitor to the market. All because the first guy to home base usually captures the market share.

God, how I wish that would change.

It's obvious when you're forced to use a product that was rushed out the door or that was cheaply made. And that's any product; it's not just software. Typically, you know within a few moments of having to use it. It either lacks the features you thought it had, it lacks the power to do any real work, or it breaks too frequently to be of any real use. Some of them, while useful, are so gaudy that you would never leave them out where your friends or family could see them. It's embarrassing to have to use them.

It bothers me to think that some of the software that I've had to work on the past, and some of the software that I've designed in the past, is of that caliber: it's only fit to be shoved into a kitchen junk drawer.

That kind of software need not be a mandate. Rather, it can be a thing of the past if I take the time to slow down and make useful, powerful, well-designed software that people are actually excited to use. But that requires slowing down, and thinking my way through the design, the requirements, the architecture, what the consumers actually want and need, and how to give it to them in a way that compels them to use it.

And that's where my experience with NValidate comes in. (You knew I had to be going somewhere, right?) I've had to stop and think my way through the design and architecture all over again. It's not just me that's going to use it. What do other folks likely want from something like this? How will they use it? How should it perform for them? What languages will they use (programming and spoken)? What are the big design goals (performance, memory footprint, extensibility, maintainability, etc.)?

So in the process, I actually get to do it right. And it's refreshing. I have a vision. I have the design priorities. I have the platform selected, and I have the language selected (and a compelling reason for the language: it's an open standard). I have a rough idea of what I think the end users will expect from it. I have the base architecture sketched out and documented. When I code, I write the test cases first, and then code to satisfy the test cases. There's no fluff. It's lean. It's clean.  

Slowing down is a joy. There's no panic involved here. I'm enjoying the project, and I'm looking forward to its initial release. I'm not even really worried about whether or not it's widely accepted by the masses. The opportunity to develop a piece of software that's well documented, using a slow, steady approach to its development instead of a rushed, haphazard approach is rewarding and fulfilling in ways that I never imagined.

I've got twenty years and counting under my belt as a software developer. The vast majority of that time has been spent working at companies where "best practices" were either unknown, paid lip service to, or looked upon as something that were typically beyond the fiscal reach of the firm. But my experience with NValidate has taught me something surprising: my confidence in the product is leaps and bounds ahead of anything I've written before. Granted, it's not rocket science, but I am left wondering if that same degree of confidence isn't directly transferable to larger projects were we to adopt the mantra, "Slow and steady wins the race."

Slow and steady, careful and methodical. Take your time, think your way through the product, and stop rushing through everything. Invest the time you need to design, architect, plan, code, and test. Don't shortchange yourself or your customers in the name of "time to market." While there's always something to be said for getting something out the door, I'd like to think that most customers would rather have something that works and works well, rather than something that looks pretty and blows their foot off.