Software Architecture

Clean Code

One of the objectives of the all challanges is to write clean code. Clean code is a code that is easy to read, understand and change. In order to write clean code, you need to follow some rules. These rules explain in detail in challanges.

  • Writing a complicated code is not a good thing. Try to write simple code. (Good comments, small functions, no over abstraction etc.)

Styling and Formatting

A code can be seen unclear if it is not formatted correctly. Formatting covers spaces, tabs, new lines, semicolons etc. A code formatter is a tool that automatically formats your code. Formatting means changing the code style. For instance, you can use a code formatter to change

  • all double quotes to single quotes
  • all tabs to spaces
  • all semicolons to no semicolons

or any other code style. A code formatter is a tool that you can use to format your code. It is a good practice to use a code formatter. It will help you to keep your code clean. However, please do not forget that you need to setup your code formatter correctly. Also, different code formatting rules across different projects can be a problem. So, you need to add a configuration file to your project in order to keep your code style consistent. Also, configuration file should be under version control. So, all developers can use the same code style.

Naming

Naming: You should be careful about naming. You should use meaningful names for your variables, functions, classes etc.

Comments

Your comments should be as short as possible. You should write comments to explain your code but in general your code should be self-explanatory. You should not write comments that are not needed. You can explain algorithms, data structures, design patterns etc. in your comments. You should not write comments that are explaining what your code does. Instead, your code should explain what it does in a clear way.

Nesting

You should avoid deeply nested code. You should use early returns to avoid nested code.

Immutablity

One of the most bug-prone parts of a code is mutable variables (or variables). Because, you can change the value of a variable at any time from any place. This can cause a lot of bugs. In order to avoid these bugs, you should use immutable variables as much as possible. Instead of using let and var, you should use const in order to make your variables immutable. Also, you should avoid mutating objects and arrays. You should use map, filter, reduce functions to manipulate arrays.

Also you should be careful about scoping. Because scopes can restrict the usage of a variable. If you are defining a variable in a global scope, you can use it from anywhere. This can cause a lot of bugs. For this reason, please try to use local variables as much as possible and keep your scopes as small as possible.

It may be seem to be impossible to avoid mutable variables. However, you can use some techniques to avoid them. For instance, you can use Map, Filter and Reduce functions can be used. They are higher order functions which means that they take a function as an argument and they return a new array. These functions are very useful and they are reduces the need for loops and mutable variables. You should use these functions as much as possible. Also there are some other functions in javascript that you can use to manipulate arrays. For instance, forEach, some, every, find, findIndex etc. You should use these functions as much as possible. Also, you can use lodash library to manipulate objects and arrays.

Also, you should return results of a function with return statement. Mutating a global variable and then reading it from another function is a bad practice. Instead of that, you should return the result of a function with return statement. This will make your code much more clear and easy to understand.

If you want to learn more about immutability, you can check Functional Programming Paradigm.

Pure Functions

There is a difference between functions in mathematics and functions in programming. In mathematics, a function is a relation between a set of inputs and a set of possible outputs. Therefore, a function satisifies two properties:

  1. A function should return the same output for the same input.
  2. A function should not have side effects.

However, in programming, a function can have side effects and it can return different outputs for the same input. For instance, a random number generator function is a function that returns different outputs for the same input. It does not take any arguments but it returns a different output each time you call it. (If it would be a function in a mathematical sense, it should return only one value because it does not take any arguments.) Also, a function that prints something to the screen is a function that has side effects. It does not return anything but it changes the state of the screen. The functions that satisfy these two properties are called pure functions.

In some functional programming languages, all functions must be pure functions (such as Haskell). However, in JavaScript, you can use pure functions as much as possible. Pure functions are very useful because they are easy to test. You can test a pure function by giving it an input and checking the output. If the output is the same as you expected, then the function is working correctly. Also, pure functions are easy to understand and most importantly, they are easy to compose. Therefore, building complex systems with pure functions is much easier than building them with impure functions. Because, they are garantueed to work correctly for each individual function and composing them will not result any unexpected behavior.

Map, Filter, Reduce

Extra Resources

https://youtu.be/CFRhGnuXG-4?si=dOHjdiMcc5xxgEuM