I recently inherited a web app from a dirty, nasty, stinking contractor that claimed to be a competent enough programmer to be left alone to get things done. Unfortunately, we took him at his word. Functionally, most of the web app seemed to work at first glance. However, once the client took over the reins and actually started using it things went downhill fast. The contractor disappeared after payment (die reputation DIE!) and I was left to try and get things working properly and performing up to snuff while the client limped along with what they had been given.

I decided to document a few of the things that I found wrong along the way.  These are really just things that every good programmer should already know to avoid… but obviously some people need to be reminded (or taught).

Update – 05.18.2010 – Some people thought that this article was too sarcastic.  While I thought it wasn’t sarcastic at all, it does exactly what the title promises and teaches people to suck, I’m always game for being constructive.  So I wrote an offset to this article – 10 Ways To NOT Suck At Programming.

#10 – Don’t store settings in a configuration file

When you’re writing a sizable application, things like database connections and SMTP server information will be used throughout the app.  The best way to make sure your app is entirely immune to maintenance is to redefine those little bits of information every time you need them.  So instead of putting them in the configuration file (Web.config or whatever) just leave them in your compiled code.  Whoever inherits the app will thank you for sending them on a hunt through thousands of lines of code to change which SMTP server is being used.  What’s even more fun is when the next programmer only finds 14 of the 15 places where you’ve used this code and a single instance somewhere deep in the app silently breaks hundreds of times without anyone knowing.  Sometimes it’s helpful to build the variables in inconsistently concatenated strings. The repeated and more frequent interaction between the new developer and the disgruntled client will help strengthen their relationship.  And if you don’t hook up that love connection, who will?

#9 – Don’t store variables in [any] memory scope

One of the great things about databases is they store your bits of information and allow you to access them whenever you need them.  To make sure your app is as terrible as possible, you’ll want to be sure and access the database every time you need a bit of that information.  The more common the information is that’s needed, the bigger win you’ll have by making a new database connection to get that information.  Non-sensitive user information is a great use of this prinicple.  Don’t worry about defining a user’s information, such as “isAdmin” to a variable and using it throughout the current request.  Just query the database each time you need to know anything about the user.  After all, the client paid for that database, we’d better get as much spin out of it as possible!

#8 – Use arcane plugins

If the client has a non-standard request, such as formatting a table in a way that is outside the abilities of your WYSIWYG editor (colspan are hard).  You should definitely hit up the interwebs and search for random unsupported closed source plugins to do the work for you.  If you would spend almost an entire hour writing it yourself, you should spend at least 3 hours searching for and getting a plugin that does roughly but not exactly the same thing.  Bonus points if you can get a plugin that doesn’t do what you need, but offers 15MB+ of functionality you have no use for and include it without getting caught.  Bonus bonus points if the documentation for that plugin is in a language not native to your market (for example, if you’re working in an English speaking shop look for plugins that are documented only in Spanish or German).

#7 – Never, ever remove functionality

Over the course of developing a large application there are bound to be times when functionality you were working on proves itself to not be needed.  Now, to be sure to leave plenty of dead ends for those who come behind you to get lost in, never delete that functionality.  Maybe even comment out random parts of it, or even hundreds of lines of it at a time, but don’t delete it.  Imagine the hours of fun the future-crew for this app will have while they trace through this functionality only to find that it isn’t needed!  If you can make it seem needed, without actually needing it, it will even keep them from deleting it themselves…  This way the fun is exponential!  Oh, a bonus on this one… if your project uses source control and multiple server environments, be sure to have a different version of your files (both code and compiled) on each server and source control.  This way no one will know which one is live in production and who doesn’t love a good round of Code Russian Roulette?

#6 – Screw performance

Large applications, you know, the ones that pay the bills, are generally needed because they deal with large amounts of data.  Sure, during your development process you’ll create 20 or so test records.  Take my word for it, there’s no need to even worry about what happens once you get to 25 records, or even 1,000!  Obviously, all pagination will work just fine and performance will never take a hit.  So if it compiles, ship it!

#5 – Nest major logic/functionality in loops

Now obviously, we’ve already covered #6 so we know that we’re working with large amounts of data.  And inevitably, there will be plenty of looping through that data to do work with it.  If you want to make sure your application is really difficult to maintain and completely unusable to the client, you should embed major functionality and/or logic inside of these loops.  For example, instead of running a query against the database to get ALL the data you need, storing the data in memory and working with the variables in memory during your loop, just get all the data except one field up front and loop through it… then on each loop you should get all the data again, and now include your extra field.  This will guarantee that your app will never survive more than 5 concurrent users (re: #6).  So for review:  Get data > create loop > get data > work with data.  I’m sure you see some room for added idiocy in that process, so feel free to nest this idea as many times as you want.

#4 – Document NOTHING

Look, documentation is for morons.  I mean either you can read the code or you can’t, right (this was actually said to me at one point)?  Of COURSE the next programmer will be able to read the code.  What’s really fun though, is when you document absolutely nothing, especially not your intent.  It pays to keep them guessing.  You’re mysterious, like a ninja.  No need to let someone get all up in your grill, knowing everything about what you were trying to do.  Because if you document what you’re trying to do and then don’t end up doing it… well… that’s just embarrassing.

#3 – Use and reuse illogical variable names

There’s going to be a LOT of variables needed to work on this app, so you’d better choose a movie or television show with enough characters to use all the names.  Lord of The Rings, Star Wars and Family Guy are all good choices for this.  Maybe you can even form relationships with the variables.  That way, you never have to kill them!  You can have variables that are chameleons, changing their usage and values throughout processing and you can recycle them for something new each time you need a variable for new functionality.  It’s like they’re growing up, evolving, right before your eyes!  After all, you’re trying to be green and reduce your carbon footprint so recycling variables just seems like the responsible thing to do!

#2 – Catch all errors — and do nothing with them

Most languages / platforms nowadays have really good error handling built in.  They’ll die somewhat gracefully and give enough details through the default error output to be helpful.  You must not allow this to happen!  Start off by wrapping nearly every tiny piece of functionality in a try / catch phrase.  Then… inside the catch… put a comment, like “// It borked lawl.”  This will ensure that if anyone wants to work on this app, they’d better spend the time getting to know the app and it’s adorable character variables before they start wrecking the app altogether.

#1 – Duplicate functionality

If the client tells you that they need two pages:  One for an administrator that has all of the details on an item along with a button to delete it; and one for a regular user which has all of the details on an item without a button, you should create multiple pages to accomplish this.  In fact, if you can make pages for each user group that would even be better.  Making a separate page for each user is the ultimate success.  So ninja up and get serious on this one, because it’s your last line of defense against the teeming hordes of qualified individuals who will inevitably be bewildered while trying to update your carefully constructed Pandora’s box of an app.

This is by no means a comprehensive list.  On this project alone I could name 10 more things that could make you suck.  But I’ll leave it at 10 for now.  Anyone have more to add?