---
created_at: '2016-08-01T15:30:43.000Z'
title: Tips from the Pragmatic Programmer (2000)
url: https://pragprog.com/the-pragmatic-programmer/extracts/tips
author: gasull
points: 165
story_text: 
comment_text: 
num_comments: 72
story_id: 
story_title: 
story_url: 
parent_id: 
created_at_i: 1470065443
_tags:
- story
- author_gasull
- story_12203140
objectID: '12203140'

---
[Source](https://pragprog.com/the-pragmatic-programmer/extracts/tips "Permalink to 
  List of Tips |  The Pragmatic Bookshelf 
")

# 
  List of Tips |  The Pragmatic Bookshelf 


__

* [Books & Screencasts][1]
* [Forums][2]
* [Support][3]
* [Video Courses][4]
* [Become an Author][5]
* [Log in][6]
* __

[Skip to main content][7]

[

][8]

* [Books & Screencasts][1]
* [Forums][2]
* [Support][3]
* [Video Courses][4]
* [Become an Author][5]
* * [ _ _ Cart  (0)  ][9]
* [Login][6]

[ _ _ Cart  (0)  ][9]

## By developers for developers.

**small** **medium** **large** **xlarge**

×

# List of Tips

![Cover Image For The Pragmatic Programmer…][10]

Extracted From _The Pragmatic Programmer_  
by Andrew Hunt and David Thomas. Copyright 2000, Addison Wesley.

We’ve been busy since we first wrote _The Pragmatic Programmer_ back in 1999. Have you seen all of our [recent books that we’ve written or published][11]?

From Agility to Ruby on Rails, project management to debugging your career, we’ve got the titles to help keep you on top of your game.

—Andy and Dave

* [Browse all titles][11]
* [Browse by category][12]

#### Pragmatic Software Development Tips

**Care About Your Craft**  
Why spend your life developing software unless you care about doing it well?

**Provide Options, Don’t Make Lame Excuses**  
Instead of excuses, provide options. Don’t say it can’t be done; explain what can be done.

**Be a Catalyst for Change**  
You can’t force change on people. Instead, show them how the future might be and help them participate in creating it.

**Make Quality a Requirements Issue**  
Involve your users in determining the project’s real quality requirements.

**Critically Analyze What You Read and Hear**  
Don’t be swayed by vendors, media hype, or dogma. Analyze information in terms of you and your project.

**DRY—Don’t Repeat Yourself**  
Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.

**Eliminate Effects Between Unrelated Things**  
Design components that are self-contained, independent, and have a single, well-defined purpose.

**Use Tracer Bullets to Find the Target**  
Tracer bullets let you home in on your target by trying things and seeing how close they land.

**Program Close to the Problem Domain**  
Design and code in your user’s language.

**Iterate the Schedule with the Code**  
Use experience you gain as you implement to refine the project time scales.

**Use the Power of Command Shells**  
Use the shell when graphical user interfaces don’t cut it.

**Always Use Source Code Control**  
Source code control is a time machine for your work—you can go back.

**Don’t Panic When Debugging**  
Take a deep breath and THINK! about what could be causing the bug.

**Don’t Assume It—Prove It**  
Prove your assumptions in the actual environment—with real data and boundary conditions.

**Write Code That Writes Code**  
Code generators increase your productivity and help avoid duplication.

**Design with Contracts**  
Use contracts to document and verify that code does no more and no less than it claims to do.

**Use Assertions to Prevent the Impossible**  
Assertions validate your assumptions. Use them to protect your code from an uncertain world.

**Finish What You Start**  
Where possible, the routine or object that allocates a resource should be responsible for deallocating it.

**Configure, Don’t Integrate**  
Implement technology choices for an application as configuration options, not through integration or engineering.

**Analyze Workflow to Improve Concurrency**  
Exploit concurrency in your user’s workflow.

**Always Design for Concurrency**  
Allow for concurrency, and you’ll design cleaner interfaces with fewer assumptions.

**Use Blackboards to Coordinate Workflow**  
Use blackboards to coordinate disparate facts and agents, while maintaining independence and isolation among participants.

**Estimate the Order of Your Algorithms**  
Get a feel for how long things are likely to take before you write code.

**Refactor Early, Refactor Often**  
Just as you might weed and rearrange a garden, rewrite, rework, and re-architect code when it needs it. Fix the root of the problem.

**Test Your Software, or Your Users Will**  
Test ruthlessly. Don’t make your users find bugs for you.

**Don’t Gather Requirements—Dig for Them**  
Requirements rarely lie on the surface. They’re buried deep beneath layers of assumptions, misconceptions, and politics.

**Abstractions Live Longer than Details**  
Invest in the abstraction, not the implementation. Abstractions can survive the barrage of changes from different implementations and new technologies.

**Don’t Think Outside the Box—Find the Box**  
When faced with an impossible problem, identify the real constraints. Ask yourself: "Does it have to be done this way? Does it have to be done at all?"

**Some Things Are Better Done than Described**  
Don’t fall into the specification spiral—at some point you need to start coding.

**Costly Tools Don’t Produce Better Designs**  
Beware of vendor hype, industry dogma, and the aura of the price tag. Judge tools on their merits.

**Don’t Use Manual Procedures**  
A shell script or batch file will execute the same instructions, in the same order, time after time.

**Coding Ain’t Done ‘Til All the Tests Run**  
‘Nuff said.

**Test State Coverage, Not Code Coverage**  
Identify and test significant program states. Just testing lines of code isn’t enough.

**English is Just a Programming Language**  
Write documents as you would write code: honor the DRY principle, use metadata, MVC, automatic generation, and so on.

**Gently Exceed Your Users’ Expectations**  
Come to understand your users’ expectations, then deliver just that little bit more.

**Think! About Your Work**  
Turn off the autopilot and take control. Constantly critique and appraise your work.

**Don’t Live with Broken Windows**  
Fix bad designs, wrong decisions, and poor code when you see them.

**Remember the Big Picture**  
Don’t get so engrossed in the details that you forget to check what’s happening around you.

**Invest Regularly in Your Knowledge Portfolio**  
Make learning a habit.

**It’s Both What You Say and the Way You Say It**  
There’s no point in having great ideas if you don’t communicate them effectively.

**Make It Easy to Reuse**  
If it’s easy to reuse, people will. Create an environment that supports reuse.

**There Are No Final Decisions**  
No decision is cast in stone. Instead, consider each as being written in the sand at the beach, and plan for change.

**Prototype to Learn**  
Prototyping is a learning experience. Its value lies not in the code you produce, but in the lessons you learn.

**Estimate to Avoid Surprises**  
Estimate before you start. You’ll spot potential problems up front.

**Keep Knowledge in Plain Text**  
Plain text won’t become obsolete. It helps leverage your work and simplifies debugging and testing.

**Use a Single Editor Well**  
The editor should be an extension of your hand; make sure your editor is configurable, extensible, and programmable.

**Fix the Problem, Not the Blame**  
It doesn’t really matter whether the bug is your fault or someone else’s—it is still your problem, and it still needs to be fixed.

**"select" Isn’t Broken**  
It is rare to find a bug in the OS or the compiler, or even a third-party product or library. The bug is most likely in the application.

**Learn a Text Manipulation Language**  
You spend a large part of each day working with text. Why not have the computer do some of it for you?

**You Can’t Write Perfect Software**  
Software can’t be perfect. Protect your code and users from the inevitable errors.

**Crash Early**  
A dead program normally does a lot less damage than a crippled one.

**Use Exceptions for Exceptional Problems**  
Exceptions can suffer from all the readability and maintainability problems of classic spaghetti code. Reserve exceptions for exceptional things.

**Minimize Coupling Between Modules**  
Avoid coupling by writing "shy" code and applying the Law of Demeter.

**Put Abstractions in Code, Details in Metadata**  
Program for the general case, and put the specifics outside the compiled code base.

**Design Using Services**  
Design in terms of services—independent, concurrent objects behind well-defined, consistent interfaces.

**Separate Views from Models**  
Gain flexibility at low cost by designing your application in terms of models and views.

**Don’t Program by Coincidence**  
Rely only on reliable things. Beware of accidental complexity, and don’t confuse a happy coincidence with a purposeful plan.

**Test Your Estimates**  
Mathematical analysis of algorithms doesn’t tell you everything. Try timing your code in its target environment.

**Design to Test**  
Start thinking about testing before you write a line of code.

**Don’t Use Wizard Code You Don’t Understand**  
Wizards can generate reams of code. Make sure you understand all of it before you incorporate it into your project.

**Work with a User to Think Like a User**  
It’s the best way to gain insight into how the system will really be used.

**Use a Project Glossary**  
Create and maintain a single source of all the specific terms and vocabulary for a project.

**Start When You’re Ready**  
You’ve been building experience all your life. Don’t ignore niggling doubts.

**Don’t Be a Slave to Formal Methods**  
Don’t blindly adopt any technique without putting it into the context of your development practices and capabilities.

**Organize Teams Around Functionality**  
Don’t separate designers from coders, testers from data modelers. Build teams the way you build code.

**Test Early. Test Often. Test Automatically.**  
Tests that run with every build are much more effective than test plans that sit on a shelf.

**Use Saboteurs to Test Your Testing**  
Introduce bugs on purpose in a separate copy of the source to verify that testing will catch them.

**Find Bugs Once**  
Once a human tester finds a bug, it should be the last time a human tester finds that bug. Automatic tests should check for it from then on.

**Build Documentation In, Don’t Bolt It On**  
Documentation created separately from code is less likely to be correct and up to date.

**Sign Your Work**  
Craftsmen of an earlier age were proud to sign their work. You should be, too.

| ----- |
|  [Buy eBook][13] |  [Browse Titles][11] |  [Discuss!][14] | 

# Added to your cart

Continue Shopping [View Your Cart][9]

Yes

No

## Customer Service

* [Contact][15]
* [Privacy][16]
* [Legal][17]
* [Become an Author][5]
* [Security][18]

## Menu

* [Categories][19]
* [Screencasts][20]
* [Video Courses][4]
* [Magazine][21]
* [Articles][22]
* [Forums][23]
* [Help Wanted][24]
* [Promotions][25]
* [About][26]
* [Login][6]
* __
* __
* [ __ ][27]
* [ __ ][28]
* [ __ ][29]

© 1999–2018 The Pragmatic Programmers, LLC 

[1]: https://pragprog.com/categories/all
[2]: https://forums.pragprog.com/
[3]: https://pragprog.com/frequently-asked-questions/
[4]: https://pragmaticstudio.com
[5]: http://write-for-us.pragprog.com/
[6]: https://pragprog.com/login
[7]: https://pragprog.com#main
[8]: https://pragprog.com/
[9]: https://pragprog.com/cart "Display your cart and proceed to checkout"
[10]: https://imagery.pragprog.com/products/59/tpp_largecover.jpg?1339433898
[11]: https://pragprog.com/titles
[12]: https://pragprog.com/categories
[13]: https://pragprog.com/titles/tpp
[14]: http://forums.pragprog.com/forums/tpp
[15]: https://pragprog.com/contact
[16]: https://pragprog.com/privacy
[17]: https://pragprog.com/terms-of-use
[18]: https://pragprog.com/security
[19]: https://pragprog.com/titles/category/all
[20]: https://pragprog.com/screencasts
[21]: https://pragprog.com/magazines
[22]: https://pragprog.com/articles
[23]: http://forums.pragprog.com/
[24]: https://pragprog.com/help-wanted
[25]: https://pragprog.com/promotions
[26]: https://pragprog.com/about
[27]: https://pragprog.com/feed/global/news.rss
[28]: https://pragprog.com/frequently-asked-questions/ebooks/sending-ebooks-to-your-dropbox
[29]: https://pragprog.com/frequently-asked-questions/ebooks/sending-ebooks-to-your-google-drive

