I think “The Pragmatic Programmer” book by David Thomas and Andrew Hunt is a timeless treasure that remains ever-relevant in software development context. Filled with practical wisdom and approachable techniques, it equips developers with superpowers to tackle challenges and excel the process of software development. These 12 subjects are what I’ve gathered from the book, yet it offers learnings that surpass these 12:
1. Use Version Control
Record every change in your code base using version control. If you mess up, you can always go back to the previous code version. But a version control system does far more than reverting the mistakes. A good version control enable you to track changes, and helps in tracking modifications, identifying contributors to specific code lines, highlighting differences between versions, measuring code alterations, and recognizing frequently modified files. This kind of information is invaluable for bug-tracking, audit, performance, and ensuring quality. (Topic 19, Version Control, Page 84)
2. Good Enough Software
Seeking perfection often prolongs projects indefinitely. If you don’t know when to stop, you’ll end up in over-embellishment and over-refinement. Instead, aim for “good enough” and iterate. Deliver value early and often. Write code that works, prove it by writing tests, and ensure they are executed automatically. However, the phrase “good enough’’ does not imply sloppy or poorly produced code. (Topic 5, Good-Enough Software, Page 11)
3. Refactoring
Refactoring isn’t about big changes. Avoid starting a huge refactor. It’s more like tidying up your garden while weeding as a day-to-day process, not a major change. It’s the art of making small, low-risk changes to keep the code clean and efficient. And, last but not the least, unit testing is your trusty sidekick for keeping the code’s behavior consistent and dependable during refactoring. (Topic 40, Refactoring, Page 209)
4. Don’t blame, just fix it
Sometimes, you will find lousy code that someone else wrote. Sometimes, you will find bad code that you wrote some time ago. Pragmatic programmers don’t say, “I didn’t write this, so I will not fix it” but do something about it and open a debate in a team about why. Avoid spending time and effort in assigning fault to the creator. The responsibility of fixing a bug remains, it doesn’t really matter whether the bug is your fault or someone else’s. It is still your problem.(Top 20, Debugging, Page 89)
5. Broken Window Theory
The Broken Window Theory suggests that if something is broken, others will break it even more in the future. As a pragmatic programmer, you should fix all significant problems you find in the system while working on it. Don’t continue walking on the wrong path the last developer walked on. Don’t be a slave to history. Don’t let existing code dictate future code. I’ve recently worked on a legacy code-base where the original coder used incredibly poor variable names. Whenever I encountered these confusing variables during development, I took the initiative to rename them. Gradually, I managed to update the entire code-base, significantly improving the clarity of variable naming. However, I must admit that my initial plan was to rectify all names at once, which contradicted the refactoring principle of making incremental changes as a day-to-day activity rather than undertaking a massive overhaul. (Topic 3, Software Entropy, Page 7)
6. Stay Up To Date
Continuous learning is essential in software development world. Stay updated with new tools, technologies, and best practices. Learn at least one programming language, tech stack or framework every year. It doesn’t matter whether you ever use any of these technologies. Once you feel comfortable with some new language or bit of technology, move on, learn another one. Investing in your skills yields substantial returns in your career advancement. ( Tip 9, A Pragmatic Philosophy, Page 15)
7. DRY (Don’t Repeat Yourself)
Try not to repeat the codes, and when you notice duplication, refactor it into a shared function or module, because redundant code is more complex to maintain, and duplication is the root of all evil. DRY is not limited to code. Wherever you have to change code and documentation, or a database schema and a structure that holds it, your code isn’t DRY. (Topic 9, DRY—The Evils of Duplication, Page 30)
8. Programming By Coincident
Understand your code deeply; don’t rely on coincidental successes. If you’re not sure why it works, you won’t know why it fails. Make sure you know why your code works, not just that it works. Understanding the underlying mechanisms and environment in which the code works ensures confidence in the reliability and efficiency of your solutions. (Topic 38, Programming by Coincidence, Page 197)
9. Keep Your System Orthogonal
Two or more things are orthogonal if changes in one do not affect any of the others. In a well-designed system, the database code will be orthogonal to the user interface: you can change the interface without affecting the database, and swap databases without changing the interface. Enhanced productivity and reduced risks through modular, reusable, and isolated components are benefits of an orthogonal system. Three most important techniques to maintain your system orthogonal during development are :
- Keep your code decoupled
- Avoid global data
- Avoid similar functions
(Topic 10, Orthogonality, Page 39)
10. Be a Good Listener
To help your users, you’ll need to understand them first. Be careful when others speak, and ask good questions. When engaging with individuals such as product managers, developers, and business analysts, remain attentive and discerning to extract meaningful insights. The art of posing insightful questions plays a key role in uncovering comprehensive information, enabling you to craft solutions that resonate deeply with user requirements and expectations. Good questions comes after good listening, and well understanding. (Chapter 1, A Pragmatic Philosophy, Page 22)
11. Take Responsibility
Before you explain limitations or problems, assess yourself: talks to the rubber duck beside your laptop, evaluate the validity of your reasoning, anticipate your boss’s response, consider alternatives, and offer solutions rather than excuses. need to spend more time? need to learn some technique or technology? Don’t be afraid to ask, or to admit that you need help. (Chapter 1, A Pragmatic Philosophy , Page 4)
12. Culture of Testing
For all software, thorough testing is essential for minimizing future costs and issues. Your options boil down to: Test First, Test During coding, or Test Later. Testing early is the best, and testing during coding is good, but testing later is the worst choice because …, emm, let’s be honest “Test Later” really means “Test Never”. Keep in mind that all software you write will be tested, if not by you and your team, then by the eventual users. (Chapter 7, While You Are Coding, Page 222)