I just wrapped up Chapter 2 of The Pragmatic Programmer, and let me tell you, it really got me thinking about what makes good design—not just in terms of looks, but how adaptable it is for the future. Moreover, a well-designed system should be easy to change, which is a game-changer when you’re in the thick of coding.

The chapter also discussed the pain points of code duplication. After reading it, I just had one thought it’s fascinating how every piece of code is more than just lines on a screen; it carries meaning and intention. And that’s not all!

I even discovered the concept of orthogonality—how decoupling parts of your system can keep things tidy and efficient. Well, there are several other plus points. So, let’s dive deeper into the learnings!

What Makes a Design Truly Great for a Pragmatic Programmer?

  • A well-designed system isn’t just about looking pretty—it’s about being easy to change.
  • The ETC principle (Easier To Change) helps guide you toward writing adaptable code. Well, think of it as a mental checklist:
    • Keep asking yourself during development, “Will this make future changes easier or harder?”
  • How to ensure your code follows ETC:
    • Write code that’s replaceable—so it won’t become a bottleneck later.
    • Take note of design decisions to revisit them when the code evolves.

Why Is Duplication So Painful (The Evils of Duplication)?

  • The second chapter of Pragmatic Programmer on duplication really hits the nail on the head with this quote:
    Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.
  • Thinking of code as knowledge captures the human side of development—each line holds meaning, logic, and intention.
  • The temptation to duplicate code usually falls into one of these “Four I’s”:
    1. Imposed: Sometimes you’re forced to repeat code due to external constraints.
    2. Inadvertent: Duplication sneaks in without you noticing, especially when teams work in silos.
    3. Impatient: The “quick fix” mindset, where copy-pasting feels faster than finding a proper solution.
    4. Interdeveloper: When teams fail to communicate effectively, leading to redundant code across the board.

Bottom line: Stay DRY (Don’t Repeat Yourself). Also, when code or knowledge has a single, clear representation, it becomes:

  • Easier to reuse.
  • Easier to change.
  • Easier to share across teams.

How Can Orthogonality Keep Your Code Tidy?

  • Orthogonality refers to decoupling parts of your system, so changes in one place don’t mess things up elsewhere.
  • Think of it like this: Your car’s turn signal and the steering wheel are orthogonal—flicking the signal won’t force the car to turn (or you’d have a lot of crashes!).
  • Eliminating side effects in code provides huge benefits:
    • Increased productivity since changes are contained.
    • Lower risk of introducing bugs, as code is more isolated and easier to test.
  • How to achieve orthogonality:
    • Avoid global variables or data that can ripple through the system.
    • Keep your functions focused and independent.

Why Should You Think Ahead About Reversibility?

  • Reversibility is about not locking yourself into one solution. Decisions should be flexible so you can adjust when things go south.
  • This principle isn’t just for code—it applies to business and project decisions too.
    • For example, at Aggrego, we partnered with third-party vendors without retaining control of key data or architecture, and that decision came back to bite us.
  • How to prepare for reversibility:
    • Build abstraction layers to avoid dependency traps.
    • Break code into small, modular components that are easy to swap or upgrade.

What Are Tracer Bullets, and How Do They Benefit You?

  • Tracer bullets are a bare-bones version of your code that provides minimal functionality and helps you get early feedback.
  • This method isn’t just about building a prototype—it’s about evolving the code toward the final product.
  • Benefits of tracer bullets:
    • Users get to see something working early on.
    • Developers build a foundation for further work.
    • It creates a structure for easier integration.
  • Pro Tip: Tracer bullets should be easy to tweak based on feedback—this is what helps them evolve quickly.

What Sets Prototypes Apart from Tracer Bullets?

  • Prototypes are disposable versions of your product, often hacked together just to see if an idea works.
  • Use prototypes when you need to test feasibility before fully committing to development.
  • Unlike tracer bullets, prototypes aren’t meant for production—their value lies in the lessons learned, not the code itself.
  • What to ignore in a prototype:
    • Correctness
    • Completeness
    • Style or robustness
  • Just be clear with stakeholders: The prototype isn’t the final product. It’s a rough draft, not something you can ship!

What Are Domain-Specific Languages, and Why Should a Pragmatic Programmer Use Them?

  • Domain-specific languages (DSLs) are mini-languages designed to solve problems in a particular field. Think of Rspec in testing frameworks—it’s tailored to the testing domain, making code more intuitive.
  • Why use DSLs?
    • They make code easier to read and maintain, especially for people familiar with the problem domain.
  • Tip: As long as the problem domain doesn’t shift too much, maintaining the DSL should remain a low-effort task for a pragmatic programmer.

How Does a Pragmatic Programmer Gets Better at Estimating?

  • Estimating accurately can save you from a world of hurt—avoiding surprises keeps projects running smoothly.
  • A great tip from the chapter: The way you phrase your estimate matters.
    • Saying “It’ll take 13 days” gives the impression of precision—people expect 12-14 days.
    • But saying “Around two weeks” gives a more forgiving range—1 to 3 weeks feels reasonable.
  • Tips for better estimating:
    • Provide three estimates: optimistic, realistic, and pessimistic timelines.
    • Adjust your estimates at each iteration as the project evolves.
  • Pro Tip: When someone asks for an estimate, don’t rush. Take a moment to build a mental model—it’ll lead to more accurate predictions.

With these principles in mind, you’re set to write cleaner, maintainable code, make smarter decisions, and take the next step to become a pragmatic programmer. Just remember: stay DRY, plan for change, and keep things modular. And hey, if you need to slap together a prototype, make sure everyone knows it’s just a test!

Also, become an automation expert with my SDET Masterclass where you will learn everything about software development and testing.

×