More on this book
Community
Kindle Notes & Highlights
Nothing is more dangerous than an idea if it's the only one you have.
By the time many critical decisions have been made, the target becomes so small that if it moves, or the wind changes direction, or a butterfly in Tokyo flaps its wings, you miss.[4] And you may miss by a huge amount.
Instead of carving decisions in stone, think of them more as being written in the sand at the beach. A big wave can come along and wipe them out at any time.
The cat's alive in one universe, dead in another. Only when you open the box do you know which universe you are in.
Pragmatic Programmers, however, tend to prefer using tracer bullets.
The tracer code approach addresses a different problem. You need to know how the application as a whole hangs together.
Over time, you add to this framework with new functionality, completing stubbed routines. But the framework stays intact, and you know the system will continue to behave the way it did when your first tracer code was completed.
The distinction is important enough to warrant repeating. Prototyping generates disposable code. Tracer code is lean but complete, and forms part of the skeleton of the final system. Think of prototyping as the reconnaissance and intelligence gathering that takes place before a single tracer bullet is fired.
The limits of language are the limits of one's world.
So the first question you have to ask yourself when someone asks you for an estimate is the context in which your answer will be taken. Do they need high accuracy, or are they looking for a ballpark figure?
What's the value of π? If you're wondering how much edging to buy to put around a circular flower bed, then "3" is probably good enough.[10] If you're in school, then maybe "22/7" is a good approximation. If you're in NASA, then maybe 12 decimal places will do.
When an estimate turns out wrong, don't just shrug and walk away. Find out why it differed from your guess. Maybe you chose some parameters that didn't match the reality of the problem. Maybe your model was wrong. Whatever the reason, take some time to uncover what happened. If you do, your next estimate will be better.
You almost always get better results if you slow the process down and spend some time going through the steps we describe in this section. Estimates given at the coffee machine will (like the coffee) come back to haunt you.
Start keeping a log of your estimates. For each, track how accurate you turned out to be. If your error was greater than 50%, try to find out where your estimate went wrong.
Unix is famous for being designed around the philosophy of small, sharp tools, each intended to do one thing well. This philosophy is enabled by using a common underlying format—the line-oriented, plain text file.
A benefit of GUIs is WYSIWYG—what you see is what you get. The disadvantage is WYSIAYG—what you see is all you get.
Clearly the list could go on. The shell commands may be obscure or terse, but they are powerful and concise. And, because shell commands can be combined into script files (or command files under Windows systems), you can build sequences of commands to automate things you do often.
If you haven't spent much time exploring the capabilities of the command shell on the systems you use, this might appear daunting.
One Editor We think it is better to know one editor very well, and use it for all editing tasks: code, documentation, memos, system administration, and so on.
Always Use Source Code Control Always. Even if you are a single-person team on a one-week project. Even if it's a "throw-away" prototype. Even if the stuff you're working on isn't source code.
It is a painful thing To look at your own trouble and know That you yourself and no one else has made it
Debugging itself is a sensitive, emotional subject for many developers. Instead of attacking it as a puzzle to be solved, you may encounter denial, finger pointing, lame excuses, or just plain apathy.
The easiest person to deceive is one's self
Once you think you know what is going on, it's time to find out what the program thinks is going on.
The best way to start fixing a bug is to make it reproducible. After all, if you can't reproduce it, how will you know if it is ever fixed?
Don't Assume It—Prove It
Pragmatic Programmers manipulate text the same way woodworkers shape wood.
When everybody actually is out to get you, paranoia is just good thinking.
Nothing astonishes men so much as common sense and plain dealing.
Dealing with computer systems is hard. Dealing with people is even harder. But as a species, we've had longer to figure out issues of human interactions. Some of the solutions we've come up with during the last few millennia can be applied to writing software as well. One of the best solutions for ensuring plain dealing is the contract.
All errors give you information. You could convince yourself that the error can't happen, and choose to ignore it. Instead, Pragmatic Programmers tell themselves that if there is an error, something very, very bad has happened.
One of the problems with exceptions is knowing when to use them. We believe that exceptions should rarely be used as part of a program's normal flow; exceptions should be reserved for unexpected events. Assume that an uncaught exception will terminate your program and ask yourself, "Will this code still run if I remove all the exception handlers?" If the answer is "no," then maybe exceptions are being used in nonexceptional circumstances.
"I brought you into this world," my father would say, "and I can take you out. It don't make no difference to me. I'll just make another one like you."
A key concept in creating flexible code is the separation of a data model from a view, or presentation, of that model. We'll decouple models from views in It's Just a View.
Change and decay in all around I see ...
Keep track of the things that need to be refactored. If you can't refactor something immediately, make sure that it gets placed on the schedule.
Refactoring started out in the Smalltalk community, and, along with other trends (such as design patterns), has started to gain a wider audience. But as a topic it is still fairly new; there isn't much published on it.
We'll talk more about testing at this level in Code That's Easy to Test, page 189, and larger-scale testing in Ruthless Testing, page 237, but Mr. Fowler's point of maintaining good
The unit tests for a module shouldn't be shoved in some far-away corner of the source tree. They need to be conveniently located. For small projects, you can embed the unit test for a module in the module itself. For larger projects, we suggest moving each test into a subdirectory. Either way, remember that if it isn't easy to find, it won't be used.
All software you write will be tested—if not by you and your team, then by the eventual users—so you might as well plan on testing it thoroughly. A little forethought can go a long way toward minimizing maintenance costs and help-desk calls.
Don't Use Wizard Code You Don't Understand
Perfection is achieved, not when there is nothing left to add, but when there is nothing left to take away....
Work with a User to Think Like a User
Workflow can be captured with UML activity diagrams, and conceptual-level class diagrams can sometimes be useful for modeling the business at hand.
Don't Think Outside the Box—Find the Box
Is there an easier way? Are you trying to solve the right problem, or have you been distracted by a peripheral technicality? Why is this thing a problem? What is it that's making it so hard to solve? Does it have to be done this way? Does it have to be done at all?
[photographs] with circles and arrows and a paragraph on the back of each one explaining what each one was, to be used as evidence against us...
Quality is a team issue. The most diligent developer placed on a team that just doesn't care will find it difficult to maintain the enthusiasm needed to fix niggling problems.
This duplication leads to wasted effort, and can result in a maintenance nightmare. Clearly good communication can help here, but sometimes something extra is needed.