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();
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);
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');
}
}
}
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');
}
}
}
}
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
Top comments (11)
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)
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 ✌️
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
Yes! This makes me realize that DRY is SPOT as seen by a developer.
Is SPOT single point of termination? I hadn't heard that acronym before :)
Single Point of Truth, really.
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...
Oh nice one, added to my watch list, thanks Joaquin! ✌️
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.
Oh that first chapter you mention is such a good story part actually!
Nice addition.
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.