0% found this document useful (0 votes)
95 views

Clean Code

Clean Code

Uploaded by

sumit.kumar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
95 views

Clean Code

Clean Code

Uploaded by

sumit.kumar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 8

Clean Code — Object Calisthenics in Javascript

Mostly, developers will spend their time working on the code. And to be able to work efficiently we
need to understand the code. That’s why we can follow one of the good practices on Software
Development called the Clean Code.

Clean Code is code that is easy to understand and easy to change

We do clean code because we know that code is written and will have changed from time to time, not
by only us but also by the future developers. Because other developers also need to understand the
code we have written, we need to make sure that our code can be easily understood by others. And
essentially making life easier for everyone involved in our codebase.

With many code reviews and many projects with different code conventions, of course, we need to have
some rules that can be implemented across all codebase and help us to achieve clean code. And also as
most high-level programming languages such as C, Java, Javascript can implement OOP or Object
Oriented Programming concepts, We can create a codebase/project which follows both Clean Code and
OOP concepts properly. It’s called Object Calisthenics.
Object Calisthenics are basically programming exercises, as a set of 9 rules to help us write better Object
Oriented code

1. Only One Level Of Indentation Per Method

2. Don’t Use The ELSE Keyword

3. Wrap All Primitives And Strings

4. First Class Collections

5. One Dot Per Line

6. Don’t Abbreviate

7. Keep All Entities Small

8. No Classes With More Than Two Instance Variables

9. No Getters/Setters/Properties

Keep in mind that these 9 rules are heavily oriented on OOP Concepts done in Java (before Java 8),
therefore there are some of the rules probably cannot be applied “as is” in other programming
languages and paradigms. If you already write code that is maintainable, readable, testable, and
comprehensible, then these rules will help you write code that is more maintainable, more readable,
more testable, and more comprehensible. Here, the provided example will be on Javascript ( Node JS ).

Rule 1: Only One Level Of Indentation Per Method

If you have various conditions at different level, or a loop in another loop or a function which have more
than one indentation, you can always simplify it or extract it‌

This rule will make us think about how to ensure that each method does exactly one thing — one
control structure or one block of statements per method. If you have nested control structures in a
method, you’re working at multiple levels of abstraction, and that means you’re doing more than one
thing.

conditional structure in here are things such as if or switch case or ternary operation

if there are conditional structure inside other control structure, it is better to simplify it or extract it to a
separated function

Example Rule 1 Conditional — Simplify the logic

In here, we can simplify the logic by merging line number 6 and line number 7 into

