It's well understood that software code is a document written primarily for two different types of audience:
- The platforms that will execute the code, and
- The developers who will maintain the code.
To support these audiences, code is written simultaneously for execution and for maintainability. Execution is always the primary concern, as execution is why we have software. Maintainers will therefore want to develop a coherent model of how the code under maintenance will execute, what its assumptions are about its environment, and what promises the code makes to its clients. Well-written code makes developing this model as easy as possible (Elegance Is Teaching). Which means, to write code well, one has to know something about the audience that will read it. And this will depend on the type of project you are working on.
The easiest type of code to write is of the throwaway type. That is, code written to satisfy some short-term need, then disposed of. Examples include shell-scripts that you write on the command line, and experimental code written to test or develop your understanding of a platform. This is the easiest type of code to write, for two reasons:
- You are not concerned about anyone else reading this code.
- The entire model of the code's behavior lives in your working memory. (If it does not, then you might consider that this isn't throwaway code.)
As such, for this type of code (and, in my opinion, only for this type of code), you do not need to worry about making the code reflect your intentions as you are writing it.
Closed-Source Personal Projects
Then there is the project which is longer-lived, and will likely require maintenance across its life-time, but for which the only audience that matters is you, yourself. Other things being equal, this ought to be the second easiest type of code to write: it is much easier to know the audience, to know what their skills are, and what ideas they already know or can easily pick up, when you are your own audience.
Still, it's a fair bet that you'll forget parts of how it works, and if you ever need to maintain something you wrote yourself, there will certainly be times when you need to remind yourself of the design. You will want to have either explicit design documentation, or, preferably, to have your design be self-documenting.
Then there is the case where you are making a contribution to a code base controlled by someone else. In this case, it's really up to the project maintainers to provide guidance on the mechanisms you should use to make your code maintainable. But practices like having good names for your symbols and creating well-factored code will be appreciated in any project.
Finally, you have the case where you are an active maintainer, in some capacity, of a project. In this case, your decisions will be a key factor in determining your intended audience, so your audience should be considered as you make decisions.
It's probably sufficiently clear that considering your audience will affect the nature of your project's documentation. But audience considerations can also have significant effect on your project's technical decisions, as well. For example, considering your audience may guide you towards more or less advanced techniques when making architectural decisions: Doug Simon (at http://www.se-radio.net/2009/09/episode-144-the-maxine-research-virtual-machine-with-doug-simon/, around the 40 minute mark) noted that basing the Maxine JVM on continuations made it less accessible to some of his desired audience than a more mainstream stack-oriented architecture would be. On the other hand, Bryan O'Sullivan (http://www.infoq.com/presentations/Running-a-Startup-on-Haskell) argued that using Haskell allowed his start-up to attract better developers. One wanted to expand the audience, by reducing reliance on less well-understood techniques, while the other wanted to reduce the developer audience, by increasing reliance on a less well-understood language. In either case, the nature of the potential audience informed a technical decision.
If you will be working closely with the same, small group of people on a project for a long time (for example, for a large-scale work project), then you may not need much explicit design documentation: informal communication may suffice to spread design knowledge through the team. If you have a high degree of turnover on your project, then you will probably want to invest more in introductory documentation, and your code base should not require a high level of refinement to productively use.
There are a plethora of ways that understanding the audience for your software should influence its technical design, I only scratch the surface here. As in any other form of communication, understanding your listener is critical to success. Your code can communicate to multiple audiences. To produce beautiful code, you must write with those audiences in mind.