I’ll give you a quick summary of some software development principles and software design related terms with a brief description.
You should be familiar with the following by the end of this blog post.
- What is the DRY principle and what are some real-world examples?
- What is the KISS principle and how does it apply in real life?
- Finally, I will use an example to explain the YAGNI principle.
Aside from design patterns, we adhered to some design principles, such as the solid, YAGNI, and dry principles. In this blog post, I will use real-world examples to demonstrate how to apply these principles, such as Yagna, Dry, and Solid.
What is good software?
Good software must meet the following conditions:
- Operational
- Transitional
- Maintenance
Why Software Design Principles
To handle the frequent change in user requirements, we need the software design principles. These principles reduce dependencies so that developers can change one area of software without affecting others. They are also intended to make designs easier to understand, maintain, and extend.
SOLID Principles
This is an abbreviation for five Object-Oriented design principles.
- Single Responsibility Principle.
- Open/Closed principle.
- Liskov Substitution principle.
- Interface Segregation Principle.
- Dependency Inversion principle.
Tight Coupling
Tight coupling (in general) occurs when two things rely on one another, i.e., changing one may have an effect on the other.
Loose Coupling
Loose coupling occurs when two things are dependent on one another, implying that changing one may have little or no effect on the other. The goal of a loose coupling architecture is to reduce the risk that a change made in one element will cause unanticipated changes in other elements.
Dependency Injection
In software engineering, dependency injection is a technique whereby one object (or static method) supplies the dependencies of another object. A dependency is an object that can be used (a service).
Mock
Mock objects are simulated objects in object-oriented programming that mimic the behaviour of real objects in controlled ways, most often as part of a software testing initiative. A mock object is typically created by a programmer to test the behaviour of another object.
Spy
Mock and Spy are both used to fake or mimic the behaviour of an object, but in spy, there is a real object and you are simply spying or stubbing specific methods of it.
DRY(Don’t Repeat Yourself)
Don’t Repeat Yourself is an abbreviation. It entails refactoring code that is reused several times. DRY code is simple to modify since all changes must be made in one place.
Have a glance at the following code fragment. I’m checking for the even or odd number in the specified array. But for if(array[i] percent 2!==0), the rest of the code is duplicated. This is obviously against the DRY principle.
const printOdd=(array)=>{
for(let i=0;i<array.length;i++){
if(array[i]%2!==0){
console.log(array[i]);
}
}
}
const printEven=(array)=>{
for(let i=0;i<array.length;i++){
if(array[i]%2===0){
console.log(array[i]);
}
}
}
printOdd([1,2,3,4,5]);
printEven([1,2,3,4,5]);
Let’s refactor the code and apply the DRY principle.
DRY Code
const printNumbers=(array,cb)=>{
for(let i=0;i<array.length;i++){
if(cb(array[i])){
console.log(array[i]);
}
}
}
printNumbers([1,2,3,4],(x)=>x%2!==0); // odd numbers
printNumbers([1,2,3,4],(x)=>x%2===0); // even numbers
KISS- Keep it Simple, Stupid
This principle states that your code should be as simple as possible. You should avoid overcomplicating things. A simple code is easier to understand and maintain.
Let’s look at some real-world examples to better understand this principle.
Example 1
I’m merging the two arrays into a single array in the following code snippet. This code is fine, but we can simplify it by using the new javascript operator spread.
const even = [2,4,6]
const nums = [10,12,16].concat(even); // 10,12,16,2,4,5
After applying the KISS principle
const even = [2,4,6]
const nums = [10,12,16,...even]
We could use the spread operator in any situation (beginning, end, middle)
Example 2
The example below is self-explanatory. Here, I’m checking to see if the variable is defined and then making a decision. This code is quite verbose, and we can simplify it by utilising the “short circuit” technique.
Short-**Circuit Code-**n some programming languages, the second argument is only executed or evaluated if the first argument does not suffice to determine the value of the expression.
function checkName(name) {
if (name === null || name === undefined || name === "") {
console.log("name not defined!");
} else {
console.log(name);
}
}
checkName();
The code above is fairly common, so let’s put it to good use.
function checkName(name) {
console.log(name || "name not defined!");
}
checkName();
Example 3
Consider the following scenario. In the code below, I’m making an ajax request and using a “Promise”-based API. Things can get nasty when we use multiple nested promises.
const getData = (url) => {
return $.getJSON(url)
.then((data) => {
console.log(data);
})
.catch((err) => {
console.log(err);
});
};
getData("https://jsonplaceholder.typicode.com/todos/1");
This promise-based code will be transformed into an async/await code block as shown below. Which is very clear and simple to understand.
const getData = async (url) => {
try {
const data = await $.getJSON(url);
console.log(data);
} catch (err) {
console.log(err);
}
};
getData("https://jsonplaceholder.typicode.com/todos/1");
YAGNI
YAGNI stands for “you aren’t gonna need it”: don’t implement something until it is necessary.