More on this book
Community
Kindle Notes & Highlights
Great software today is often preferable to perfect software tomorrow. If you give your users something to play with early, their feedback will often lead you to a better eventual solution
Don't spoil a perfectly good program by overembellishment and over-refinement. Move on, and let your code stand in its own right for a while. It may not be perfect. Don't worry: it could never be perfect.
An investment in knowledge always pays the best interest. • Benjamin Franklin
Don't put all your technical eggs in one basket.
Never underestimate the power of commercialism. Just because a Web search engine lists a hit first doesn't mean that it's the best match; the content provider can pay to get top billing. Just because a bookstore features a book prominently doesn't mean it's a good book, or even popular; they may have been paid to place it there.
A large part of our day is spent communicating, so we need to do it well.
Make what you're saying relevant in time, as well as in content. Sometimes all it takes is the simple question "Is this a good time to talk about...?"
Any chef will tell you that you can slave in the kitchen for hours only to ruin your efforts with poor presentation.
After awl, their are spelling miss steaks that the chequer can knot ketch.
We often find that the documents we produce end up being less important than the process we go through to produce them. If possible, involve your readers with early drafts of your document.
EVERY PIECE OF KNOWLEDGE MUST HAVE A SINGLE, UNAMBIGUOUS, AUTHORITATIVE REPRESENTATION WITHIN A SYSTEM.
It isn't a question of whether you'll remember: it's a question of when you'll forget.
The use of accessor functions ties in with Meyer's Uniform Access principle [Mey97b], which states that "All services offered by a module should be available through a uniform notation, which does not betray whether they are implemented through storage or through computation."
In computing, the term has come to signify a kind of independence or decoupling. Two or more things are orthogonal if changes in one do not affect any of the others.
You get two major benefits if you write orthogonal systems: increased productivity and reduced risk.
When you bring in a toolkit (or even a library from other members of your team), ask yourself whether it imposes changes on your code that shouldn't be there.
Prototyping generates disposable code. Tracer code is lean but complete, and forms part of the skeleton of the final system.
This needn't be a paradox if you practice incremental development, repeating the following steps. Check requirements Analyze risk Design, implement, integrate Validate with the users
What to Say When Asked for an Estimate You say "I'll get back to you."
And, since Mr. Murphy was really an optimist after all, you can't be a great programmer until you become highly skilled at Debugging.
This is the difference between human readable and human understandable.
Unix is famous for being designed around the philosophy of small, sharp tools, each intended to do one thing well.
Progress, far from consisting in change, depends on retentiveness. Those who cannot remember the past are condemned to repeat it. • George Santayana, Life of Reason
However, in the technical arena, you want to concentrate on fixing the problem, not the blame.
The easiest person to deceive is one's self • Edward Bulwer-Lytton, The Disowned
Above all, remember the first rule of debugging: Tip 25 Don't Panic
Don't waste a single neuron on the train of thought that begins "but that can't happen" because quite clearly it can, and has.
Before you start to look at the bug, make sure that you are working on code that compiled cleanly—without warnings.
When trying to solve any problem, you need to gather all the relevant data.
The best way to start fixing a bug is to make it reproducible.
Often, the easiest way to discern what a program is doing—or what it is going to do—is to get a good look at the data it is operating on.
A very simple but particularly useful technique for finding the cause of a problem is simply to explain it to someone else.
Don't Assume It—Prove It
When you come across a surprise bug, beyond merely fixing it, you need to determine why this failure wasn't caught earlier.
Make sure that whatever happened, you'll know if it happens again.
If it took a long time to fix this bug, ask yourself why. Is there anything you can do to make fixing this bug easier the next time around?
Finally, if the bug is the result of someone's wrong assumption, discuss the problem with the whole team: if one person misunderstands, then it's possible many people do.
Write Code That Writes Code
Did that hurt? It shouldn't. Accept it as an axiom of life. Embrace it. Celebrate it. Because perfect software doesn't exist. No one in the brief history of computing has ever written a piece of perfect software. It's unlikely that you'll be the first. And unless you accept this as a fact, you'll end up wasting time and energy chasing an impossible dream.
They don't trust themselves, either.
When everybody actually is out to get you, paranoia is just good thinking. • Woody Allen
Nothing astonishes men so much as common sense and plain dealing. • Ralph Waldo Emerson, Essays
A contract defines your rights and responsibilities, as well as those of the other party. In addition, there is an agreement concerning repercussions if either party fails to abide by the contract.
Design by Contract (DBC, for short).
Preconditions. What must be true in order for the routine to be called; the routine's requirements. A routine should never get called when its preconditions would be violated. It is the caller's responsibility to pass good data (see the box on page 115).
Postconditions. What the routine is guaranteed to do; the state of the world when the routine is done. The fact that the routine has a postcondition implies that it will conclude: infinite loops aren't allowed.
Class invariants. A class ensures that this condition is always true from the perspective of a caller. During internal processing of a routine, the invariant may not hold, but by the time the routine exits and control returns to the caller, the invariant must be true. (Note that a class cannot give u...
This highlight has been truncated due to consecutive passage length restrictions.
If all the routine's preconditions are met by the caller, the routine shall guarantee that all postconditions and invariants will be true when it completes.
Design with Contracts
Remember, if your contract indicates that you'll accept anything and promise the world in return, then you've got a lot of code to write!