Important Programming "Rules of Thumb"
1) K.I.S.S. (Keep It Simple, Stupid)
There are many areas where this rule applies in programming.
Two very important ones are:
a) Subprogram behavior and length: Subprograms should do
precisely ONE conceptual task and no more. The length of a
subprogram should allow it to be easily visually inspected;
generally no more that one page in length. Similarly you should
generally not mix input/output and algorithmic logic in the same
subprogram; it is alway a goal to separate I/O from logic.
b) If a problem is can be decomposed into two or more
independently solvable problems, then solve them independently
and after you have implemented and tested the independent
solutions, then combine them into the larger result. This is
sometimes known as "Gall's Law":
"A complex system that works is invariably found to have evolved
from a simple system that worked. The inverse proposition also
appears to be true: A complex system designed from scratch
never works and cannot be made to work. You have to start over,
beginning with a working simple system."
2) "Rule of Three" (code duplication)
is a code refactoring rule of thumb to decide when a replicated
piece of code should be replaced by a new procedure. It states
that you are allowed to copy and paste the code once, but that
when the same code is replicated three times, it should be
extracted into a new procedure. The rule was introduced by
Martin Fowler in his text "Refactoring" and attributed to Don
Roberts.
Duplication in programming is almost always in indication of
poorly designed code or poor coding habits. Duplication is a bad
practice because it makes code harder to maintain. When the rule
encoded in a replicated piece of code changes, whoever
maintains the code will have to change it in all places correctly.
This process is error-prone and often leads to problems. If the
code exists in only one place, then it can be easily changed there.
This rule is can even be applied to small number of lines of code,
or even single lines of code. For example, if you want to call a
function, and then call it again when it fails, it's OK to have two
call sites; however, if you want to try it five times before giving
up, there should only be one call site inside a loop rather than 5
independent calls.
3) Ninety-ninety rule ( failure to anticipate the hard parts)
The ninety-ninety rule is a humorous aphorism that states:
"The first 90 percent of the code accounts for the first 90 percent
of the development time. The remaining 10 percent of the code
accounts for the other 90 percent of the development time."
—Tom Cargill, Bell Labs
That the total development time sums to 180% is a wry allusion
to the notorious tendency of software development projects to
significantly overrun their original schedules. It expresses both
the rough allocation of time to easy and hard portions of a
programming project and the cause of the lateness of many
projects (that is, failure to anticipate the hard parts). In other
words, it takes both more time and more coding than expected to
make a project work.
4) Efficiency vs. code clarity (chasing false efficiency)
Never sacrifice clarity for some perceived efficiency. One of the
biggest mistakes that new programmers make is tweaking code
to remove a couple of textual lines of high level code and replace
it with a much more complex single line of code. This is
commonly called "bit twiddling". Always remember that most
compilers optimize code. Further, there is a corollary to the 90-90
rule known as the "Pareto Principle":
In computer science, the Pareto principle can be applied to
resource optimization by observing that 80% of the resources are
typically used by 20% of the operations. In software engineering,
it is often a better approximation that 90% of the execution time
of a computer program is spent executing 10% of the code
(known as the 90/10 law in this context).
Given this knowledge, most "bit twiddling" will have no
perceivable impact on the runtime of most programs as most of
them will likely be in the 90% of code that has little impact on the
run-time of the program. The real efficiency gains come from
changing the order of complexity of the algorithm, such as
changing from O(N^2) to O(NlogN) complexity. Keep your code
clearly and cleanly written and it will usually be reasonably
efficient. Occasionally, after the program is written and tested, it
might prove to be slower than the problem specification calls for.
On the these few occasions, and only after you have first
optimized the complexity of the algorithm, then instrument or
profile the code and find the 10% or less of the code that
PROVABLY causes slow runtime and then optimize that small code
segment.
Comments on this topic from well respected computer scientists
and software engineers:
"More computing sins are committed in the name of efficiency
(without necessarily achieving it) than for any other single reason
— including blind stupidity." — W.A. Wulf
"We should forget about small efficiencies, say about 97% of the
time: premature optimization is the root of all evil. Yet we should
not pass up our opportunities in that critical 3%. A good
programmer will not be lulled into complacency by such
reasoning, he will be wise to look carefully at the critical code; but
only after that code has been identified" — Donald Knuth
"Bottlenecks occur in surprising places, so don't try to second
guess and put in a speed hack until you have proven that's where
the bottleneck is." — Rob Pike
"The First Rule of Program Optimization: Don't do it. The Second
Rule of Program Optimization (for experts only!): Don't do it yet."
— Michael A. Jackson
5) Naming of things (subprograms and variables)
In computer programming, a naming convention is a set of rules
for choosing the character sequence to be used for identifiers
which denote variables, types and functions etc. in source code
and documentation. Reasons for using a naming convention (as
opposed to allowing programmers to choose any character
sequence) include the following:
1) to reduce the effort needed to read and understand source
code which supports its maintainability
2) to enhance source code appearance (for example, by
disallowing overly long names or unclear abbreviations)
There are lots of naming conventions that are strongly argued for
or against by various engineers; in reality these are mostly
religious arguments. However, whatever you do, you should
follow some consistent naming style. There is one thing that is
common to most all naming conventions, and that is that the
name should be descriptive of the contents, or a name that is in
common programming practice for the language (such as using i,
j, k for loop and array indexes).
Commonly, subprograms should have verb/verb phrase names as
a subprogram should specify one specific task (see KISS rule)
which should be an activity description. Variables should have
noun or adjective names as variables represent things or
attributes of something. When choosing a name, if you have
difficulty in coming up with a descriptive name this is an
indication that your code needs further refactoring to improve the
clarity of the design and the purpose of subprograms and
variables.