How to write really good code
1) Test *every single line*. I generally execute whatever I’m writing about once every 2-3 lines of code, once I’ve got the skeleton up. If you can’t do this quickly, change your workflow so you can.
2) Use human-language function names, variable names, method names, and class names. If a loop won’t fit on a standard IDE screen, use a human language iterator name instead of i.
3) If you find yourself cutting and pasting code more than once, use a method or a function.
4) If you’re not sure exactly how something is going to play out (like a regular expression, library system call, etc) create a very small program that only tests the way you are using it. This will encourage you to test out the possibilities involved more thoroughly, and once you get used to doing it it can be a very fast thing to do.
5) In #4, deliberately create bad data. Pass in empty strings, negative numbers, nulls, strings with SQL injection in them, strings that are too long, email addresses with no @ sign, and the like.
6) If you have a try {} catch {} – make sure you do something useful in the catch. If you need to break this rule (and occasionally you will) write a very descriptive comment as to why.
7) Know when you’re not in the headspace to code. Don’t try to program when you’re not capable of simultaneously seeing things as black and white and as shades of grey. Only you will know which emotions and thoughts make you write bad code – but in general, if you’re not in the place to program, don’t try. The rest of the team thanks you. Coding is the very essence of explaining rational thought about a subject in very very small steps, so if you’re not thinking rationally, you’re not going to write good code.
8) If you’re working on a very big project (20k+ lines), try to do all your developing in little testbed programs (as in #4) until you’ve got it working completely correctly. It is much faster to build and run small programs, and you also stand a much better chance of not stepping on someone else’s work
9) Use source code control. Check in early and often.
10) If you have a group of related data (for example, information about a customer), use a class. Even if it’s just carrying data – later you may find reasons to add methods to it. There’s a fine line to be walked here, however. You don’t want to use a class for the customer’s phone number’s format string. Usually.
11) Once you know and understand how to write code, you will see that a lot of the things your teachers tell you are basic rules are meant to be broken, occasionally. When you do break them, however, comment on which one you broke and why.
12) Build quality stuff. You never know when you will have to maintain it.
13) Refactor and rewrite. You will often get much better results the second and third time you write the same function. I actually prefer to write most things in a prototyping language (php, perl) before writing them in a compiled binary language, and I think switching languages also helps me write better code.
14) I generally write out psuedocode in human-readable language (english, in my case) before I start programming. This encourages me as a developer to think through what I’m trying to do before I start thinking about breaking it down into if/then/else
15) Every function should have a sane default path through it. switch() is a very powerful and useful tool because it encourages this. Sometimes the sane default thing to do is throw a exception.
16) For every variable that comes from ‘the outside world’ (a human out there on the net, a A/D converter, etc) make sure your code can cleanly handle completely unexpected values. What would happen if there were special characters? If it’s a signed type, did you handle negative? If it’s a nullable type, do you handle null?
17) While you’re doing #1, notice where the ‘pain points’ are. Use a profiler, or just capture high resolution timestamps. Figure out what ran slow and how you can make it run faster. This can be a fine art – for example, knowing which types of data sort will run better on the database engine and which will run better natively in your code takes quite some time to master.
18) When refactoring – if the source code is getting shorter, you’re doing it right.
19) Beware of excess convolution. Occasionally you will find you have done something silly like failed to initialize a useful variable set early in the process and instead calculated the value for that variable all over a set of nested function calls. If it feels confusing reading it, you probably need to rethink your approach.
20) Above all, have fun. Building really high quality things can be a great joy, if you let it. Remember to keep a positive attitude, and always work on having more patience. If you find yourself getting angry, you are probably not thinking rationally, see #7.
21) Remember, *nothing is set in stone*. One of the joys of programming in this era is you can go back and change your mistakes.
January 1st, 2016 at 9:47 am
For those of you who say “But Sheer, #1 is so slow..” – I remind you I’m one of the fastest programmers I know.
July 11th, 2016 at 1:55 pm
Seems like a good sound ruleset. 14 has been my method since learning 6502 Assembly, and 13 reminds me of the story about the original Doom, they wrote it on NeXT Step systems, then ported to DOS/4GW. John Carmac said that the porting process helped them eliminate many bugs.
June 16th, 2023 at 3:02 pm
I’m now curious what you’d be like as an IT professor. #12 is a good lesson for so many disciplines.