There are some great tools out there for capturing documentation, certainly compared to just a couple of years ago. Now it seems like every git repository greets me with a readme, and every project comes with a wiki on how to use it. If you’re building a library or similar, and publishing it to the general public, these are really useful things – after all, this is your most maintainable way of answering frequent questions and communicating to newcomers. For open source libraries, having decent documentation can be a key factor in whether a library gains adoption or not, so providing the right level is critical. For an open source project, things like Intellisense comments, giving help to the developer at a low level, combined with a getting started guide, and maybe a full reference, can make all the difference.
A good suite of well-written tests, or sample projects, are a really great way to capture the usage and behavior of a library. The beauty of these is that they are runnable – while a wiki will rot and go out of date, tests or samples should break if the library changes significantly, and they are much more likely to stay valid. There is a maintenance cost that comes with this of course, but that maintenance cost is reduced by things like compile-time checking and automated tests. There should be a matching cost for the wiki form, but all too often the wiki simply isn’t maintained at the same cadence as the software it is documenting.
The best form of documentation for me though is none at all – because it isn’t needed. If we can write software so clearly that its intent and usage are obvious, then we have no need for additional description. Software languages that work at a much higher level can be very expressive if used well; by naming things in a way that makes sense to people, and using appropriate levels of abstraction, it should be the goal in every single module of software for the source code to be “self-documenting” in its clarity and simplicity. There is a general stereotype of software developers that communication is not among their main strengths, but this doesn’t have to be true. Learning to communicate – both verbally and in writing – is arguably the most important skill a modern software developer can work on. At its core, software development is about language and translation of business requirements to machine commands. The often overlooked element is that the machine commands will need to be understood by other people, and so the writer of machine commands needs to write not just for a compiler, but for a human audience.
Writing documentation around something complex sometimes strikes me as unprofessional, because it represents an acceptance of that complexity. If something is complex, the right thing to do is to attempt to address that complexity at source. Writing documentation gives the complex solution more permanence, and makes it less likely it will be tamed into a simpler form. One of the challenges in reducing complexity is that its creators are often proud of the effort that went into its creation, and if they have then gone to the trouble of documenting it, then there is even more effort that will be written off if the complexity is removed. As professionals, we need to get over this once and for all: we should take pride in the value we deliver, and in doing so in the lowest cost way, both in the long and short term. Creating a complex solution is not something to be proud of; it has high costs attached and these can have a crippling effect if not rectified.
If you find yourself documenting something that is complicated, it means you will need to first gain a deep enough understanding of it. This is a great opportunity – since you now have that deep understanding, you could use that to remove the complication for the next person, rather than leave it in place. As software engineers, there is plenty of complexity around us, some of it necessary and a lot of it not. We may work in a complex business, with an intricate domain; we work with complex tools and languages, with their syntax and paradigms. As humans, we have finite capacity to hold only so much information in our heads at any time. If we can reduce the noise even slightly, we gain a large advantage. If we try to manage complexity by writing documentation, we are increasing the amount of information that needs to be held when looking at this area, and even if that additional information makes other things easier to understand, it still takes valuable space in our thinking.
If you’re writing a public facing library, give yourself the best chance of adoption by taking documentation seriously as part of your “user interface” to developers. However, whether public or private, we should remember at all times that the front line of documentation is the solution itself. A badly designed or complex solution with the best documentation in the world is going to cause problems, so why not do ourselves a favor by improving the design, reducing complexity to a minimum, and reducing the cognitive load we create for ourselves.