For code to be considered 'good' it needs to be simple
and easy to understand
. It needs to be bug free
To write good code use Test Driven Development
, remove all duplication
, and name every function and variable carefully
Good code is bug free and maintainable.
In order to make your code bug free use Test Driven Development.
This discipline makes you think which tests need to be written, what are the positive test cases, and what are all the 'rainy day' scenario where the code has to cope with unexpected input data, missing files, corrupt files etc.
Taking the time to create a test plan, preferably before you start writing code, is the best thing you can do to ensure bug free code. And if you create a new test case every time a bug is found, you will both enhance the quality of our code, and equally important, you will learn from the bug. Why didn't you include this test case initialy? Are there any other places where you've forgotten this type of test case?
Writing maintainable code is hard. By maintainable I mean the code should be able to adapt and change as new requirements are added. The code should never force you to say 'we can't do that'. Maintainable code can cope with any new feature, no matter how unexpected. Equally important, the code needs to be maintainable by a developer who didn't originally write it.
When I was learning my craft it was thought that documentation and comments in the code would allow any developer to maintain the codebase. There turned out to be 3 problems with this apprach.
1. The documentation and comments were frequently out of date. Even worse, there was no way to tell if they were out of date or not, so they could never be trusted. The reasons they were frequently out of date was that it takes time to keep them updated (assuming they were written in the first place.) Typically developers don't like writing documentation so avoided updating them, and typically managers don't like developers doing anything other than coding, and so wouldn't enforce the updating.
2. Documents and comments are written in English (or another human language) which is always ambiguous, open to interpretation, and incomplete. Simple code is much more concise and understandable than any documentation.
3. Developers didn't always read the documentation and comments. Either because they didn't know where it was, or because they didn't trust it, or because the documentation was hard to understand, or because they just plain didn't like reading.
So it turns out that keeping your code simple and easy to understand will make it more maintainable than any amount of documentation.
The three rules I use to keep my code maintainable are:
Use test driven development.
Use precise names for all functions and variables.
Remove all duplication.
1. I write my code using test driven development. As well as all the benefits of making sure the code is bug free, and remains bug free, using test driven development has actually made my code easier to understand. Because the first thing I write is the test, I am writing how to use the function before I write the function. This allows me to play with different ideas very quickly. Then when I've found the most elegant way to use the function I then write the function.
2. If a function does exactly what it is called, and only what it is called, then it is very likely to be a good function. You won't need to read the code to know what the function does. It does what it says it will.
Coding in this style I write many, many small functions. But because each function is clear and obvious the total effect is clear and obvious code.
When I was learning to code I was taught to write the comments inside the function first and then write the code second. Every few lines of code should have a comment.
Now I've learnt instead of writing a comment every few lines, call a function with a clear name.
3. Continually removing all duplication from your code is what will make a beautiful, flexible design emerge. Removing duplication is not always simple. It's not always as easy as putting common code in a function that can be called from multiple places. It might require adding classes, changing your class hierarchy, or even totally changing the way your classes interact with each other. I.e. changing your design.
It is putting this effort in of removing duplication which will give you the best design. It also allows you to write simple code. Because it is perfectly fine to hardcode things if the code is only used in one place to do one thing, and you know that as soon as you see an opportunity to reuse the code, you will reuse it, and then you will take the time to make it flexible when it is needed, and not before.