If you want one of the best books that will help you become a better programmer, try this one: Clean Code: A Handbook of Agile Software Craftsmanship
And you can watch me try to apply some of the principles I got from the book in this video:
Disclaimer, I haven't read all of the book, because it kind of stopped me on the TDD, which is something I don't really do since I was never asked to do this in the first place. Come to think about, last year was the first time I've written any tests for an application, on a project in the forth company I've been working for.
But anyways, here are some rules and quotes I found interesting and which you can follow whenever you want to write new code.
Naming is very important
One difference between a smart programmer and a professional programmer is that the professional understands that clarity is king. Professionals use their powers for good and write code that others can understand.
Whoever is reading your code should feel like he's reading a story and understand what your program is doing by just reading the variable, function, class names.
This means that you should:
Avoid single letter variables, and use intention-reavealing names
ex: forget about var t
(or single letter variables in general) and use var time
Use pronounceable names
ex: getClassroomStudents
vs getClsStuds
This means that the names are searchable and easy to find in your code
you can still use single letter variables, in for loops, for example `for(let i = 0;...)
Class names should be a noun or noun phrase; also, don't use verbs as names
ex: use Customer, Product, ProductPage; avoid using words like Manager, Processor, Data or Info in the class names
Method names should use verbs and accessors, mutators and predicates should be prefixed with get and set with their value
ex: sendMessage
, getName
, setName
One word per concept meaning you shouldn't use multiple words describing the same concept
ex: get
, fetch
, retrieve
used for getting data; just pick one and stick with it
Add meaningful context when there can be confusions made;
ex: state
might make sense when it's together with city, country, etc. but might be confusing when used alone. You can add the info in a class or object or even prefix them with the word address
Shorter names are better than long one as long as they are clear; don't add gratuitous context
ex: if your app is named Featuring Code App, don't add FCA in front of every class
Functions
The first rule of functions is that they should be small. The second rule of functions is that they should be smaller than that.
The reason we write functions is to decompose a larger concept.
Blocks and indenting
The blocks within if/else/while statements should be one line long; This line should probably be a function call with a nice descriptive name.
The functions should not be large enough to hold nested structures and the indent level of a function should not be greater than one or two.
Do One Thing
You can have functions that call other functions and so on, if they serve the main goal of that function. If the function does coupled steps that are one level below the stated name of the function, then the function is doing one thing.
You can tell if your function is doing more than one thing if you can extract other functions from it that with a name that is not merely a restatement of its implementation.
To me, for example, this function is adding an element but doing two different things: creating a div with contend and appending the div
function addElement () {
// create a new div element
const newDiv = document.createElement("div");
// and give it some content
const newContent = document.createTextNode("Hi there and greetings!");
// add the text node to the newly created div
newDiv.appendChild(newContent);
// add the newly created element and its content into the DOM
const currentDiv = document.getElementById("div1");
document.body.insertBefore(newDiv, currentDiv);
}
How I would make addElement do one thing is by renaming it and creating two new functions
function addNewDivWithContentBeforeDiv1() {
const newDivWithContent = getNewDivWithContent();
addHtmlElementBeforeDiv1(newDivWithContent);
}
function getNewDivWithContent() {
const newDiv = document.createElement("div");
const newContent = document.createTextNode("Hi there and greetings!");
return newDiv.appendChild(newContent);
}
function addHtmlElementBeforeDiv1(element) {
const div1Element = document.getElementById("div1");
document.body.insertBefore(element, div1Element);
}
And before jumping to conclusions, OF COURSE I would have made the functions reusable, by accepting parameters and renaming the functions to addNewDivBeforeIdIdentifiedElement(newDivContent, id)
and addElementBeforeIdIdentifiedElement(htmlElement, id)
Sections within Functions
Functions that do one thing cannot be reasonably divided into sections.
Reading Code from Top to Bottom: The Stepdown Rule
The code should read like a top-down narrative. Each function should be followed by those at the net level of abstraction, descending one level of abstraction at a time as we read the code.
The code should read like adding the word "to" in front of a paragraph
*ex: TO add a new div with content before div 1 we get a new div with content and then add the new div before the div 1
TO get a new div with content we create a new div, then create new content and return this new div
TO add a new div before the div 1 element we get the div1 element and then insert the new div before it *
Use Descriptive Names
Don't be afraid of long names. Although(this I got from the online lectures), the broader the scope of the function, the shorter the name (ex: start() or init()) and the more focused the function is, the longer the name.
Verbs and Keywords
Verbs should express the intent of a function. For example write(name)
tells us that a thing
called name is being written, but writeField(name)
tells us that the name is actually a field.
Function Arguments
The ideal number of arguments for a function is none, followed by one, two and three. You can also pass an object if you have multiple arguments.
Don’t Repeat Yourself
Move repeatable code inside functions and call those functions instead.
Comments
Don't comment bad code - rewrite it
You should avoid writing comments all together, because the code should explain itself by the way it is written. Also, comments might become obsolete while the code functionality changes, which creates more confusion for the colleague working on the new code.
Some comments can be good, for example, explaining some abstract methods from some libraries.
Objects
Objects expose expose behaviours and hide data
The Demeter law
Don't talk to strangers. - which means that you should access data only from the direct children of an object and not by talking to children of children;
ex: ob.methodA() - is good
, ob.methodA().methodB() or ob.a.b; - is bad
The book has 450+ pages so if you want to get deep into the rules, you can find it here Clean Code: A Handbook of Agile Software Craftsmanship