This is a continuation from Part 1. If you have not read that, I encourage you to read it first.
In my last post, we were looking at a large picture perspective of web applications. I first must apologize for a misuse of terminology. I used the terms “PM” and “Project Manager” when referring to the role being described in my last post. Strictly speaking that would be incorrect as just setting up premade software would not concern a PM in all likelihood. I should have just used the term “manager”.
As we continue, we are going to look at usability and maintainability. We are going to continue to approach these problems from the perspective of effort/time and decisions rather than technical aspects except where very useful.
Usability is arguably the most important part of the project for a manager. This is really what needs to be reasonably well defined before hand and what can make or break the final project.
The largest and most important part of this is a well defined list of features. After all, this product is providing the users with access to some features. If they are good enough, the users will continue to use the product. If the features are lacking, convoluted, difficult or time consuming, wrong, inappropriate for the target audience or anything else negative, this can spoil the project. Since even though all these descriptors are similar they are still extremely important, I want to look more specifically about what each can entail. More importantly, how features could be better defined to remove the problem and give a better product.
Lacking features references when a product lacks an element of completeness to the user. This comes from a couple of ways. The most direct is when a product helps the user toward a goal but fails to help from the start or until completion. Having to use external tools or do more work by hand is generally unacceptable unless there is good reason why the product cannot do more (licensing, technical limitations, etc.). Even if it might be more work to do it by hand, users may choose to do all the work without the product then simply because it involves less context switching.
The more subtle way that a set of features can be lacking is when all of the features from start to finish do exist, but they are not well done. Not well done can refer to both flawed in a different way (possibly one of the ways described below) or that the feature itself does not provide enough help to the user to really be seen as a full feature. For example, if something expects html formatted input but only provides a text area, this is not very useful or friendly to the user (unless the user is known to be very comfortable with writing html by hand and not much writing would be needed).
How do we avoid this though? Well, use-cases can help to actually identify all of the features that really need to be developed. These use-cases need to be detailed enough to also convey technical knowledge of the user and then tested with that level in mind. Features that are not well done tend to only be discovered by tested (and frequently more public of testing due to people associated with the project might know too much to be able to evaluate short comings).
Convoluted features can pose another large problem. The actual cause of a feature being convoluted is two-fold. The first comes from the feature being hard to find. If it is not presented to the user anywhere, how can one expect a user to take advantage of it? I could easily see this coming up when you have say a bookmarklet that you want people to use. If there is no real way to find a link to this without prior knowledge, the feature is convoluted to find and essentially does not exist to most of the user base. Presenting a feature only where it is not relevant has the same result. These can be evaluated by tracing paths to how to find each feature and determining if that is a logical set of steps for a common user or not.
Being convoluted can also refer to a poorly explained feature. Sometimes this is the result of a bug in rendering. If you cannot see the explanation of a field, it is much more difficult to use. If there are constraints on input, these also need to be explained to the user ahead of the user trying to use the feature. Also, error messages should be useful when seen rather than cryptic or exclusively for debugging purposes. Error messages should also exist for all errors so that the user is well aware when something has gone wrong (and whether it was a random fluke such as a race condition, server error, or user error).
Possibly one of the most difficult things to test when the system is understood is how difficult or time consuming the features are to use. That said, it is also extremely important. After all, the service being provided is here to help users. In order to do that, these features have to be intuitive to use and helpful whenever possible. The best way that this can be thought out is by considering the actual use case down to each input. If a user has to enter 40 different values before they get any feedback, there is a decent chance something will go wrong. Also, when actually testing the product, the tests should be timed especially between interactions with the system (or some feedback at the very least like notifications of auto-saving).
Difficulty is something usually hard to measure by people involved on a project due to their understanding of what is required. This poses two possible ways to evaluate the situation: the most authentic way to test this would be to have the system tested by outsiders before it goes live. Finding good and willing outside testers is difficult and also is harder to get fast and good feedback. Because of that limitation, some evaluation still can come internally. The biggest question is how much effort must the user put in outside of the actual function to cause it to work. Does the user need to already have certain figures calculated? Can the product be expanded to help with that? Can any prerequisites be helped by expanding the product some? Conversely, is the product forcing the user to accept its help when a user may be able to figure out the answer on his or her own without the need of assistance? Answers to these questions are important and should affect how the product exists when it is moved into production.
Possibly the easiest one to test is the validity of any output generated by the product. This is somewhat of a demand to really unit test and hand test each and every feature. If there are limitations, can they be either handled gracefully or is the user informed? This I won’t go into so much because this actually would come up mainly in development and can be handled to a large degree there.
Our final question that management should investigate is whether or not the features are appropriate for the target audience. Exactly who might be included in the target audience is very important. If there are several categories, each feature needs to be evaluated from the perspective of that category. Appropriateness is evaluated through many of the above methods. Is there appropriate information to allow the audience to use the feature in a timely manner without problems? More importantly, would this audience actually use the feature? Can you make the feature more useful? It’s possible that the fact that an audience would not use a feature is acceptable (like advanced users may not take advantage of a guided mode). This should explicitly be realized and probably documented. Also, if there are distinct groups of users, maybe the product should tailor itself to present the most appropriate features first.
When thinking about a product, how much work it will need in a years time or maybe several years. A common thought is that the set up is likely to be replaces. Experience will dictate otherwise in many situations though. Maintainability needs to be considered in a number of situations: work needed to update, expand, move between hardware, and tightness to dependancies. Again we’ll look at each individually.
Even after a product is done, it is very likely to need updates. No where is this more important than the web where the exposure to the world is huge. As such, the ability to roll out a new update successfully is key. Success in an ideal world means next to no work from the administrator and no noticed downtime from the users. The more complicated the system, the less likely this is. If the product is packaged, it is good to look at how updates are distributed ahead of time so that an idea of effort can be gaged. This gets more complicated also in distributed systems. Can an update be applied one server at a time and they all continue to cooperate in the mean time or does it need to be instantaneous? What happens to any users currently logged into the system? A large concern is data loss. If someone is working in the system as something is updated, will that work be lost? The web is in reality stateless though state is frequently hacked on top of it. Any changes to how state or caches are handled can cause problems for users. Can users be warned about an update that is coming up?
With answers to these questions, one still needs to look at what has to be done on the administrator’s side. Can the update be completed completely from the management interface? Is direct database access required? From a manager’s point of view, how many people will be needed to normally maintain as well as update the system? Needing a full team of IT people to stay late to do an update is costly to the company. Choosing a product that someone without technical ability can update with little effort is much cheaper in the long run.
Projects frequently start much smaller than they end up if they get popular. As such, a question of how to expand this project is very important. This can be important for clustering and redundancy. Does the product itself actually handle being distributed or is that something that has to be handled at the server or database level? Very database oriented applications frequently can be simply handled by using clustering and redundancy features built into the database. If, however, the program also uses local temp files, suddenly load balancing is much trickier. Also, does the product handle increases in hardware gracefully or not notice? If something has to be reconfigured to actually become aware of changes in say RAM, this is another sticking point in long term maintainability.
Hardware changes begs another question of just moving servers. Frequently it is useful to move software to different hardware for better reliability or performance, but some software is not as easy as others to move. Could one server be brought up and another taken down without any noticeable change to the outside world? Can any problems be reduced or removed by simply running the system in say a Xen or Hyper-V virtual machine? If that would work, can the organization support this?
A lot of the questions of moving between servers or hardware might actually be more related to the software’s reliance on the underlying system. It might be very beneficial to performance to take advantage of certain aspects of the operating system. This could create a dependancy on that operating system. Though there currently is a good administrator of AIX systems, is it a wise idea to require the software to run strictly on those systems? More commonly, there can be dependancies on libraries and the like. Most of the time the binding is loose enough that the library can be upgraded past the starting point without any problems. This is not always true. If, for instance, the program was built against a beta version of a library, the actual interface might change in the future. Because of this, an update may actually break the system. This can also exist in underlying languages. If the solution is java based, for instance, would it work well with different java runtime environments? I have personally seen software that would not work correctly with java versions later than a certain point. Sometimes this can happen with interpreted languages too. How much does the software depend on deprecated code? Is it documented so that future administrators can determine whether or not it can be upgraded?
I realize this has been a long post, but I hope it helps with planning projects. After all, better products come from better planning. As a developer though, I believe that it would be good to actually look at approaching how to implement some of this and the ease of development. In my next post we will start to look at advantages and disadvantages of various web languages and frameworks. If you have any comments on what I presented here or would like to contribute to that post, please feel free to email me or post a comment below.