DRY, KISS and YAGNI - Make Your Code Simple
Kevin Toshihiro Uehara
Posted on May 17, 2024
Hi There!!! How have you been? Everything alright? I hope so!
The previous post became so popular and I had no idea how interested you were about concepts of Software Engineer.
We know about SOLID, Design Patters and a lot of best practices.
Today I want to introduce you another practices: DRY, KISS and YAGNI. And I know what you thinking, what the hell are these concepts.
But trust me, these concepts are more easier than you thinking. So let's begin!
DRY - Don't Repeat Yourself
The name itself when we understand it already explains itself. When we are coding, propably you alreary saw some code that are repeating in the same or another files.
I don't want be boring and say that you DON'T need of this duplicity of code and you NEED to refact and create a generic or use the same code. Sometime we need repeat, it is not a probleme, 'cause sometimes we need to inject some new business rule or in some cases we need that piece of code in another file context.
I will create a simple function that find numbers:
But let's see a simple
example:
function main() {
const findTwoNumbers = [5, 1];
const array = [1, 3, 6, 8, 3, 5, 2, 3];
const findFirst = array.find((number) => number === findTwoNumbers[0]);
const findSecond = array.find((number) => number === findTwoNumbers[1]);
console.log(findFirst);
console.log(findSecond);
}
main();
Notice that we are repeating the .find
function. How about we separate this search into a function?
function findNumber(numberToFind: number, array: number[]) {
const value = array.find((number) => number === numberToFind);
console.log(value);
return value;
}
function main() {
const findTwoNumbers = [5, 1];
const array = [1, 3, 6, 8, 3, 5, 2, 3];
findNumber(findTwoNumbers[0], array);
findNumber(findTwoNumbers[1], array);
}
main();
Easy beasy, isnt,it? We just separate the search of numbers in another function. Now we can reuse in another parts of project or modules.
KISS - Keep It Simple, Stupid!
This principle says that every code should be simple as possible. Also states that there is no value in a solution being “smart”, but rather in it being easily understandable.
This is because developers are often tempted to write “smart” solutions that use complex resources. In this case, a solution is better when using less inheritance, less polymorphism, fewer classes, etc.
But let's see a simple
example to validate and leave an array with unique numbers and sort
.
function selectionSort(arr: number[]) {
for (let i = 0; i < arr.length; i++) {
let indexMin = i;
for (let j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[indexMin]) {
indexMin = j;
}
}
if (indexMin !== i) {
let lesser = arr[indexMin];
arr[indexMin] = arr[i];
arr[i] = lesser;
}
}
return arr;
}
function uniqueSortArray() {
const array = [1, 2, 1, 2, 3, 3, 10, 5, 3, 1];
const newArray = array.filter(
(value, index, self) => self.indexOf(value) === index
);
const sortedArray = selectionSort(newArray);
console.log(sortedArray);
}
uniqueSortArray();
Complicated? Yes! Problably for people that don't know about the helpers functions of Javascript it's ok!
But with ES6 we know that this function can be more simple!
Let's see:
function uniqueSortArray() {
const array = [1, 2, 1, 2, 3, 3, 10, 5, 3, 1];
const sortedArray = [...new Set(array.sort())];
console.log(sortedArray);
}
uniqueSortArray();
Woooooow! Gosh! It's turn a lot of more simple!!!!
Just using the functions of ES6.
Amazing isn'it?
YAGNI - You Aren’t Gonna Need It
The last principle, is another widely adopted principle of software development that states that features should only be added when necessary.
The argument is that developers don't waste time creating extraneous elements that may not be necessary and could hinder or slow down the development process.
Let's create a simple
example just to understand:
interface Animal {
walk(): string;
noise(): string;
makeWalkAndNoise?: VoidFunction;
}
class Dog implements Animal {
walk(): string {
return "Dog is Walking";
}
noise(): string {
return "rouf rouf";
}
}
Notice that the method makeWalkAndNoise
is not beeing used.
And if will not be used and very class instanciation, probably we don't need these method.
interface Animal {
walk(): string;
noise(): string;
}
class Dog implements Animal {
walk(): string {
return "Dog is Walking";
}
noise(): string {
return "rouf rouf";
}
}
And that's it! Just remove and turn simple. And remember of the ISP (Interface Segregation Principle) of SOLID?
A class should not be forced to implement interfaces and methods that will not be used.
We can see the same principle here in this example.
And that's it folks!
I hope you liked! (And be famous as the previous article lol)
Thank you so much and Stay Well Always!
Contacts:
Linkedin: https://www.linkedin.com/in/kevin-uehara/
Instagram: https://www.instagram.com/uehara_kevin/
Twitter: https://twitter.com/ueharaDev
Github: https://github.com/kevinuehara
dev.to: https://dev.to/kevin-uehara
Youtube: https://www.youtube.com/@ueharakevin/
Posted on May 17, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.