DEV Community

loading...
Cover image for Software design principles: DRY

Software design principles: DRY

dailydevtips1 profile image Chris Bongers Originally published at daily-dev-tips.com ・2 min read

Today we'll be exploring a design principle called DRY it stands for Don't Repeat Yourself. Of course, a pretty obvious one, meaning you shouldn't type code more than once.

The principle states: "Every piece of logic must have a single unambiguous representation within a system".

Of course, with the upcoming of component-based frameworks, we see less and less of reused codes.

DRY Examples

I'm going to demonstrate some simple use-cases, but they should give you a good understanding of what DRY means.

const foods = ['🧀','🌶','🍉'];
const animals = ['🦞','🐁','🐕'];

revFoods = foods.reverse();
revAnimals = animals.reverse();
Enter fullscreen mode Exit fullscreen mode

This is only a very simple function, but this can be converted to a DRY part:

const foods = ['🧀','🌶','🍉'];
const animals = ['🦞','🐁','🐕'];

let reverse = (input) => {
  return input.reverse();
}

revFoods = reverse(foods);
revAnimals = reverse(animals);
Enter fullscreen mode Exit fullscreen mode

Why would you do this?
Well, think of this code as a little bit more complicated, a full sorting function, and all of a sudden the sorting key changes, you now have to make changes twice, instead of doing it once.

Another good example is validations; this is were I personally fail sometimes.

<?php
class Validator {
    public function validate(array $post)
    {
        if(!isset($post['title']) {
            throw new \Exception('validation failed, no title set');
        }
        if(!isset($post['date']) {
            throw new \Exception('validation failed, no date set');
        }
        if(!isset($post['description']) {
            throw new \Exception('validation failed, no description set');
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

While it's not specifically a violation, we could enhance this and make our lives easier in case that exception might ever change.

<?php
class Validator {

    private $validateAttributes = [
        'title', 
        'date', 
        'description'
    ];

    public function validate(array $post)
    {
        foreach ($this->validateAttributes as $attribute) {
        if (!isset($post[$attribute])) {
            throw new \Exception('validation failed, no '.$attribute.' set');
        }
    }
    }
}
Enter fullscreen mode Exit fullscreen mode

There you go. I hope you learned something about not repeating yourself in code.

Looking forward to hearing what kind of things you do that you could optimize?

Thank you for reading, and let's connect!

Thank you for reading my blog. Feel free to subscribe to my email newsletter and connect on Facebook or Twitter

Discussion

pic
Editor guide
Collapse
winstonpuckett profile image
Winston Puckett

This is interesting. I always apply DRY to my business logic: "make sure every time you validate the sales order, it's done through the same method." vs with my programming concepts like: "make sure that every time you validate that a field is present, it's done in the same method."

I've found that as my software ages, the parts that break are the ones which are coupled together for the reason of allowing a developer to write less lines over the ones which must be done the same from a business perspective. I always ask myself, "Would I expect X user flow to break if Y breaks." Then if I do, I consider coupling it together.

You seem to have a different experience. What techniques do you use to manage wide dependency trees this could create? Do you find that this creates wide dependency trees?
(I'm hoping this doesn't come across as confrontive. I'm honestly trying to ask a question while giving a bit of background... it's hard without body language lol)

Collapse
dailydevtips1 profile image
Chris Bongers Author

Haha I totally visualize you as a person waving your hands now.

I think my main thing is thinking out the full application on paper to help with this.
There we write out what could change for a reusable element.

But as you might know, requirements change, and this can cause hectic changes, and break for one of the things.

Just the other day created a super re-usable input component, could handle about anything, except for large file upload.

Trying to wire that into it, was just breaking about everything, so decided to deduct it, it's not neat and nice, and what you want, but sometimes it's also a good mix of time vs effort vs result.

I hope I got your question right here, also up for discussion on points like this ✌️

Collapse
winstonpuckett profile image
Winston Puckett

Ah, that also might be part of it :). My current job has a simple front end and endlessly complex back end, so I'm mostly thinking of API calls. I could totally see designing a reusable component

Collapse
xtofl profile image
xtofl

Yes! This makes me realize that DRY is SPOT as seen by a developer.

Collapse
winstonpuckett profile image
Winston Puckett

Is SPOT single point of termination? I hadn't heard that acronym before :)

Thread Thread
xtofl profile image
xtofl

Single Point of Truth, really.

Collapse
darkwiiplayer profile image
DarkWiiPlayer

I highly recommend reading the chapter Beware the Share from the book 97 Things Every Programmer Should Know. Probably also the section Don't Repeat Yourself.

Collapse
dailydevtips1 profile image
Chris Bongers Author

Oh that first chapter you mention is such a good story part actually!
Nice addition.

Collapse
jqn profile image
Joaquin Guardado

Cool topic Chris, you should check out this video by Kent C Dodds where he goes deeper into when and why to use DRY and when other patterns are more applicable.
youtube.com/watch?v=wuVy7rwkCfc&li...

Collapse
dailydevtips1 profile image
Chris Bongers Author

Oh nice one, added to my watch list, thanks Joaquin! ✌️

Collapse
zoedreams profile image
☮️✝️☪️🕉☸️✡️☯️

nice simplified explanation` of the mysterious IoC -> en.wikipedia.org/wiki/Dependency_i...

thanks for keeping it DRY. phun not intended this time., i love your article

Collapse
dailydevtips1 profile image
Chris Bongers Author

Whahaha, love this!

Yeah IoC is harder to fully wrap your head around, if explaining it as DRY it's easier for beginners, and even experienced devs.

I tend to look at my code like an 8-year-old quite a lot, would I understand it, would I be able to use it etc.