20 stories with 5 code smells each are 100 code smells, right?
Let's continue...
You don't own objects.
TL;DR: don't use my as a name prefix.
Several old tutorials use the word 'my' as a lazy name. This is vague and lead to context mistakes.
MainWindow myWindow = Application.Current.MainWindow as MainWindow;
MainWindow salesWindow = Application.Current.MainWindow as MainWindow;
/*
Since window is instanciated, we are currently working
with a specialized window playing a special role
*/
We can tell our linters and static checkers to search for this prefix and warn us.
Avoid using my. Objects change according to the usage context.
Photo by Michał Bożek on Unsplash
Thinking about my experience of modifying code, I see that I spend much more time reading the existing code than I do writing new code. If I want to make my code cheap, therefore, I should make it easy to read.
Kent Beck
Software Engineering Great Quotes
We should take special care with error descriptions for the users (and ourselves).
TL;DR: Use meaningful descriptions and suggest corrective actions.
Programmers are seldom UX experts.
We also underestimate the fact we can be on both sides of the counter.
alert("Cancel the appointment?", "Yes", "No");
// No consequences
// Options not clear
alert("Cancel the appointment? \n" +
"You will lose all the history",
"Cancel Appointment",
"Keep Editing");
// Consequences are clear
// Choice options have context
We need to read all exception messages in code reviews.
We need to think in our end users when raising exception or showing messages.
While it is a known fact that programmers never make mistakes, it is still a good idea to humor the users by checking for errors at critical points in your program.
Robert D. Schneider
Spelling and readability are very important for humans and not important for machines.
TL;DR: Take care of your names.
Many of us don't speak English as our first language.
We need to have extra care for our texts and names.
This article has a typo in its title as proof of context and also a clickbait😀
comboFeededBySupplyer = supplyer.providers();
comboFedBySupplier = supplier.providers();
Pay close attention to your names.
You will probably be the person reading the code in a few months.
Code Smell 48 - Code Without Standards
What exactly is a name — Part I The Quest
What exactly is a name — Part II Rehab
Photo by Brett Jordan on Unsplash
Inside every well-written large program is a well-written small program.
C.A.R. Hoare
How many times do we see lazy argument names?
TL;DR: Name your arguments according to the role and not the accidental position
When writing methods, we usually don't stop to find decent names.
We never refactor the obvious, neither.
class Calculator:
def subtract(self, first, second):
return first - second
class CalculatorTest
def test_multiply():
assert equals(first, second)
class Calculator:
def subtract(self, minuend, subtrahend):
return minuend - subtrahend
class CalculatorTest
def test_multiply():
assert equals(expectedValue, realValue)
We can warn for forbidden words like 'first' and 'second' as argument names.
Always follow rule suggesting parameter.
Name your collaborators according to the role.
Code Smell 65 - Variables Named after Types
What exactly is a name — Part II Rehab
Photo by Priscilla Du Preez on Unsplash
Final source code is the real software design.
Jack Reeves
GOTO was considered harmful 50 years ago
TL;DR: Don't ever use GoTo.
I started programming in Basic.
GOTO was heavily abused there.
I had to learn structured programming from scratch in Rehab mode.
for x < 0 {
if x > -1e-09 {
goto small
}
z = z / x
x = x + 1
}
for x < 2 {
if x < 1e-09 {
goto small
}
z = z / x
x = x + 1
}
if x == 2 {
return z
}
x = x - 2
p = (((((x*_gamP[0]+_gamP[1])*x+_gamP[2])*x+_gamP[3])*x+_gamP[4])*x+_gamP[5])*x + _gamP[6]
q = ((((((x*_gamQ[0]+_gamQ[1])*x+_gamQ[2])*x+_gamQ[3])*x+_gamQ[4])*x+_gamQ[5])*x+_gamQ[6])*x + _gamQ[7]
return z * p / q
small:
if x == 0 {
return Inf(1)
}
return z / ((1 + Euler*x) * x)
}
for x < 0 {
if x > -1e-09 {
return small(x, z)
}
z = z / x
x = x + 1
}
for x < 2 {
if x < 1e-09 {
return small(x, z)
}
z = z / x
x = x + 1
}
if x == 2 {
return z
}
x = x - 2
p = (((((x*_gamP[0]+_gamP[1])*x+_gamP[2])*x+_gamP[3])*x+_gamP[4])*x+_gamP[5])*x + _gamP[6]
q = ((((((x*_gamQ[0]+_gamQ[1])*x+_gamQ[2])*x+_gamQ[3])*x+_gamQ[4])*x+_gamQ[5])*x+_gamQ[6])*x + _gamQ[7]
return z * p / q
small(x, z) {
if x == 0 {
return Inf(1)
}
return z / ((1 + Euler*x) * x)
}
}
In languages supporting GOTO, our linters can warn us against its usage.
We acknowledged GOTO problems a few decades ago.
The problem is still present in modern languages like GoLang, PHP, Perl etc.
Most programmers luckily avoid GOTO sentence. Next goal will be to consider harmful null usage.
Courtesy XKCD
Photo by Jens Johnsson on Unsplash
It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration.
Edsger Dijkstra
Software Engineering Great Quotes
And that’s all for now, We have hit 100 milestone.
The next article will explain 5 more code smells!