Musings from a Southern software developer

The Sins of Bad Software

Writing software is difficult at best. It takes a particular mind to follow the code, be logical, and clarify ones thoughts out of ambiguity. Writing GOOD software is even harder – almost impossible. Lately I have been working with software that seems to break the cardinal sins of programming. Here are some things to avoid in your next project:

If you create a convention – stick to it. Nothing is worse than debugging a program only to find that two similar tasks are executed in totally different ways. Good code can be resused again and a gain in many similar scenarios.

Write a bullet-proof installer and uninstaller. Better yet – customize your installation to the specific platform it is released on. If it is a Linux RPM architecture – make a RPM. If it is a DPKG system, make a DEB. If it is Windows – well, just stick with InstallShield and you should be ok. Your installer should check for different scenarios and correct minor problems automatically. The uninstallation should back everything out to the state it was in before the installation was run. Satisfy any dependencies using the package manager, or bundle them internally in your own code.

Don’t write something that requires a web server to restart in development. This sends development and troubleshooting time through the roof. In production this is very forgivable (almost expected) the goal is performance. In development, if something caches, provide a way to clear the cache. Better yet – make it automatic based on the environment.

Store your data in a database. This seems like an elementary concept, but many a fool tries to write files the the web directory, or leverage LDAP in a way that mimics the functionality of a database. Use a database for what it was meant to do.

Don’t repeat yourself. Anticipate database credentials changing, or server DNS names changing. Your program needs to have this information stored in ONE location. Period. Any other way and you are just doing it wrong.

Anticipate the need to cluster. Your application should be designed so that it can be easily scaled up and easily scaled down. The complexity of setting up a new server should be minimal. Also, make your deployment setup flexible. If you have to reinstall a program to provide the ability to cluster, then that program was not written correctly.

Provide a central location to change settings. Don’t make the administrator jump through hoops looking through files, LDAP, the Database, and the GUI to change settings. Provided a coherent, consolidated interface for changing all administrative settings.

Don’t reinvent the wheel. If you need an email server, web server, calendar implementation, etc don’t write it yourself. Doing so is a fools errand. There are millions of projects out there that can be leveraged inside your solution. Using existing technologies reduces your code size, improves maintainability, and provides a better support base for your customers.

Use current standards. If your application is written using a a language or platform that has since been replaced by newer technologies, you are probably missing out on many recent innovations in technology. Stay current. Use current industry-standards.

Know the needs of the intended users. If you make a system so complicated that end users don’t use it, you have done something wrong. Users don’t need to be intimidated by software. A sign of good software is one you don’t have to train people to use. The interface should explain itself. Avoid the classic anti-pattern of “developers operating in a vacuum”.

Document with quality, not quantity. Documentation is important, but too much is almost as bad as none at all. Lay out conventions for the documents at the front to save repeated explanations later. Don’t re-explain the same concepts in different areas of the documentation. Give your documentation form, and flow instead of making people jump around. Save time and space by skipping elementary concepts, like moving files, making a backup copy, etc.

Provide timely, knowledgeable support. Usually when support is needed it is mission critical, and an issue that is on a deadline to resolve. It is very frustrating to be bounced around by support technicians that seem to know less about the software than you do. This should be a priority of any company, and should never be cut back because it is a soft area.

Provide a solid and simple API. You can never encompass all that a customer might use your project for. Focus on the common tasks, and provide a way to extend your application to handle the rest. Give the customers a lot of flexibility, with a solid, and easy to use API. Don’t lock them out of your application.

Allow access to your source code. Many people will disagree with me on this one, however I think it is important. Many, many problems can be solved by the consumer without ever contacting your program’s support department if the consumer can just see what is happening behind the scenes. It is much easier to pinpoint where a PHP, Python, or Ruby application is failing, than it is to pinpoint where a C#, Java, or other similar application is failing. If you don’t provide

Provide meaningful error messages. A stacktrace is not a good error report. Error logs should indicate what failed, and where without information overload.

Keep it simple. There is no reason to make solutions more complicated than they need to be. Use the most natural solution, instead of re-creating the wheel. When a component is no longer used, get rid of it.