- Avoid debugging
- make bugs impossible with techniques like static typing, automatic dynamic checking, and immutability
- Keep bugs confined
- failing fast with assertions keeps a bug’s effects from spreading
- incremental development and unit testing confine bugs to your recent code
- scope minimization reduces the amount of the program you have to search