Alexandre Lim

The Pragmatic ProgrammerBy Andrew Hunt & David Thomas

A classic book in the software industry. A book that can be reread many times over the years no matter how experienced you'll become. From experience, I often saw too much dogmatism from my peers, which is why I really like the word pragmatic in the book's title. This book will help you build a solid foundation for long-term success in your career.


Each developer is unique, with individual strengths and weaknesses, preferences and dislikes. Over time, each will craft their own personal environment.

Pragmatic Programmer characteristics:

  • Early adopter/fast adapter
  • Inquisitive
  • Critical thinker
  • Realistic
  • Jack of all trades

We feel that there is no point in developing software unless you care about doing it well.

Never run on auto-pilot. Constantly be thinking and critiquing your work in real-time.

Within the overall structure of a project, there is always room for individuality and craftsmanship.

Kaizen applies to individuals, too. Every day, work to refine the skills you have and to add new tools to your repertoire.

Make no mistake, it is your career, and more importantly, It’s Your Life. You own it.

Your team needs to be able to trust and rely on you—and you need to be comfortable relying on each of them as well.

When you do accept the responsibility for an outcome, you should expect to be held accountable for it. When you make a mistake or an error in judgment admit it honestly and try to offer options. Don’t blame someone or something else, or make up an excuse. It is up to you to provide solutions, not excuses.

Whatever the name, both debt and rot can spread uncontrollably. Don’t leave “broken windows”(bad designs, wrong decisions, or poor code) unrepaired.

People find it easier to join an ongoing success. Show them a glimpse of the future and you’ll get them to rally around.

Keep an eye on the big picture. Constantly review what’s happening around you, not just what you personally are doing.

Great software today is often preferable to the fantasy of perfect software tomorrow.

Don’t spoil a perfectly good program by overrefinement. Move on, and let your code stand in its own right for a while. It may not be perfect. Don’t worry: it could never be perfect.

Your knowledge and experience are your most important day-to-day professional assets. Unfortunately, they’re expiring assets. Invest regularly in your knowledge portfolio.

Be curious. If you don’t know, search for it.

Beware of the zealots who insist that their dogma provides the only answer—it may or may not be applicable to you and your project. Critically analyze what you read and hear.

About communication:

  • Know what you want to say.
  • Know your audience.
  • Choose your moment.
  • Choose a style.
  • Make it look good.
  • Involve your audience.
  • Be a listener.
  • Get back to people.
  • Keep code and documentation together.

Good Design is easier to change than bad design.

Programmers are constantly in maintenance mode.

DRY (Don’t Repeat Yourself) principle: Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.

It isn’t a question of whether you’ll remember: it’s a question of when you’ll forget.

DRY of code is a tiny and fairly trivial part. DRY is about the duplication of knowledge, of intent. It’s about expressing the same thing in two different places, possibly in two totally different ways.

Not all code duplication is knowledge duplication.

Perhaps the hardest type of duplication to detect and handle occurs between different developers on a project. Encourage active and frequent communication between developers.

Two or more things are orthogonal if changes in one do not affect any of the others. When components of any system are highly interdependent, there is no such thing as a local fix. When components are isolated from one another, you know that you can change one without having to worry about the rest.

Don’t rely on the properties of things you can’t control.

Every time you write code you run the risk of reducing the orthogonality of your application. To help avoid that when you code:

  • Keep your code decoupled
  • Avoid global data ⇒ Be careful of Singleton Pattern
  • Avoid similar functions ⇒ Look at the Strategy Pattern

Look for the important requirements, the ones that define the system. Look for the areas where you have doubts, and where you see the biggest risks. Then prioritize your development so that these are the first areas you code.

Tracer code is not disposable: you write it for keeps.

The tracer code approach has many advantages:

  • Users get to see something working early
  • Developers build a structure to work in
  • You have an integration platform
  • You have something to demonstrate
  • You have a better feel for progress

