| Paul Haahr / Essays / Java Style / Basic Principles |
|
|
Basic PrinciplesThese principles are, I believe, independent of any specific programming language and motivate the specific suggestions below. When a tension exists between a principle here and one of the other style rules, the principle should win out. Readability is the most important attribute of styleThis is probably obvious. A style, as a restriction on how one writes programs, does not make it much easier to write programs that are never read. Of course, a good style should make it easier to maintain or extend a program, but that's mostly because of the benefits in reading and understanding the program. (A consistent style does make programs easier to write by restricting the choices available for any given construct.) When writing in a natural language, it is necessary to consider one's readers. This applies to programs as well, there are three readers I consider when writing code:
Other possible audience members (managers, lawyers) for my programs do not receive much of my attention when coding. Choose good namesThe most direct way of explaining what a program is about is by selecting good names for variables, types, procedures, etc. Where language syntax and keywords are punctuation and external libraries provide some vocabulary, the names you chose are the ``content words'' of your programs and provide the means for making the program clear. My obsession with names can lead to paralysis as a programmer. If I'm trying to write some new code, and I can't figure out a good name for a class or method, I'll often be stuck until I have something. Many times, I find that the reason I can't pick a good name is that I don't understand enough about what I'm trying to say; with understanding comes good names, and vice versa. A thesaurus sometimes helps, but I often wish I had domain-specific thesauri for the areas I work on. (See the section on naming for my thoughts on what makes a good name.) Don't fight the language | |
|
Not all programming languages are right for all programs, and not all techniques can easily be expressed in all languages. When working in Java, try to use approaches that meet the least resistance from the language. This rule has both affirmative (``do it this way'') and negative (``don't do it that way'') aspects. For example, Java is a class-based, object-oriented language. That makes classes the default structuring tool, and a good Java program will take advantage of them. A design which uses lots of public fields, empty constructors, and static methods spread out over bunches of classes not related to the objects they manipulate feels wrong for Java. As a negative example, I've spent a lot of my career working in Lisp-derived languages, where recursion is often the most obvious and efficient form of control flow. This usually isn't true in Java, because nested local methods are awkward to use and restrictions in the language often prevent efficient implementation of recursion. So, while my natural instinct is to write recursive functions, if there really isn't a good reason for the recursion -- for example, taking advantage of the implicit stack -- I don't do it. Be consistent | |
|
Whatever individual style decisions you make, stick with them. Consistency means that a reader can ignore many details of typography and naming, because they're exactly as would be expected, and concentrate on the substance of a program. Purposeless variations in styles only serve to distract. Of course, which variations are purposeless and which consistencies are foolish is a subjective matter. Taste and discretion are often required. Comment appropriatelyComments (and other forms of in-program documentation) are essential tools for a reader trying to understand how to use a program, how it works, and how it is structured. And few people disagree -- it's hard to find anyone who doesn't advocate commenting code, even if they don't always practice what they preach. Treating comments as a panacea is, of course, a mistake. A badly written program can be documented well, and it's still a bad program. Commenting is one tool among many for making programs clearer. But, the number of programs which suffer from overdocumentation is probably not too large. More problematic is documenting the wrong things, so that documentation serves to confuse or distract a reader; the worst examples are comments that are incorrect or out-of-date and disagree with the code they refer to. What to write comments about and how to write them are what people do reasonably disagree on. Broadly speaking, there are two forms of comments -- those aimed at people trying to understand the innards of a system and those trying to understand its interface. My opinion is that every comment should answer some question intelligent readers of the program, with those goals in mind, would ask themselves, such as:
When writing a comment, think about the questions you're answering. If a question would never be asked by a reader, then there's no purpose in answering it. A comment which doesn't answer any questions is probably superfluous. Don't let optimization interfere with readabilityThe best-known truism about programming is ``Premature optimization is the root of all evil.'' It's also probably the most often violated. I've found that a good barrier to prematurely optimizing code is forcing myself to document anything that's subtle or uses optimization techniques beyond what might be expected for a given situation, both in terms of documenting the implementation and giving an explanation of why I bothered to optimize -- usually my reasoning is that a particular piece of code will be invoked very frequently or deal with large data sets. Often, trying to back this up with quantitative data in the comments will lead me to do more analysis of the problem, which at least gives better insight into the problem. (One of the hazards of writing compilers, especially if you're writing a compiler for a language you use, is that it becomes natural to think about the code your compiler would generate for code as you type it. My reaction to this situation is a silly one: I edit myself while coding to ensure that my programs are easy for our compiler to optimize. For example, I often end up eliminating common subexpressions by hand, even if the compiler could do it for me. I'm a sinner and I know it.) Be a chameleonWhen you're dropped into a piece of existing code, don't rewrite it all in your own style. This should be obvious, but many people (myself included) find too many reasons for exceptions. Aside from wasting time and confusing source control systems, you will annoy everyone else working in the same code base. |