pragmatist
Patrick Joyce

July 19, 2013

Build It Twice

Good programmers hate duplication. They're intelligently lazy. So as a general rule they try to avoid building the same thing twice.

However, this very reasonable desire often leads otherwise pragmatic developers to build over-abstracted, hard to maintain software.

Let's take a real example. You're an engineer working on an e-commerce site that currently accepts credit cards and you're asked to add support for PayPal. You suspect you may have to integrate with similar systems in the future, so you start to think through how you would build a general solution for PayPal-like services.

You should avoid thinking about that now.

My advice when you're building something new is to focus exclusively on the problem at hand. Don't worry about how you're going to need to build something similar in the future. Don't try to build a general framework for solving that class of problem. Just build the best PayPal integration you can.

Most reasonable engineers can manage to suppress their urge to build a framework the first time they solve a problem. It's when they see a similar problem that they get in trouble.

The trap

You built a great PayPal integration; customers are happy, conversion rates are up. A few months later, your VP of Product comes to you and asks you to add support for Amazon Payments. Surely now is the time to build that common base class or library?

I don't think so.

When a similar project or requirement comes along it is very tempting to extract the parts of your first solution that apply to this one.

"This isn't a science project, I'm extracting from working code!" you'll think.

"But this will make maintenance so much easier" your programmer brain will scream.

"Think of how much less code I'll have to write."

I know this is how I start thinking when I see a problem that is similar to one I've already solved.

Stop.

You're not ready to build a general version yet.

The trouble is that while you have solved the problem once, you still don't know which parts of your program are general to the class of problem, and which were specific to that first project.

Build it again

If you try to extract a framework or library at this point you run the risk of creating something that is too specific to the first problem.

You'll end up with a library that is so tailored to PayPal that it only awkwardly maps to other systems.

So solve the second problem the same way you did the first: by building the best solution to that specific problem that you can.

By all means, apply what you learned the first time, but don't let that dictate what you build. If there is something different about this problem then solve it differently.

Third time's the charm

A few more months go by. Both PayPal and Amazon Payments are working well. Your VP of Product comes back again, this time asking you to add Google Checkout.

Now you know enough to break out common code into a library or service. At this point you've solved similar problems twice and you're thinking through the third case. This should give you a pretty good sense of what things are common to this type of problem and what is problem-specific.

You'll also have solved two similar problems in similar—but somewhat different—ways. This will help you build a good solution to those common problems.

The rewards of patience

By waiting to build a framework you get to design from a position of experience: both with regards to the problem and how to solve it. This means you should end up with a better common solution than if you had created a framework at the beginning when you were just learning about the problem.

There's another benefit, too. There's a good chance that you'll never be asked to solve those second and third similar problems. If those additional problems never come along you're left with a solution perfectly tailored to your problem without the additional complexity of a generalized framework.

When you feel the itch to create a framework, wait. You and your code will be better off for it.

More Articles on Software & Product Development

Agile With a Lowercase “a”
”Agile“ is an adjective. It is not a noun. It isn’t something you do, it is something you are.
How Do You End Up With A Great Product A Year From Now?
Nail the next two weeks. 26 times in a row.