Book: The Pragmatic Programmer

In terms of purely technical, I would say Code Complete has done better. However, this book is great at the point that it’s really practical and drives software engineers not just focus on technical parts. In addition, you need to understand the project itself, its requirements, how to communicate with other engineers as well as customers.

Still worth to give it a read! I am going to list out what caught me up most.

Chapter 1: A Pragmatic Philosophy

Software Entropy

One broken window, left unrepaired for any substantial length of time, instils in the inhabitants of the building a sense of abandonment—a sense that the powers that be don’t care about the building. So another window gets broken. People start littering. Graffiti appears. Serious structural damage begins. In a relatively short space of time, the building becomes damaged beyond the owner’s desire to fix it, and the sense of abandonment becomes reality. 

Chapter 2: A Pragmatic Approach


Duplication in Documentation

This is somewhat I’ve seen across codebase in the company: code comments are out-of-date and do not reflect the current state of code. I agree in code comments we explain reasons or “why” rather than “how”. Because the code itself is already “how”.

In case, the code is not clear to represent “how”, we may rewrite the code, use appropriate names for functions and variables, or decouple it into smaller functions.

Orthogonality > Avoid global data

Every time your code references golba data, it ties itself into the other components that share that data.

Working with WordPress and the most common global variable $post, I can feel this pain. Definitely, we need to avoid this. I’ve seen two patterns to achieve the same thing but less painful: singleton and dependency injection.

Reversibility

When we use an external configuration/vendor, we may need to think about the ability to easily switch between different vendors and that does not affect other parts of the current project. A solution is to abstract the idea of configuration/vendor to a service, then we have the flexibility to “change horses in midstream”.

My team builds an API layer to interact with another service but the vision of the product is to work with any provider rather than just a single provider. This concept is exactly what an RFC has been proposed: to create a business logic abstraction.

Chapter 3: The Basic Tools

Generally, this is a good call to learn shell, Unix, and text manipulation tools! I found out the need for this when working on CI setups.

Chapter 4: Pragmatic Paranoia

In chapter 4, the author mentions “Design by Contract”. I found out this becomes more important for loosely typed languages like JavaScript (glad that now TypeScript exists) or PHP. If possible, always declare input and output types, which helps reduce a lot of type issues, catch up issues during the development phase, and make things easier when debugging issues.

Don’t Outrun Your Headlights

Always take small, deliberate steps, checking for feedback and adjusting before proceeding. Consider that the rate of feedback is your speed limit. You never take on a step or a task that’s “too big.”

I think this is a good reminder that sometimes we go too fast and solve unknown future issues. Development resource is scarce, so iterate on feedback or simplify things before spending too much to solve “unknown future issues”.

Chapter 5: Bend, or Break

Global Data Includes External Resources

Any mutable external resource is global data. If your application uses a
database, datastore, file system, service API, and so on, it risks falling into
the globalization trap. Again, the solution is to make sure you always wrap
these resources behind code that you control.

If It’s Important Enough to Be Global, Wrap It in an API

Keeping your code shy: having it only deal with things it directly knows about,
will help keep your applications decoupled, and that will make them more
amenable to change.

Events Are Ubiquitous

Events are everywhere. Some are obvious: a button click, a timer expiring.
Other are less so: someone logging in, a line in a file matching a pattern. But
whatever their source, code that’s crafted around events can be more
responsive and better decoupled than its more linear counterpart.

Events are a big part of programming. Many patterns like pubsub, observer, etc. For example, Redux and Flux both implements observer to handle events in JavaScript and React.

Transformations Transform Programming


Thinking of code as a series of (nested) transformations can be a liberating
approach to programming. It takes a while to get used to, but once you’ve
developed the habit you’ll find your code becomes cleaner, your function
shorter, and your designs flatter.

It’s interesting to see the usage of pipeline operator |>. There is a proposal for JavaScript here.

Tip 51 Don’t Pay Inheritance Tax

Let us suggest three techniques that mean you should never need to use
inheritance again:
• Interfaces and protocols
• Delegation
• Mixins and traits

I can not say anything more correct than this! They definitely make code much more readable and understandable. Also, using them also requires developers to know exactly what they’re implementing.

Chapter 6: Concurrency

Tip 57 Shared State Is Incorrect State

Tip 58 Random Failures Are Often Concurrency Issues

They’re true statements! I have not much experience with these issues but I think it’s worthwhile to know a bit about model “Actors and Processes”.

Chapter 7: While You Are Coding

When dealing with complicated problems. The better way is to move away from it for a while:

First, stop what you’re doing. Give yourself a little time and space to let your
brain organize itself. Stop thinking about the code, and do something that is
fairly mindless for a while, away from a keyboard. Take a walk, have lunch,
chat with someone. Maybe sleep on it. Let the ideas percolate up through the
layers of your brain on their own: you can’t force it. Eventually they may
bubble up to the conscious level, and you have one of those a ha! moments.

Empathy and empathy:

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

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. Even within one program, don’t let what you’ve already done constrain what you do next—be
ready to refacto

You refactor when you’ve learned something; when you understand something
better than you did last year, yesterday, or even just ten minutes ago.

Other advice:

  • The fastest solution in general may not be suitable to your specific problem with a small set. The fastest solution can only make sense with a huge dataset as it takes a lot of time to implement.
  • Be wary of premature optimization. Again, don’t worry too much about “unknown future issues”.

Chapter 8: Before the Project

Requirements and requirements! We’re just going to wast time if we don’t know what we’re heading towards.

No One Knows Exactly What They Want

That’s where we programmers come in. Our job is to help people understand
what they want. In fact, that’s probably our most valuable attribute. And it’s
worth repeating: Programmers Help People Understand What They Want

Requirements are not architecture. Requirements are not design, nor are they
the user interface. Requirements are need.

Use a Project Glossary
It’s hard to succeed on a project if users and developers call the same thing
by different names or, even worse, refer to different things by the same name.

There Can Never Be an Agile Process
In fact, whenever someone says “do this, and you’ll be agile,” they are wrong.
By definition.

Because agility, both in the physical world and in software development, is
all about responding to change, responding to the unknowns you encounter
after you set out.

Chapter 9: Pragmatic Projects

I think it is never wrong with the following quotes. We need to know our own problems and available resources, and then choose tools or methodologies that are most suitable to projects.

Context Matters

One Size Fits No One Well
The purpose of a software development methodology is to help people work
together

The following preparation makes more sense. What’s the purpose of programming? Automation! Then if we see repetive processes during the development phase, let’s apply automation way: auto deploy, auto testing, auto update, etc:

And so the idea of the Pragmatic Starter Kit was born, covering these three
critical and interrelated topics:
• Version Control
• Regression Testing
• Full Automation

Empathy is how a team can work together. The rule is always “don’t blame” and use “Assume Positive Intent”:

Sign Your Work

That’s not what we want. You shouldn’t jealously defend your code against
interlopers; by the same token, you should treat other people’s code with
respect.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s