A recent TechRepublic discussion focused upon the idea of anticipation in program design. I answered that the designer should not try to anticipate the limit of the user's needs, and that the software should try to anticipate the user's actions. What exactly does this mean, and how does it relate to my recent theme regarding how and why?
Regular readers will be aware that I advocate the idea of the software developer viewing a project as a method of fulfilling the user's ultimate goals, not necessarily writing the software that the user originally had in mind when they requested the software. Look at the common spreadsheet. It started as a means of replicating what accountants, bookkeepers, and other number crunchers were doing with ledger books. Now it gets used not just for that purpose, but as a quick, easy to use, lightweight database. If the developers of software had it designed so that all it could do was perform basic numerical computations on columns of numbers, it would not be very useful at all. It would have fulfilled the original design request (replicate with software what was done with ledger books), but would not have met the true why. The real why was "we need to be able to put data into a Cartesian coordinate system and perform operations upon that data." As users push spreadsheets beyond their intended purposes, the software developers add in functionality to address the new uses, which allows even further innovation by the users.
This is one reason why I am such a big fan of interpreted programming languages. Interpreted languages allow the developer and the user to quickly expand functionality beyond the original specifications in ways that were never imagined. A piece of software that exposes its functionality to a macro or scripting language (always an interpreted language) is always more useful than a program that is compiled with whatever functionality the developer put in and is unable to do anything else without talking to the developer. This is not to say, of course, that all software should be written in interpreted languages, of course, but that they should support the use of an interpreted language within the software itself. Providing the user with a simple macro language within your application directly addresses the idea of not anticipating the limits of your users' needs.
Especially when working with an interpreted language, it is extremely easy to separate the business logic from the presentation logic, even in a desktop application. I discussed a potential project today with my boss. As we analyzed the user's why (one user program), one thing that jumped out was that the user would want to have us make wide scale changes to the business logic as their needs changed, and that providing them with an entirely new installation with each change was going to be unrealistic to do. The solution that we are going to propose? The application itself will be written in VB.Net, but all it will do is pull data from the database and expose core functionality to a Perl interpreter that will eval() the contents of an encrypted file. The end result? Business logic can be edited and altered without requiring a full recompile/installation, and users with minimal programming skills should be able to make minor changes themselves. That is handing power to the user. They do not want to call us for every minor change, and we do not want to support them for every minor change.
Especially when developing software that will be used by a wide and diverse set of users, it is vital that the developer not attempt to anticipate the limit of the users' needs. Indeed, it is equally important when software is aimed at a very small, specialized set of users. The "large audience" software such as graphics editors, office suites, Web browsers, email applications, etc. can be used by so many diverse sets of people, that it is impossible for the developer to conceive of every possible way to use them. For the "small audience" program, the users tend to be extremely specialized and have their own particular way of working; what may be perfect for one user will be absolutely worthless to another user.
On the other hand, the application itself should respond to what the user is doing, and anticipate their needs. This is, in many ways, a matter of interface design. A piece of software that responds to a user's attention and gestures the moment it recognizes a unique pattern is one that will be more useful than one that doesn't. Photoshop, for example, shows not just a thumbnail preview of what the changes will look like as you adjust the values of the tool you are using, but also shows the picture itself changing. This saves a lot of time; instead of adjusting the values, clicking "OK," then having to undo the change and try again, you know if the results are going to be what you want before you even click "OK." It would be great if Office suite software did them same; mouse over the "Bold" button? Make the selected text bold while the mouse is over the button, and un-bold it when they stop hovering over bold. That will let the user see if bold is really what they want before they commit to it.
Prefetching data is another great way that software can anticipate user's needs and deliver extra value in the process. If the user is paging through a large data set, go ahead and start loading the next page's data in the background (resources and bandwidth permitting of course, no one likes an application that makes a computer slow when you aren't doing anything). The user will see instant results when they click to the next page, instead of waiting for the results. This is one reason why Web-based applications have much less potential than desktop applications; their mechanisms for caching stink, even when using
Even the programming tools we need fail to anticipate. Developer's tools are unique; they are written by the very people who are the intended audience. Yet, they fall very short in terms of anticipation. Version control is especially bad at this; it does not let you know that another person changed code that your code relies upon in a way that breaks your code until you refresh your code. It also does not notify that person that they are about to break your code. This is a situation which causes a lot of problems.
I love the idea of code that anticipates the user's needs. This is one direction that I see Steve Gillmor headed in with the Gesture Bank. If developers can access an aggregated source of user's attention and gestures, they can write software that reacts as soon as the user begins to take action, not when they finalize the action. Really smart developers will have the software develop that knowledge on the fly on an individual basis. And that will let the user focus on why they are using your software, and not how they are using your software.
Justin James is the Lead Architect for Conigent.