Tracer bullets show what you’re hitting. This may not always be the target. You then adjust your aim until they’re on target. That’s the point.

Tracer code ≠ Prototype. Prototype is disposable code.

Many business users don’t read Cucumber Features because we rarely know what the requirements are.

What to say when they suddenly asked for an estimate? You say “I’ll get back to you.”

Learn the commands that make your life easier.

Rubber Ducking: Explain the problem to someone else for finding the cause.

When you come across a surprise bug, beyond merely fixing it, you need to determine why this failure wasn’t caught earlier.

You can’t write perfect software.

Whenever you find yourself thinking “but of course that could never happen” add code to check it. The easiest way to do this is with assertions. Don’t use assertions in place of real error handling. Assertions check for things that should never happen.

Take small steps—always. The more you have to predict what the future will look like, the more risk you incur that you’ll be wrong.

Tell, Don’t Ask. This principle says that you shouldn’t make decisions based on the internal state of an object and then update that object.

Coupled code is hard to change. Keep your code shy.

Four strategies to write responsive applications:

  • Finite State Machines
  • The Observer Pattern
  • Publish/Subscribe
  • Reactive Programming and Streams

Three techniques to avoid the use of inheritance:

  • Interfaces and protocols
  • Delegation
  • Mixins and traits

Concurrency is when the execution of two or more pieces of code act as if they run at the same time. Parallelism is when they do run at the same time.

Shared state Is incorrect state.

Actors and processes offer interesting ways of implementing concurrency without the burden of synchronizing access to shared memory.

Listen to your Lizard Brain.

A large part of our job is dealing with existing code, often written by other people. Those people will have different instincts from you, and so the decisions they make will be different. Not necessarily worse; just different.

We should avoid programming by coincidence—relying on luck and accidental successes—in favor of programming deliberately.

Don’t be a slave to history. Don’t let existing code dictate future code. All code can be replaced if it is no longer appropriate.

Code needs to evolve; it’s not a static thing.

Software is more like gardening than construction.

About Refactoring:

  • The activity is disciplined, not a free-for-all
  • External behavior does not change; this is not the time to add features

When to refactor?

  • Duplication
  • Nonorthogonal design
  • Outdated knowledge
  • Usage
  • Performance
  • The Tests Pass

Refactor early, refactor often.

Testing is not about finding bugs. The major benefits happen when you think about and write the tests, not when you run them. Testing is vital feedback that guides your coding.

One of the most important aspects of software development: we don’t know what we’re doing when we start.

Test your Software, or your users will.

Use Property-Based Tests to validate your assumptions.

Security Basic Principles:

  • Minimize Attack Surface Area
  • Principle of Least Privilege
  • Secure Defaults
  • Encrypt Sensitive Data
  • Maintain Security Updates

What’s in a name? When we’re programming, the answer is “everything!”

Programmers help people understand what they want.

Requirements are learned in a feedback loop.

Fortune favors the prepared mind. Let your nonconscious brain work for you.

About programming together:

  • Build the code, not your ego
  • Criticize the code, not the person
  • Listen and try to understand others’ viewpoints. Different isn’t wrong
  • Conduct frequent retrospectives to try and improve for next time

Agile is how you do things. There can never be an agile process.

Working in an agile way:

  • Work out where you are.
  • Make the smallest meaningful step towards where you want to be.
  • Evaluate where you end up, and fix anything you broke.

Do what works, not what’s fashionable.

The purpose of a software development methodology is to help people work together. There is no single plan you can follow when you develop software, especially not a plan that someone else came up at another company.

Many certification programs are predicated on the student being able to memorize and follow the rules. But you need the ability to see beyond the existing rules and exploit possibilities for advantage. You want to take the best pieces from any particular methodology and adapt them for use.

Your signature should come to be recognized as an indicator of quality. People should see your name on a piece of code and expect it to be solid, well written, tested, and documented. A really professional job. Written by a professional. A Pragmatic Programmer.

Last Updated

July 20th, 2022