What Writing DRY Code Really Means

Shawn Deprey
KITE SRM
Published in
4 min readMay 12, 2020

Most developers early in their careers learn an important programming principle called Don’t Repeat Yourself (DRY). For most engineers this basically means avoid writing the same lines of code more than once, and realistically that’s the best place to start when learning how to write efficient code. While DRY is an important code-writing concept, it’s far from the whole story.

DRY as a programming principle was formulated by Andy Hunt and Dave Thomas in their 1999 book The Pragmatic Programmer. They lay out the DRY principle this way: “Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.” You’re probably thinking that description is a bit more convoluted or deeper than simply not repeating the same lines of code, and that’s for a good reason. Hunt and Thomas are elegantly conveying a higher-level concept: when you write code, you are not just building an application, you’re implementing a logic system.

So what’s the difference between an application and a logic system?

Well… Nothing, and everything! It really depends on your perspective for viewing code. From the programmer’s perspective, an application is the sum of all the code that runs it. However, from the architect’s perspective, code is the implementation of a logic system. Both perspectives are talking about the same thing but from a different layer of the implementation lifecycle. That point is crucial when considering DRY’s full meaning. Hunt and Thomas’s definition speaks not only to the programmer but also to the architect. Likely you fulfill both roles depending on the day, so let’s explore how we can expand DRY to make better systems and ultimately better applications.

Expanding DRY for Everyday Use

In my own practice, I like to use a term that generally helps developers better implement the tenants of DRY: Pattern machining.

Pattern machining is the process of DRYing systems. Technically, DRY and pattern machining mean the same thing. However, I’ve found that using a term that describes DRY at a different layer of the implementation lifecycle helps people remember DRY at a more fundamental level. So how do you implement pattern machining in your applications? The clue is in the name.

When you’re developing an application, do not start with writing code. Instead, lay out a plan, a blueprint if you will. Architects are familiar with this step, but it might take some practice if you haven’t done it before. For those new to architecture, think back to the time you’ve spent pseudocoding. Software architecture is essentially pseudocoding but at a higher level where the goal is to describe your system logically.

Once you’ve laid out a plan for your system, start considering which parts of that system are not DRY. These non-DRY elements will present themselves to you as patterns.

Let’s look at an example any back-end developer will be familiar with: CRUD APIs.

CRUD stands for Create, Read, Update and Destroy. These are the fundamental building blocks of any REST API, and if you’re an engineer who’s done any API work you know how tedious it is to write tons of controllers that essentially do the same thing: create, read, update and destroy your models. There’s your clue. A pattern that is repeated continuously between your controllers can be pattern machined.

Let’s look at a front-end example.

Have you ever built a list? Of course you have, and you have probably built different kinds of lists, including tables, unordered lists and div lists. Every time you’ve done so you’ve likely written a lot of the same code: a loop and some kind of rendered listing element. There’s your clue. You have a pattern that is repeated continuously between all lists, and yes, it can be pattern machined.

Now that we’ve reviewed a couple examples of pattern machining at different layers of the development stack, let’s return to our original DRY definition and see if it makes a bit more sense.

“Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.”
Andy Hunt and Dave Thomas

The knowledge Hunt and Thomas refer to is a piece of your system, not just a line of code. In our examples above, CRUD and lists represent pieces of knowledge that can be abstracted and systematized to create an efficient DRY system. Key to identifying these pieces of knowledge are the patterns they emit. This hidden “pattern” element of Hunt and Thomas’s definition is why I use the term pattern machining alongside DRY in my everyday practice to help developers on our team learn the deeper meaning of this pivotal programming principle.

When implemented successfully, pattern machining can take large amounts of code and perform the same operations with far less code. And less code means you can manage your application with a much smaller team, new developers can understand the code more easily and the application will be much more scalable.

At KITE, we’ve pattern machined large parts of our server and client projects, including CRUD and lists, and have witnessed all of the aforementioned benefits firsthand. When onboarding one of our new developers last year, he observed how crazy it is to do CRUD any other way given the efficiency of pattern machining it. It was great to see how quickly new developers can grasp this concept and start using it in their systems.

I hope this helps clarify the power of DRY for all types of engineers. May pattern machining prove useful to you and your practice as well.

Shawn Deprey — Director of Computer Science @ KITE

--

--

Shawn Deprey
KITE SRM

Architect | Engineer | Product Designer | Gamer