For the past 10 months I have been freelancing. During this time I have been exposed to a wide variety of code created by many individuals of vastly varying skill levels. All of these projects have been php websites and webapps. Of course this had led to tons and tons of different architectures. All of these projects have had one troubling thing in common: The projects were created with absolutely no thought about maintainability. This is, in part, because of the industry. Boutiques and contractors are not maintaining the app. The goal is to ship a working product in as little time as possible. Unit testing code doesn't play into this because the time investment involved. A significant time investment is required on determining testing strategy and writing the actual tests. I have had many instances where writing tests takes AS LONG AS writing my actual functions!!! Having to budget in up to 50% more time to write tests is undesirable for every party involved.
This test-less, unmaintainalbe strategy actually works pretty well (it is an industry standard) as long as the sites never need features added. During a 3 month contract with a php boutique we had a number of recurring contracts. This involved maintaining web sites which were created 5-10 years ago. Many of these sites were from a different era, relying on registered_globals, and completely prone to sql injection. So the solution is simple right? Fix the security holes, add new features, and deploy!? No. Many of the sites did not have any sort of structure to the programs. Each file generally had 1 or no functions and hundreds of lines of code. Fixing bugs meant wading through lots of code that was more or less unrelated to the problems. Why not fix this code soup? The issues are there are set deadlines. People don't see refactoring the whole site into something that can be maintained as a good usage of time.
Writing code as if it were going to be unit tested will resolve many issues. Unit testing is important because it helps us think in terms of maintaining code. The most important aspects of unit testing are usually overlooked:
Thinking about program structure. This NEEDS to be thought about. Even for small websites. Sitting down and writing whatever comes to ones head is a sure way to reduce the quality of code and to remain a mediocre programmer.
Designing units, what are logical sections
I think a simple way to do this is to go through long code and comment what each section does. For example
// log in a user
// check user permissions
// get friends of user
When doing this it becomes very very apparent what should comprise a "section". This would makes sense to have a login_user function. Or a check_permission function. Even if they are only used one time, it still makes sense to create functions for these. This helps with the next point.
Thinking in terms of maintaining code.
- how willl this code be added to?
Actually thinking about program design will make maintaining and extending your code so much easier. Say that in addition to the facebook login that version 1 of the site uses a client wants to add twitter auth too. With a login_user function this is pretty easy. All login code can be located in this function.
Learning to create software as a series or related units takes practice, but it pays off in the long run as code is easier to work on and easier to extend.