Good programmers are the ones who explain what they do in the most simple way they can. Even physicists explain wormholes with a piece of paper and a pencil pinned in it. What makes us different?
I have always tried to write my code as simply as I could, everything from picking the right name for a variable to using code conventions, but something was still missing, a way to understand the code without trying to understand the “how” I did it, but rather the outcome I was trying to achieve.
You might even say the ability to read the code as a story, rather than a bunch of code.
Let’s address 3 main topics:
The Problem
Reading other programmers code can be a real struggle. Without providing the proper context one can simply find him/herself lost in finding the meaning of a function or a property.
The Suggestion
From 1’s and 0’s to low-level code to elite languages, it is noticeable that code syntax becomes more and more user-friendly, thus inviting new programmers to the developer’s universe. As the syntax becomes clearer to read in plain English so should our code be, simple,to the point, and self-explanatory.
The Outcome
A well written code that masks itself as a story, making it easy to read and understand (even without context).
_
Naming Functions
How to do it the right way:
When we write function we assume that the person reading the function has enough context to understand what we were trying to achieve. Naming our function in a vague way “handleRedView()” will raise many questions about what “RedView” stands for? What is the main goal of this function?.
It seems that in some cases the function's purpose is vague and too complicated to understand without providing context.
We can separate our function proposes into 4 categories:
1. Informer functions
2. Management functions
3. Router functions
4. Execution functions
1. Informer function
Usually triggers router/management functions.
function examples:
1 delegate.dataHasUpdated()
2
3 func dataHasUpdated()
4 {
5 //Someone is informing you that something has happened
6 }
1 // Informer Functions
2 override func engineStarted()
3 {
4 super.engineStarted()
5 handleCarStarted()
6 }
Call back function, inform that something did/will happen and gives you the option to react.
Mostly used as delegate triggered actions, or notification handling functions .
2. Management function
Used to unite multiple function to achieve 1 higher purpose without dependency, all the code inside the block will execute.
1 // Management Function
2 func handleCarStarted()
3 {
4 turnLights(on: true)
5 turnAC(on: true
6 }
Reading this function we have all the information we need, execute this functions when the car has started, at this point we don’t care “how” its done rather the “what” it does.
3. Router function
Used to unite multiple functions to achieve 1 higher purpose with some sort of dependency, the code will execute only when intended to.
1 // Router Function
2 private func turnLights(on shouldTurnLightsOn: Bool)
3 {
4 if shouldTurnLightsOn
5 {
6 turnExteriorLightsOn()
7 checkForBurnedBulbs()
8 }
9 else { turnExteriorLightsOff() }
10 // When an if statment has only 1 thing to execute i like to write it
11 // at the same line with the "if" "else" word, it makes reading your code more fluent.
12 }
Router function mostly points to execution functions but in some cases can include logic itself only if the code won’t exceed 1 line.
4. Execution function
The implementation of the function name.
1 // Execution Function
2 private func turnExteriorLightsOn()
3 {
4 leftFrontLight .isOn = true
5 rightFrontLight .isOn = true
6 leftBackLight .isOn = true
7 rightBackLight .isOn = true
8 }
9 private func checkForBurnedBulbs()
10 {
11 for lightBulb in bulbs where !lightBulb.isUseable
12 {
13 Dashborad.display(errorType: .lights)
14 break
15 }
16 }
The logic itself could potently be complicated to understand but we already declared what the function does in the name, the function turns exterior lights on, the