How to Find The Stinky Parts of Your Code [Part XV]
source link: https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xv
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
I’m senior software engineer specialized in declarative designs and S.O.L.I.D. and Agile lover.
Infinite code smells!
We see several symptoms and situations that make us doubt the quality of our development.
Let's look at some possible solutions.
Most of these smells are just hints of something that might be wrong. They are not rigid rules.
Previous Code Smells
Let's continue...
Code Smell 71 - Magic Floats Disguised as Decimals
TL;DR Don't trust numbers on immature languages like JavaScript.
Photo by Stephen Radford on Unsplash
Problems
Solutions
Choose Mature Languages.
Represent Decimals with Decimals.
Sample Code
Wrong
console.log(0.2 + 0.1)
// 0.30000000000000004
//We are adding two decimal numbers
// 2/10 + 1/10
// Result should be 3/10 as we learnt at school
Right
class Decimal {
constructor(numerator) {
this.numerator = numerator;
}
plus(anotherDecimal) {
return new Decimal(this.numerator + anotherDecimal.numerator);
}
toString() {
return "0." + this.numerator;
}}
console.log((new Decimal(2).plus(new Decimal(1))).toString());
// 0.3
//We can represent the numbers with a Decimal class (storing only the numerator)
//or with a generic Fraction class (storing both the numerator and denominator)
Detection
Since this is a language feature, it is difficult to detect. We can ask our linters to prevent us from manipulating numbers this way.
JavaScript
Premature Optimization
Conclusion
My first programming language was Commodore 64's basic back in 1985.
I was very surprised to discover that 1+1+1 was not always 3. Then they introduced integer types.
JavaScript is 30 years younger, and it has the same immaturity problems.
More info
Here is the technical (and accidental) explanation:
https://blog.pankajtanwar.in/do-you-know-01-02-03-in-javascript-here-is-why
Please, don't argue telling this is fine and expected since this is the binary representation.
These numbers are decimals, we should represent them as decimals. If you think representing them as floats is a great performance improvement, you are wrong. Premature optimization is the root of all evil.
Floating Point Standard - 83 pages
The purpose of computing is insight, not numbers -Richard Hamming
Code Smell 72 - Return Codes
APIs, Return codes, C Programming Language, We've all been there.
Photo by Alex Hay on Unsplash
TL;DR: Don't return codes to yourself. Raise Exceptions.
Problems
Code Polluting
Outdated documentation
Coupling to accidental codes.
Functional logic polluted.
Solutions
Change Ids and return Generic Exceptions.
Distinguish Happy Path from Exception Path.
Sample Code
Wrong
function createSomething(arguments) {
//Magic Creation
success = false; //we failed
//We failed to create
if (!success) {
return {
object: null,
errorCode: 403,
errorDescription: 'We didnt have permddtttttttttission to create...'
};
}
return {
object: createdObject,
errorCode: 400,
errorDescription: ''
};
}
var myObject = createSomething('argument');
if (myObject.errorCode != 400) {
console.log(myObject.errorCode + ' ' + myObject.errorDescription)
}
//but myObject does not hold My Object but an implementative
//and accidental array
//from now on me need to remember this
Right
function createSomething(arguments) {
//Magic Creation
success = false; //we failed
//We failed to create
if (!success) {
throw new Error('We didnt have permission to create...');
}
return createdObject;
}
try {
var myObject = createSomething('argument');
//no IFS, just happy path
} catch (exception) {
//deal with it!
console.log(exception.message);
}
// myObject holds my expected object
Detection
We can teach our linters to find patterns of integer and strings returns coupled with ifs and return checking.
Exceptions
Conclusion
Ids and codes are external identifiers.
They are useful when you need to interact with an external system (for example an API Rest).
We should not use them on our own systems and our own internal APIs.
Create and raise generic exceptions.
Only create specific exceptions if you are ready to handle them, and they have specialized behavior.
Don't create anemic Exceptions.
Avoid immature and premature optimized languages favoring return codes.
More info
https://hackernoon.com/how-to-get-rid-of-annoying-ifs-forever-zuh3zlo
http://nicolecarpenter.github.io/2016/03/15/clean-code-chapter-7-error-handling.html
Error handling is important, but if it obscures logic, it’s wrong - Robert Martin
Code Smell 73 - Exceptions for Expected Cases
Exceptions are handy Gotos and flags. Let's abuse them.
Photo by Greg Rosenke on Unsplash
TL;DR: Do not use exceptions for flow control.
Problems
Readability
Principle of least astonishment Violation.
Solutions
Use Exceptions just for unexpected situations.
Exceptions handle contract violations. Read the contract.
Sample Code
Wrong
try {
for (int i = 0;; i++)
array[i]++;
} catch (ArrayIndexOutOfBoundsException e) {}
//Endless loop without end condition
Right
for (int index = 0; index < array.length; index++)
array[index]++;
//index < array.length breaks execution
Detection
This is a semantic smell. Unless we use machine learning linters it will be very difficult to find the mistakes.
Readability
Conclusion
Exceptions are handy, and we should definitively use them instead of returning codes.
The boundary between correct usage and wrong usage is blur like so many design principles.
Relations
More info
When debugging, novices insert corrective code; experts remove defective code - Richard Pattis
Code Smell 74 - Empty Lines
Breaking the code to favor readability asks for refactor.
Photo by Sigmund on Unsplash
TL;DR Don't add empty lines to your methods. Extract them!
Problems
Readability
Low Reuse
Solutions
Extract Method
Refactor
Remove unneeded lines.
Sample Code
Wrong
<?
function translateFile() {
$this->buildFilename();
$this->readFile();
$this->assertFileContentsAreOk();
//A lot of lines more
//Empty space to pause definition
$this->translateHiperLinks();
$this->translateMetadata();
$this->translatePlainText();
//Yet Another empty space
$this->generateStats();
$this->saveFileContents();
//A lot of more lines
}
Right
<?
function translateFile() {
$this->readFileToMemoy();
$this->translateContents();
$this->saveFileContents();
}
Detection
This is a policy smell. Every linter can detect blank lines and warn us.
Readability
Long Methods
Conclusion
Empty lines are harmless, but show us an opportunity to break the code into small steps.
If you break your code with comments, it is also a code smell asking for a refactor.
It’s OK to figure out murder mysteries, but you shouldn’t need to figure out code. You should be able to read it - Steve McConnell
Code Smell 75 - Comments Inside a Method
Comments are often a code smell. Inserting them inside a method calls for an urgent refactor.
Photo by Jason Rosewell on Unsplash
TL;DR Don't add comments inside your methods. Extract them and leave declarative comments just for not obvious design decisions.
Problems
Readability
Low Reuse
Bad Documentation
Solutions
Extract Method
Refactor
Remove not declarative comments.
Sample Code
Wrong
function recoverFromGrief() {
// Denial stage
absorbTheBadNews();
setNumbAsProtectiveState();
startToRiseEmotions();
feelSorrow();
// Anger stage
maskRealEffects();
directAngerToOtherPeople();
blameOthers();
getIrrational();
// bargaining stage
feelVulnerable();
regret();
askWhyToMyself();
dreamOfAlternativeWhatIfScenarios();
postoponeSadness();
// depression stage
stayQuiet();
getOverwhelmed();
beConfused();
// acceptance stage
acceptWhatHappened();
lookToTheFuture();
reconstructAndWalktrough();
}
Right
function recoverFromGrief() {
denialStage();
angerStage();
bargainingStage();
depressionStage();
acceptanceStage();
}
function denialStage() {
absorbTheBadNews();
setNumbAsProtectiveState();
startToRiseEmotions();
feelSorrow();
}
function angerStage() {
maskRealEffects();
directAngerToOtherPeople();
blameOthers();
getIrrational();
}
function bargainingStage() {
feelVulnerable();
regret();
askWhyToMyself();
dreamOfAlternativeWhatIfScenarios();
postoponeSadness();
}
function depressionStage() {
stayQuiet();
getOverwhelmed();
beConfused();
}
function acceptanceStage() {
acceptWhatHappened();
lookToTheFuture();
reconstructAndWalktrough();
}
Detection
This is a policy smell. Every linter can detect comments not in the first line and warn us.
Readability
Long Methods
Comments
Conclusion
Comments are a code smell. If you need to document a design decision, you should do it before the actual method code.
Relations
Code Smell 03 - Functions Are Too Long
Code Smell 05 - Comment Abusers
Don't get suckered in by the comments, they can be terribly misleading: Debug only the code - Dave Storer
And that’s all for now…
The next article will explain 5 more code smells!
Recommend
-
9
@mcseeMaximiliano ContieriI’m senior software engineer specialized in declarative designs and S.O.L.I.D. and Agile lover.
-
2
@mcseeMaximiliano ContieriI’m senior software engineer specialized in declarative designs and S.O.L.I.D. and Agile lover.Yet more code smells? More?...
-
3
How to Find The Stinky Parts of Your Code [Part XIV]February 24th 2022 new story4More smell...
-
4
How to Find the Stinky Parts of Your Code [Part XVI]April 6th 2022 new story4Infinite co...
-
8
@mcseeMaximiliano ContieriI’m senior software engineer specialized in declarative designs and S.O.L.I.D. and Agile lover.
-
1
Code smells are a classic. It smells because there are likely many instances where it could be edited or improved. Most of these smells are just hints of something that might be wrong. They are not required fixed per se… (You shoul...
-
4
Code smells Are a Classic. It smells because there are likely many instances where it could be edited or improved. Most of these smells are just hints of something that might be wrong. Therefore, they are not required to be fixed p...
-
4
Your browser does not support theaudio element.Read by Dr. One (en-US)
-
5
@mcseeMaximiliano ContieriI’m senior software engineer specialized in declarative d...
-
6
@mcseeMaximiliano ContieriI’m senior software engineer specialized in declarative d...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK