Good day guys, you must have stumbled across this funny acronym 'DRY' as a programmer maybe you stick to it or maybe you think it creates more problem than it solves? If you haven't then let me introduce it to you. The acronym stands for Do not Repeat Yourself. This is a software development principle that suggests that you should avoid unnecessary or unjustified repetition in your code. The idea behind this principle is that if we avoid repeating logic in our code, it will be easier to maintain and manage. I totally agree with this, if you are a beginner, you might wonder how does this makes sense? We will come to that later, l stumbled across an article on DEV some time ago that prompted me to write this article. The author suggested that our code should be WET (Write Everything Twice). They presented a good argument about why code should be as WET as possible, however i don't totally agree with that, WET code causes more harm than good because at the end of the day why should you do something twice or thrice when you can do it once ?
If you are guilty of repeating yourself or you don't see reason why your code should be DRY as much as possible, or you are finding it difficult to make your code DRY, i will demonstrate to two tips with examples of why you should stick to this principle.
Take a Short Look at the Problem
As a software developer your primary job is to solve problems, and most of the time we are so eager to solve the problem that we don't spend time thinking about the problem. You might wonder how does this help? First thing first, how can you be sure that you totally understand the problem when you have not done due diligence on it? Thinking about the problem is crucial and i would advise you to spend some time doing so, why?
Case 1
Imagine we have a database with a list of orders, now each order has an address property that is an object with a country, state and city property;
[{
id: 1,
items: ['shoe', 'bag'],
address: {
country: 'nigeria',
state: 'rivers',
city: 'port harcourt',
}
},
{
id: 2,
items: ['jean shirt', 'sneakers'],
address: {
country: 'nigeria',
state: 'lagos',
city: 'victoria island',
}
},
{
id: 3,
items: ['tank top', 'leather belt'],
address: {
country: 'nigeria',
state: 'delta',
city: 'warri',
}
},
{
id: 4,
items: ['sneakers', 'bag'],
address: {
country: 'nigeria',
state: 'rivers',
city: 'port harcourt',
}
},
{
id: 5,
items: ['shoe', 'leather belt'],
address: {
country: 'nigeria',
state: 'lagos',
city: 'surelere',
}
},
]
Now imagine that we need to write a function that will allow us to search for an order based on a property of the address;
Examine the problem
The address field has three properties, a country, a state and a city. And we need to be able to find an order based on;
- The country
- The state
- The City
We can go ahead and write three functions, one for the city, another for the state and one more for the country but in the end our code would not be dry, and we will have three functions to manage.
The properties we are going to be searching for exists on one object, that lies inside the each order; if we just went ahead and wrote our code without it being DRY, i would look something like this;
function findOrderByCountry (country){
return orders.find(order => order.address.country === country)
}
function findOrdersByState (state) {
return orders.find(order => order.address.state === state)
}
function findOrdersByCity (city) {
return orders.find(order => order.address.city === city)
}
This is fine because our solution are just one liners, imagine that it spanned over 20 lines or more and we had to change something? Maybe we renamed the address field on each order to deliveryAddress? Now we have to change address in three different places. It could be more than just the name of the field we are changing. What if we decided to add a street property to the address?? or a zip and a street property? Now we have to write more functions, which could lead to more potential headaches in the future.
Remember, that the solution to a problem is not too far from the problem itself.
Take a long look at the solution
If you don't spend sometime looking at the solution you provided for the problem then you are not employing proper problem solving skills, this will enable you to see some loopholes inside your solution and it will give you a bigger picture of the problem thus helping you get your abstraction layer right. Looking at your solution will help you determine if your abstraction layer is right or not. Do you even have an abstraction layer ??
Looking at the solution will also give you a different perspective about the problem or your solution to it, whereas you were looking at the problem like an earthly observer, you can even start seeing the problem like someone on Mars, you get the idea ? Back to our orders problem. We can re-factor our solution so we have only one function that can handle the three search scenarios rather than 3 different function.
We know that the properties we are going to be searching for exists on one object which is a property of each order, using our knowledge of working with JavaScript objects, our solution should look like this;
function findOrderByAddressField(field) {
let foundOrders = []
orders.forEach(order => {
if (Object.values(order.address).indexOf(field) !== -1) {
foundOrders.push(order)
}
})
return foundOrders
}
const riversOrders = findOrderByAddressField('rivers') // find order by state
const phOrders = findOrderByAddressField('port harcourt') // find orders by city
const NigerianOrders = findOrderByAddressField('nigeria') // find orders by country
Now we have one function that handles the three search cases, even if we add more properties to to the address field on each orders, we don't need to even touch the solution because it is already set up for this, if we remove a field same thing. If we change the name of the field we only replace one word in the solution, you start to get the picture now ?
No matter how difficult the problem is, if you are repeating yourself then you are either;
- Not looking at the problem properly or
- Not looking closely at your solution to the problem.
Spend some time on the problem or the solution and re-factor your code accordingly, ensure that you get your abstraction layer right and you will reap the rewards of ensuring that your code is DRY.
I do hope that you find this useful.