TL;DR: Andy Hunt and Dave Thomas have done a lot of programming. This is what they have to say about it. Some pieces are outdated, others are timeless, all are certainly worth the read.
1: A Pragmatic Philosophy
- Tip 1: Care About Your Craft
- Tip 2: Think! About Your Work
- Kaizen is a Japanese term that captures the concept of continuously making many small improvements (L239)
- Pragmatic programmers think beyond the immediate problem, always aware of the bigger picture
- One of the cornerstones of the pragmatic philosophy is the idea of taking responsibility for yourself and your actions in terms of your career advancement, your project, and your day-to-day work. “The greatest of all weaknesses is the fear of appearing weak.” (L239)
- Stone Soup and Boiled Frogs: kick off a small part of change yourself. People find it easier to join an ongoing success.
- 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. (L450)
- Stop when you hit great!
- An investment in knowledge always pays the best interest - Ben
- Unfortunately, in tech, knowledge expires. Gotta keep the tools sharp.
- WISDOM of understanding audience
- What do you want them to learn?
- what is their Interest in what you have to say?
- how Sophisticated are they?
- how much Detail do they want?
- whom do you want to Own the information?
- how can you Motivate them to listen to you?
2: A Pragmatic Approach
- Maintenance is not a discrete activity, but a routine part of the
entire development process. (680)
- Don’t bemoan it! You can try to cut down but it will still be there and it should be.
- DRY: Don’t Repeat Yourself.
- Duplication types:
- Imposed duplication, where developers feel like they have no choice
- Inadvertent duplication, where developers don’t realize they’re duplicating
- Impatient duplication, where developers get lazy and duplicate because it’s easier
- Interdeveloper duplication, where developers do the same work
- Things are orthogonal if changes in one do not affect any of the
others, e.g. database code and user interface
- Non-orthogonal systems are more complex to change and control. Make it so there’s no such thing as a local fix.
- Tip 13: Eliminate Effects Between Unrelated Things
- Main benefits: increased productivity and reduced risk
- Don’t rely on the properties of things you can’t control (L885)
- With DRY you’re looking to minimize duplication within a system, whereas with orthogonality you reduce the interdependency among the system’s components.
- When in doubt, choose the more reversible decision
- Tracer code: minimum viable deployable application, end to end
- Not throwaway code (that’s a prototype)
- Users get to see something working early
- Developers build a structure to work in
- You have something to demonstrate
- You have a better feel for progress (easier to scope)
- Questions to ask when prototyping:
- Are responsibilities of major components well-defined and appropriate?
- Are the collaborations between major components well-defined?
- Is coupling minimized?
- Can you identify potential duplication?
- Are interface definitions and constraints acceptable?
- Does every module have access to the data it needs during execution?
- Domain language: “ubiquitous language” concept from DDD.
- Whether it’s a simple language to configure and control an application program, or a more complex language to specify rules or procedures, we think you should consider ways of moving your project closer to the problem domain. (L1217)
- First question is about context. Do you need high accuracy or just a ballpark?
- Understand what’s being asked
- Scope scope scope
- Build a mental model of the system
- Break the model into components
- Give each parameter a value
- Calculate the answers
- Understand what’s being asked
- I’ll get back to you.
3: The Basic Tools
- Plain-text: universally portable, human readable, will never be
obsolete, not tied to any implementation or parser
- Command shell is the workbench for manipulating plain text
- Editor: know one. Well.
- Debugging is problem solving.
- Beware of myopia when debugging. Resist the urge to fix just the symptoms you see: it is more likely that the actual fault may be several steps removed from what you are observing, and may involve a number of other related things. Always try to discover the root cause of a problem, not just this particular appearance of it. (L1758)
- Start by gathering all relevant data
- Go through all assumptions and verify
- Tracer print statements: “I AM HERE”…
- Rubber duck: just explain the problem out loud
- Test, test, test when you make the fix
- Is the reported problem a symptom or the real thing?
- Is the bug in the compiler or in the OS?
- How would you explain the problem to a coworker?
- Are the tests complete?
- Do the conditions that caused this bug exist anywhere else in the system?
4: Pragmatic Paranoia
- Don’t trust yourself! You make mistakes. Be defensive
- Design by contract: Add contracts to your code (i.e. iContract for
Java). Your code shøuld abide by the contract and do nothing more.
- Liskov Substitution Principle: Subclasses must be usable through the base class interface without the need for the user to know the difference
- Leave assertions in your code to call out non-negotiable contracts
- Tip 34: Use Exceptions for Exceptional Problems.
- Tip 35: Finish What You Start
- Close files, etc.
5: Bend, or Break
- Limit interaction between modules
- Law of Demeter: don’t reach into an object to gain access to a
third object’s methods
- More like a “guideline of Demeter”
- MVC: separate model (data), view (interpretation of model), controller (coordination and translation mechanism)
6: While You Are Coding
- Program deliberately
- Don’t “program by coincidence”; you must understand exactly why your code works
- Rely only on documented behavior
- If you can’t, document your assumption well
- Always be aware of what you’re doing
- Understand the domain
- Plan first.
- Programming isn’t construction, it’s gardening
- Organic, changes, growth
- Fowler’s rules on refactoring:
- Don’t refactor and add functionality at the same time
- Make sure you have good tests before you begin refactoring. Refactor tests as often as possible. Then you’ll know quickly if you broke anything
- Take short, deliberate steps. Line by line, method by method. Check your changes often.
7: Before the Project
- Tip 51: Don’t Gather Requirements, Dig For Them
- Requirements are not on the surface. People, especially domain experts, tend to leave out stuff that feels “basic” to them but is actually very important to the implementation
- Shadowing is an effective technique
- Project glossary tracks all the commonly used words in the project
- Specification trap: don’t try to get every single detail. Just get
it to the point where the programmer’s skill can take over.
- Trick: try to describe how to tie their shoes.
8: Pragmatic Projects
- Automate, automate, automate
- Appoint tool builders on the team to make sure things get automated
- People just aren’t as repeatable as computers are. (L4020)
- Types of tests to write:
- Unit tests
- Integration tests
- Validation and verification (does it actually work the way the user wants?)
- Resource exhaustion, errors, recovery
- Memory, disk space, CPU bandwidth, wall-clock time
- Performance testing
- Usability testing
- Make well chosen and meaningful variable names
- Never make misleading names!! These trigger the Stroop Effect and the brain gets super confused
- Document concisely but thoroughly
- Small usability wins:
- Tooltip help