From the perspective of most people, web software development is much simpler than compiled software development. Coding a desktop application should require far more planning than coding a web application, right? On the other hand, compiled software developers see most web applications as silly toys and most web application developers as silly people who don't know good software from a hole in Vista.
So how can these two perspectives be reconciled? The fact is, web software development and compiled software development are exactly the same. Both have attracted different types of developers and, in some cases, different types of users, but the same principles apply. By opening the eyes of web software developers to the beauty of good software design, their opinion that web software doesn't require much planning will change. At the same time, with the increase in quality in the design of web software, compiled software developers may actually begin to show a little respect for "silly" web software developers. Well, maybe.
There are some very basic questions you should ask yourself when designing ANY software:
Can I make it easier to code additional functionality in the future?
Some develop with the sole purpose of checking items off the list of requirements. True, this may help you meet your deadline faster (though even that is not likely). But what happens when, six months from now, your client asks for another feature to be added? Did you anticipate that feature request? More realistically, did you code a framework to support quick addition of any request? Here are some ways you can do so:
- Follow the DRY (Don't Repeat Yourself) principle. For example, do you find that your code is similar or even identical in different parts of your software? It would make far more sense to generalize the code and put it in a single function. Later, when you add a feature that requires similar code, you simply call this function. This works especially well for pulling and massaging data from your database.
- Anticipate changes in data. Sure, your client may say that "red" and "blue" are the only options, so you figure an enum in the database will work just fine. Don't be so trusting. There's an N% chance that your client will remove or add colors in the future, where N is large. Create a separate table for these options, and don't feel silly when there are only two rows in the table at your initial launch.
- Correctly identify relationships in your data. Does a shopping cart have an item, or is it the other way around? Can a cart have more than one item? Unless the alternative is absurd, don't ever assume that a cart won't have multiple items, or a user won't have multiple profiles, or a post won't have multiple comments, even if your client swears that they want to "keep it simple" and only have a one-to-one relationship.
- Separate anything that looks remotely like an option from your logic (i.e., don't "hard-code" anything). The number of pictures per row in a photo gallery, the number of file upload fields in a form, the maximum dimensions of a profile photo--all of these should be variables or constants in your code. Initially, before the client asks for the ability to modify these options, they can be set in a separate config file for the application. As the client realizes that these options need to be configurable through the web interface, it will be easy-cheesy to accommodate that.
Can I make it easier to maintain this code?
Even if the client never asks for additional features, he may want "tweaks" to the software. Are tweaks going to be just that, or are they going to require an overhaul?
- Separate design from content. I can't stress how important this is. For instance, in a web application, have just a few source files (like a header, a footer, and a stylesheet) that define all design elements. If your client wants a re-design, you won't have to modify every single page of the website. This seems like common sense, but it's amazing how many people will forgo this huge time saver because "it's just a small site."
- Separate data from code. What if your database schema changes? Don't spend hours modifying eighty-two source files because you add or change one column, or worse, avoid making changes to the software that would improve functionality or efficiency because it's too much of a pain to make them. Your database queries should be quarantined in functions. All your application should know about is functions like getUsers, addUser, getCart, removeAccount etc. To demonstrate how flexible this can be, imagine converting a web application from MySQL to CSV flat files (don't actually do this, or I'll shoot you). None of your page-to-page code would have to change; you'd only have to re-work a few functions responsible for accessing data.
- Keep things organized. This is a broad point, and touches on things like consistent tabbing of your code blocks, sane file naming conventions, sane directory structure, and grouping library functions in files. There's a place for everything, and everything should be in its place. All files should be included at the top of a file, and, ideally, included in only one file. Don't include a source file in the middle of your code just because you need to call a function defined in that file on the line below. How in the world are you going to follow that logic later?
How can I make this code usable in other projects?
It's really nice to have a battle-hardened library of code that you can plug into a client's site for oft-requested functionality. Really, by taking the advice above, this takes care of itself. But just to stress a couple important points:
- Separate data from code. You wrote an awesome photo gallery module for a client, but your new client uses a different type of database. It shouldn't matter. Just rewrite your data access functions.
- Options, options, options. One client may want four photos per row, but the other may only want three. Even if you don't have a web interface for them, separate all options from your code and keep them in a config file. By changing only a few config variables or constants, you can completely customize an application for a client.
- Separate design from code. How's your client going to feel when he sees an identical gallery on a competitor's site? Allowing your clients to skin their application to fit their branding gives them warm fuzzies inside.
This is a huge topic, and I've only scratched the surface. I will expound on some of these points in later articles. Please leave additional points in the comments.