assert(timeInWordProcessor > timeInCodeEditor)
If you're like me, you didn't get into software/web development because you enjoy writing prose. If you wanted to do that, you would have gone into journalism or been an English major. No, like me, you like building things. Really cool things that are useful. And when you're done building those things, you can look at it and not only feel the pride that comes from a job well done, but you also glean enjoyment from others that use what you've built.
Writing code represents only a small fraction of the time it takes to build great software
Like many things that we have limited information about, we tend to project idealized models onto what we don't know to fill in the gaps. This is basic survival: if we truly were aware and attended to everything we didn't actually know, we'd probably become non-functional because fillingin the gaps requires time and effort. And what we don't know is larger than what we do know and can actually remember.
I was reminded of this in a recent interview where I was asked to whiteboard some code. I spent maybe 20 minutes discussing how the system would work, asking about constraints on input, desired output, user stories, corner cases, and scaling. I spent maybe 10 minutes actually writing the code for the problem. That's a 2:1.
Unless you are building something fairly trivial, the majority of your time should be spent specifying and documenting. And to document, you're not going to be writing code: you're going to be talking through examples and writing things down.
You write things down for your own benefit. That extra brain power can then be put to better use making decisions about how to implement features rather than on remembering what needs to be implemented at some future time. Documenting quickly and clearly also helps you to avoid decision fatigue. Yes, that's a thing.
For us freelancers, this becomes even more important because the documentation not only documents the what of the project but the how we'll move through the project with our clients. Our memories are fluid, so we need to document to protect both parties in case of a fluid memory situation. Beyond just our memories, communication itself is a form of compression, and it is lossy on both the encode and the decode side:
There are a bunch of concepts in your head that then your brain has to try to compress into this incredibly low data rate called speech or typing. That’s what language is—your brain has executed a compression algorithm on thought, on concept transfer. And then it’s got to listen as well, and decompress what’s coming at it. And this is very lossy as well. So, then when you’re doing the decompression on those, trying to understand, you’re simultaneously trying to model the other person’s mind state to understand where they’re coming from, to recombine in your head what concepts they have in their head that they’re trying to communicate to you. — Elon Musk
So we're documenting to seek clarity, we're documenting to create a contract, and we're documenting to build the client-contractor relationship.
So what should correct documentation include?
Good question! The first requirement is the documentation format itself. This varies from project to project, but no project is too small to be documented. In the smallest case, this can be an email thread where the specifications are laid out in detail. In larger cases, it needs to be a version controlled document where you can see edits and changes and (most importantly for the contractor) approvals of past and future work. The worst thing that can happen to both parties during development is a misalignment of goals. This usually only happens when the documentation is poor.
So, what to include?
Problem Description
All software is typically solving a problem: system integration, mobile access, migrating code, developing a website — something is new. There's a reason to do this project and the Problem Description needs to outline what the problem is and the goal(s) of the project. In larger projects, stating this explicitly can help protect against inevitable feature creep and keep the project focused. When you consider adding a new feature, ask if it supports the original goals of the project. If yes, think it through and add it. If no, consider creating a new project and discussing with stakeholders.
History
For older projects, you'll want to include a history of the previous projects arcs through time. Was this originally a relational database that has overgrown its scaling and needs to migrate to a non-relational database? Describing the history of the project can remind you of the context and the motivation for the new efforts. This can be short. But in new projects without a relevant history, I would recommend adding a Research section where you can discuss other solutions to this problem, what you might leverage, and what has been done before in this space.
Solution
The solution portion of the documentation is where the rubber meets the road. This is where you document the what and the how in your documentation: discussing specific technologies, their operation, block and state diagrams, and individual feature descriptions. In a contract situation, you'll want to break the project into individual milestones and check-offs where the client can sign-off on the individual features with a date as they are completed. For example, in a simple one page deployed web-app with an authorized login you'd want a table that minimally looks something like this:
Feature | Description | Cost | Complete or Due Date | Version | Signature |
---|---|---|---|---|---|
Login Page | front-end design and backend auth | $500 | |||
Landing Page | front-end design and backend auth | $500 |
You also want to tie in deliverables to each milestone. If you're just doing the back-end code and the client is supplying you the front-end design, that needs to be specified in the docs. You can't be done if you don't have the deliverables. As a freelancer, you also need to document how compliant the client is and documentation will help you track that. Working in teams is a relationship.
Timelines
Projects have timelines. For smaller projects, you can just insert due dates into the Solution table above. But for larger projects, you're going to want to scope out the project timeline and break it into hours. On large projects, this will be done with something like JIRA or the like, but I encourage you, as a developer, to drill into these projects and check the hours and timelines. The point here is that if feature creep, late deliverables, or surprise issues emerge, they need to be documented and the schedule needs to slip or advance as needed.
Future Work
Put a future work or backlog section into your documentation where you can put all of the things you think of that you just won't get to right now. This can be very free-form writing, but will help you and the client sort issues as they arise. Software development is iterative and even the most simple projects need a section like this.
Cancelation
It's not natural to think about project cancelation at the beginning of a project. But you need to. Put a cancelation clause in your contract or documentation so everyone is on the same page in case you or your client need to cancel. Shit happens. Their funding could dry up. You could break your hand. You don't want to have signed up for a very large project, not broken it into smaller milestones, and not have gotten paid what you are due because the client had to change their mind on the project.
This doesn't matter as much for open-ended hourly contracts, but there is still an impact. If you are working on something and intend to use that work for a portfolio piece and it is canceled before you're done, you're looking at time wasted. If you do want to use this piece in a portfolio, I'd put a cancelation clause in the contract so if it is canceled you can at least continue or close it out so you can use it.
Conclusion
You don't need to formally document all of these items in every project and formalize all of them, but you certainly should think about them and document the ones you think will matter. Every situation and client is different, but I hope now you see that time spent on documentation is time well spent.
The time you spend here will pay dividends both on making your code better with fewer errors and re-writes, but your communication skills will improve as well. Documentation helps build the business relationships that are necessary to keep your business healthy.