- Hunt, Andrew and Thomas, David
- Many books tell you how to talk in a programming language, but that is only a part of what programmers do.
- “Kaizen”—Japanese word for Slight Edge principle
What distinguishes Pragmatic Programmers? We feel it’s an attitude, a style, a philosophy of approaching problems and their solutions. They think beyond the immediate problem, always trying to place it in its larger context, always trying to be aware of the bigger picture. After all, without this larger context, how can you be pragmatic? How can you make intelligent compromises and informed decisions?
- We can be proud of our abilities, but we must be honest about our shortcomings
Provide options, don’t make lame excuses.
- Broken window
- Start-up fatigue—people defend resources (committees, budgets, etc.)
- It’s easier to ask forgiveness than it is to get permission
- Be catalyst for change
- Knowledge portfolio = financial portfolio
- know what you want to say
- know your audience
What do you want them to learn? What is their interest in what you’ve got to say? How sophisticated are they? How much detail do they want? Who do you want to own the information? How can you motivate the to listen?
- Choose your moment
- Choose a style
- Make it look good
- Involve your audience
- Be a listener
- Get back to people
DRY—because you may forget changing second piece of code
- i.e., every piece of knowledge must have a single representation
- Inter developer
- Bad code requires lots of comments
- Anything might change, do not rely on anything (e.g., vendor)
- “There are no final decisions”
- Tracer bullets—integrate all parts together faster, than finish them in parallel
- Program close to problem domain
- Tools amplify your talent
- config (font, color, keystroke bindings)
- extensible (the editor should grow with you)
- programmable (complex multi-step tasks)
- run shell commands
- efficient movement
- don’t use a teaspoon as a shovel
- picking a good editor and not learning is no good
- set compiler warnings as high as possible
- rubber duck
- code generators
- design by contract
- metadata-driven applications
- coding is not mechanical
keep track of refactorings (and schedule them)
- let people know a module is scheduled to refactoring
After debugging, formalize unit tests
- look where you insert print statements
Don’t use wizard code you don’t understand (auto-generated code)
- because generated code is not abstracted away, but rather interwoven with the programmer’s code—it becomes programmer’s code
No matter how well thought out it is, and regardless of which “best practices” in includes, no method can replace thinking.
Don’t gather requirements—dig for them.
Requirements rarely lie on the surface. Normally, they’re buried deep beneath layers of assumptions, misconceptions, and politics.
Separate requirements from policy
- e.g., who has access to view the data is a policy and may change
- work with a user to think like a user
- Good requirements documents remain abstract.
It’s important to discover the underlying reason why users do a particular thing, rather than just the way they currently do it. At the end of the day, your development has to solve their business problem, not just meet their stated requirements. Documenting the reasons behind requirements will give your team invaluable information when making daily implementation decisions.
Requirements are not architecture. Requirements are not design, nor are they the user interface. Requirements are need.
- maintain a glossary
Distribute requirements in web format. That’s handy and avoids a thick “Requirements Analysis” document no one reads.
- “If it’s on the Web, the programmers may even read it.”
- generate a team name and logo
- optical illusions or mythical cities are good names for a team
- use saboteurs to test your testing
- Analysis Patterns - Fowler
- Demeter Project
- The Practice of Programming - Brian Kernigan, Rob Pike
- When good enough software is best - Edward Yourdon
- Code Complete, Clean Code