Ok, then what happens if we have a long if because we simplifying more than one of the nested
conditional (ex: a && b && c)? we can extract it to a boolean variable and give more context to it
...
const isLowHealth = healthPoint > 0 && healthPoint < 50;
if (isLowHealth) {
...

looping structure in here are things such as for or for in/for of or even iteration on the array, such
as .forEach, .filter, .map and etc.

Example Rule 1 Loop — Extract method

we can extract the two for-loop inside to two more separated functions.

The benefit:

 by simplifying the conditional, it will be easier to understand

 by split it to more functions, we can give better naming and context as what the function does
(better documentation)

 the new functions can be reused on other function

 give more clarity as we now have a single name for the index on every function instead
of index, secondIndex, and thirdIndex

Rule 2: Don’t Use The ELSE Keyword

We can remove else keyword easily by using early return / guard clause

Well, are you surprised about this rule? yes, it is one of keyword that we will learn first when jumping to
programming. Actually, we never need an ELSE keyword. An easy way to remove the else keyword is to
rely on the early return solution. Other solutions which a little bit hard are the polymorphism concept or
State Pattern or Strategy Pattern or Null Object Pattern

Example Rule 2 — Early Return

A guard clause is a snippet of code at the top of a function or method that returns early when some
precondition is met. Therefore, we can make sure the lower code or blocks outside the if will not be
called. We can also do if-block on top to eliminate condition using return/throw, so it won’t go down to
execute the main part of the function.

If we refactor it to do early return, it will become this:

Benefit:

 reduce complexity (or increase the readability of the logic flow)

 reduce unwanted variables if previously you do only a single return on the last part of the
function.
 possibly reduce duplication on more complex if / conditional logic

Rule 3: Wrap All Primitives And Strings

every variable with type that was not written by yourself is primitive, and you should encapsulate them
to a class by their behaviours.

This rule focus on avoiding one of the code smells Primitive Obsession. Every variable which is a
primitive data type like integer, float, string, array, map, or object literal ( {} ) even in a dynamic-type
language like javascript, we need to wrap them to a class / more classes, we can also combine two or
more variable which has related behavior and can represent a real-world things/concepts inside a class.
Let’s take this example

kilometer and meter can be represented to a real-world example — Distance. And we can create a class
to represent the value, and give the proper properties and behavior.

We can go further by wrap things like the “kilometer” string to a class called Unit, and if things like
kilograms, grams, or any other measurement need to be used on our code, we can also make a more
general class called Measurement instead of Distance.

Benefit:

 give better context with additional information about what the value is and why it is being used

 enforce encapsulation and abstraction

Rule 4: First Class Collections

Every collection should be contained or wrapped in its own class

This is still related in rule 3 to wrap all primitives. Collections in javascript are like Array -[] , Map or Set,
or other Data Structures which are possibly created by some other library. We need to make sure every
class that has a collection shouldn’t have any other members inside the class. If this happens, we need
to make them to a new class and every possible action/behavior that we need on the collections (push,
remove, filter, sort, etc) should be put as methods of this first-class collection. For the naming part,
instead of giving its name as the plural form of what object that it can hold (Person & Persons), we can
give a better name that represents its domain.

Let’s say we have a Player class.

And then we have Match class

And this is how we use Player and Match class in the main class

You can see that in Match class we have a member of the collection called terrorists but also another
member which is a collection called counterTerrorists . Both of them are holding Player object. By
following the rule, we need to extract this array of Player, to a new class that only hold this array, the
best for this context is a Team just like how we called it in-game, Terrorist team and Counter-terrorist
team. So here is the updated Match class after we change the primitive collection to the first-class
collection of Team.

Here’s our new Team class that hold of the array of players, we also put the related behavior of the
array which are the addition of a member and the sorting of the members into methods
of add and sortByKillCountDescending

Benefit:

 possibly prevent duplication of code related to the collections

 enforce encapsulation

Rule 5: One Dot Per Line

you should not chain method calls which doesn’t have the same context or return type

Let’s see this example directly

We can see that line number 4 is actually long. Method calls that are too long can distract programmers
as they will not know where that long method calls can fail or throw errors, and that’s why we need to
split it. So by adding enter on every dot is the way to fix this? The answer is NO, we split the long
method calls to a new variable And you only can do the chaining method only if you do Method Chaining
Pattern (e.g. a Query Builder). We can split them into a new variable if the chaining methods don’t
return the same type or not having the same context. Here is some example of how we can find a way to
correctly split it

rawText.trim() // return string. AcceptablerawText.trim().toUpperCase() // return string. Still


AcceptablerawText.trim().toUpperCase().replace('YOU', username) // return string. Still
AcceptablerawText.trim(),toUpperCase().replace('YOU', username).split(' ') // return array, has violated
one dot per line rule

let’s now split the dot which still returns strings to a new variable

const textWithUsername = rawText.trim().toUpperCase().replace('YOU', username);

continue with the one dot per line check

textWithUsername.split(' ') // return array. become AcceptabletextWithUsername.split('


').reduce((result, item) => ({ ...result, [item]: item }), {}); // return object, has violated one dot per line
rule

by again splitting the dot which still returns an array to a new variable, the final code of this will become:

Ok, if you find it’s still too long, you can follow some convention that you can put enter after every dot
just to prettify the code.
Benefit:

 better to track for errors / easier to debug

 can put better naming for the split variables (increase readability)

Rule 6: Don’t Abbreviate

put better naming for your variable / class, don’t abbreviate them

We used to put an abbreviated name for the variable, in projects, it will sometimes get harder to know
what the abbreviation stands for and you even put more meaningless variables like x, n, t like in
competitive programming format. The code you write will be used by others, and we should make sure
they also understand it. It won’t hurt us to take one or more extra minutes to give better naming for
them.

in here, we can change temp, i and n as it is abbreviated, and change it to this:

Benefit:

 reveal the intention of the variable

Rule 7: Keep All Entities Small

s‌ tick to choose rules like function with less than 10 or 15 lines and also classes with less than 50 lines.
Start to always refactor your code based on each function / class responsibility (SRP — Single
Responsibility Principle)

The actual rule is “No class over 50 lines and no package over 10 files”. But if you have tried to follow
other rules, you will always have a small class/function as a result. So, if you have stumbled upon some
of your code has more than 15 lines on one function or more than 50 lines on one class. It is a sign that
you should start implementing the other rules. Or even start thinking about how to implement some
software design patterns on your code. Things to note here is if it’s more than what the rule said
because you have many lines of boilerplate code on it, it’s your own call whether to fully stick with these
rules or not.

Benefit:

 help other developers to not become overwhelmed with too many lines of code in one file ( it
won’t scare them to change it / refactor it)

 less of class with no specific behavior / single responsibility (God Class / Blob Class)

Rule 8: No Classes With More Than Two Instance Variables

‌ ecompose all of your classes and make each of them to only have two instance variables / attributes (or
d
state / props in some framework)
Yes, I know this will be hard for us to stick with this rule in a class/object whose main purpose is to
save/show data like Entity / DTO in java. So, it’s your own call to how many minimum instance variables
that a class can hold, maybe stick with only three? The tip to follow this rule is to take two of the
instance variables that are related to each other and can be extracted out with a responsibility/behavior
or have a real-world representation, wrap it into a class.

If choosing from real-world representation on the usual way of parents give a name to their child, first
and the middle will be a given name ( or even a third/fourth name), and the last name will be a surname
or inherited family name. We can change it to this:

This way, we can even put the third or fourth name of it as GivenName accept more than one parameter
on its constructor, the usage example is:

const givenName = new GivenName('Davidsen', 'second', 'third');


const surname = new Surname('Satio');
const Name = new Name(givenName, surname);

Benefit:

 help to create a class which we can add more functionality on it as we have cleared out what
responsibility it has ( open-closed principles )

 having complex large objects become much simpler models.

Rule 9: No Getters / Setters / Properties

Tell Don’t Ask, remove all your setters and getters, start creating functions that process and return the
data that you need.

This rule is the most controversial of all rules because we usually put getters/setters when we learn basic
OOP. This habit continues by us always using these getters/setters everywhere just to do simple things,
and sometimes, it even breaks encapsulation.

To eliminate this habit, we need to force the new habit of providing functions that make sense. Tell
Don’t Ask is the key, If we have found that we do a job/decisions outside an object by getting its state,
we should move it inside the object who originally hold the state. Any decisions based entirely upon the
state of one object should always be made ‘inside’ the object itself.

To try to implement this rule, we can first start by eliminating all the setters. If you want to set the initial
value of a state/properties of a class, you can put it on the constructor. On line 20, we want to add 2000
to the wallet balance, which made the decision on getting the last value by using getter and then add
2000 outside the wallet class. Instead, we can create a function on the wallet which are more straight-
forward
increase(money) {
this._balance += money;
}

Ok. now we need to check about getters. it’s ok to use getters to get the state of an object, but only if
it’s needed by other parts/class. If you want to check whether the value of the object is the same with
another object, you can introduce .equals. In this context, things left is to print out the last state of the
wallet (with its balance), for this, we can actually introduce a .toString() function to print out the last
state of the balance. The final code then will become this:

Benefit:

 not breaking encapsulation of a class

 significant reduction in duplication

 open for more chances to implement new features.

 keep in check on the read-only state of the class

 no overused of setters/getters, only keeping the needed one based on the requirement

You might also like