10 Ways to Avoid Writing Crappy CodePrint
1. Learn OOP and common OO principles
This is an absolute requirement. If you are still coding procedural, this is no small task. What are you waiting for?
2. Employ Test Driven Design
Code that is buggy or simply doesn't work at all can safely be considered "crappy code". TDD gives you the confidence that your code works, and the side effects force better and more flexible software design.
If you are not familiar with TDD yet, and this post has prompted you to try it, be warned: at first it will seem very cumbersome. What definitely will help is this piece of advice, which is at the core of Test Driven Design: don't write tests afterwards, write them first. Without going to much into the details, and somewhat simplified the general mantra is this: write a test first, make it work by writing the application code, refactor, write another test, make it work, refactor, etc etc. It's a cycle. The application code follows the test code, not the other way around.
I recommend PHPUnit. It has the most features and the largest adoption.
3. Refactor, refactor, refactor
Refactoring means "to improve the design of existing code". Making changes to code results in an increasing loss of quality of that code, this is known as "software decay". To battle this phenomenon, you have to constantly evaluate if the code hasn't lost its quality, and look for opportunities to improve the design beyond its original. But there's a catch. And it isn't the time that refactoring takes, if you do it properly you'll save those hours by having avoided software decay. It is the risk of change.
I can understand if you are hesitant to change code that works (at least for now). But this is where number two comes back into play: as long as you've written the right tests, you can make sure your changes don't break anything.
4. Simpler is better
Your mind should constantly be waging a battle between simplicity and flexibility. Avoid unnecessary complication.
5. Use Design Patterns
Design Patterns describe real world software design problem and solutions. Make sure you are familiar with them, buy some books. If you encounter a design problem that seems familiar take your trusty GoF and PoEAA from the shelf and look it up.
6. Don't Use Design Patterns
Once you are familiar with Design Patterns, or even just with the existence of them, it can be tempting to start sprinkling pattern implementations over your application code, just because you can. Don't. Remember a Design Pattern consists of a problem and one or more solutions to that problem. Until you have the problem, don't use the solution.
7. Accept the limitations of your language
Believe me, I know that as a programmer it is difficult to accept limitations on bending your code to your will, but trying to change the behaviour of PHP is not the solution. PHP has limitations, you'll have to live with them. If you try to "patch" them, chances are you will do more harm than good.
8. Pretend you are writing a book
It has been said that "code should be easy to read rather than easy to write". Maybe somebody else will need to understand your code at some stage. Maybe two years from now, you will revisit this code and need to re-learn its inner workings.
Semantics, meaningful docblocks and clear execution flow are everything. Imagine reading an instruction manual without pictures, filled with meaningless abbreviations, and with the pages in arbitrary order, without page numbers. That's how someone, maybe you, will feel if you ignore this advice.
9. Peer Review
Believe it or not, you don't know everything and you aren't always right. Nobody is. Getting a "second opinion" can only improve the end result.
10. E_STRICT is your friend
Make sure your code runs properly with E_STRICT turned on. Although, if you have gotten this far, I don't think that will be a problem.
11. Create a distinction between "source code" and a "build"
How does this help you avoid crappy code? It allows you to have the source code and build differ, avoiding any compromises you might be tempted to make to facilitate runing or developing the application. Bonus points if you allow the user to choose between placing everything in the server document root or just a bootstrap and the static files.
There are various build tools available, personally I use PHPUnderControl, which is a patch for CruiseControl and gives you a variety of build server features. It uses Ant by default, but I also use Phing.
Yes, there are actually 11 ;)