This is the conclusion I have come to after I recently joining a new company and a set of code from a developer who believed that commenting code was the way forward. What I found was a very verbose set of largely useless comments which litter the code and make it very difficult to read. There is another problem, practically everything is commented apart from the bit you really need a pointer on!
Now I could stand back and say what a useless developer – these comments are rubbish! This is not fair though, apart from the fact that it is entirely pointless to blame all your problems on a developer that has left the company, it is probably not true either. You may be having trouble following the code right now but the very fact that it is there after many years shows that it actually works. It’s only when changes are required that you are suddenly thrown in at the deep end and asked to work on it. Everyone who has a few years development under their belts has experienced this and it’s never easy to pick up someone else’s code even with excellent documentation. An analogy is a good way to think about this. Imagine you discovered a set of ancient Egyptian hieroglyphics – you might know what the individual symbols mean but without the context and the grammar rules, it is very difficult to make sense of the meaning. In our case, the grammar is the architectural vision – what was the plan? How was the developer trying to solve this problem?
So why are comments in code largely useless? Well, I think that the average developer adds comments to his or her code during the development process. In most projects, the majority of what we do is pretty standard, sockets, web interfaces database connections and the like. We do it all the time so generally it’s pretty easy and we feel confident. In each project (unless you are very unlucky), there is something new, something you find a bit of a challenge and tests your Googling / coding skills to some extent. Now as we do the standard stuff, we comment the code frequently and with confidence – I’ve done this before and I know exactly what I’m doing! This leads to us commenting all the really obvious stuff with some verbosity but when it comes to something a bit more difficult, we maybe have to try a few different options before we get it right. Once the Unit tests are all green, there is little imperative to go back and document your work. In other words, you get a large amount of commentary on the pedestrian every day part of your application and very little in the more interesting areas. In other words, you get lots of comments like this:
socket.connect(server, port);
Er, really thank God for your comment. I never would have worked it out!!
So that leaves the obvious question – what should you document? This is actually a really difficult question and there are many solutions proposed. Modern, agile methodologies usually say something fairly bland like “document as little as possible or only document what you need!” or in the extreme programming model “documentation is a business decision, only document what the business requires!” – these statements sound great, but actually mean very little. The business often doesn’t know what it requires and is prepared to pay for even less.
In other methodologies like waterfall, you often come across the documentation = solution type manager. This is the type of person who howls on about risk registers and “full” sets of documentation. Documentation in itself solves nothing and as soon as someone mentions things like risk registers, my hackles start to rise!
I see very little point in documenting known issues or architectural debt for that matter. You are never going to fix them and having them in a database is fairly pointless – the truth is when a system goes into production that represents your architectural decision – that’s the system and either it works or it doesn’t.
You’ll notice I haven’t answered the question yet – what should you document then, Mr Smarty Pants? Well, I think good documentation comes from a disciplined approach to software development. You should be documenting what the system is supposed to achieve, how you tackled that and salient points for its support. This actually relates directly to the software development life-cycle.
- Analysis and requirements gathering
- Design
- Development
- System testing
- UAT
- Deployment
You may have an iterative approach or a waterfall approach but this is basically what you do during a software development project. Analysis and requirements gathering is very important and future developers can see at least exactly what you were supposed to build even if that’s not quite what happened!
It’s worth a word about the agile approach here – I am a big fan of the agile development but being agile does not mean being informal about your approach to a project – in fact many approaches such as SCRUM are really very formal frameworks. To be agile is to be lean – we don’t include things we don’t need but equally we don’t stint on the good stuff. Making lists of things you wish you had done or maybe didn’t have time to do is called ‘management’, it’s not agile. Documenting your system well – that’s very much part of agile, waterfall and basically good software development.
Once you have a set of requirements and the appropriate analysis, it is the job of the developer to think about implementation. The first thing to do is lock away your IDE in a dark room, take your compiler and send it on a short, well earned city break. You shouldn’t be coding now you should be thinking in far more abstract terms.
Design is about more than choosing frameworks – in fact, at the design stage, it is enough to say we’ll use some sort of ORM and probably an MVC framework. Great, what we really need to think about now is the small nugget of fun stuff that comes with every project, so let me think – on this project, we are going to:
- Stick some stuff in a database
- Get some stuff out of the database
- Draw a pretty diagram for management
- Calculate the mass of the Universe based on the new algorithm Dave the PHD has just come up with
- Create a really nice progress bar
Hang on a minute – number four sounds quite interesting. I think we know what we need to concentrate our documentation on in this application.
Obviously, if you are going to get through this project, you are going to have to do some coding at some point but you will note we already have analysis and requirements documentation and a design which describes how we are going to approach this – I’d hope with some nice UML diagrams. We already have a really good basis for any future developers who are going to be supporting your application.
The next thing we are going to do is create some documentation right along side our code – that’s right unit tests! Unit tests are a great way to document as they are essentially a working example of each aspect of the code. A new developer can step through the unit tests and find out exactly what you expected it to do and what you expected the result to be. This is great documentation that we didn’t need to sit down and put a huge amount of effort into.
It shouldn’t be too long now and we’ll get this into test. We have a number of options when it comes to testing:
- Use a dedicated tester who will write test scripts (documentation) and hopefully some automated regression tests
- Get another developer to test it (preferably one that hates you – they always find more bugs) or
- Test it yourself (this falls into the category of pretending to test the system)
Finally, it’s time for UAT (users pretending to test the system) and deployment. Well, we have a pretty good set of documentation now and no comments in the code (well maybe just a few, but it really shouldn’t be littered with them). What else do we need to write? Hopefully very little – a deployment diagram might be nice and maybe some notes for the users.
Job done, we have a really useful set of documentation which will be really helpful to future developers so just one more thing to do before we head off to the pub – file it somewhere obscure so it will never be found again!