## Infinite code, smells! 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 should look into it though.) ## **Previous Code Smells** * [Part I](https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-i-xqz3evd) * [Part II](https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-ii-o96s3wl4) * [Part III](https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-iii-t7h3zkv) * [Part IV](https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-iv-7sc3w8n) * [Part V](https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-v-evj3zs9) * [Part VI](https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-vi-cmj31om) * [Part VII](https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-vii-8dk31x0) * [Part VIII](https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-viii-8mn3352) * [Part IX](https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-ix-7rr33ol) * [Part X](https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-x-i7r34uj) * [Part XI](https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xi-sit35t1) * [Part XII](https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xii) * [Part XIII](https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xiii) * [Part XIV](https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xiv) * [Part XV](https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xv) * [Part XVI](https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xvi) \ Let's continue... \ # Code Smell 81 - Result *result = ???* \  \ > TL;DR: Use good names always. Result is always a very bad name. # Problems * Readability # Solutions 1. Rename *result*. 2. If you don't know how to name it, just name the variable with the same name as the last function call. 3. Don't use IDEs without automatic refactors. # Sample Code ## Wrong ```javascript var result; result = lastBlockchainBlock(); // // Many function calls addBlockAfter(result); ``` ## Right ```javascript var lastBlockchainBlock; lastBlockchainBlock = findlastBlockchainBlock(); //... // Many function calls // we should refactor them to minimize space // between variable definition and usage addBlockAfter(lastBlockchainBlock); ``` # Detection We must forbid the word result to be a variable name. # Tags * Readability # Conclusion *Result* is an example of generic and meaningless names. Refactoring is cheap and safe. > Always leave the campground cleaner than you found it. > When you find a mess on the ground, clean it, doesn’t matter who did it. Your job is to always leave the ground cleaner for the next campers. # Relations [Code Smell 79 - TheResult](https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xvi) # More info * [What is in a name? Part I: Rehab](https://hackernoon.com/what-exactly-is-a-name-rehab-part-ii-4st3uph). # Credits Photo by [KMA .](https://unsplash.com/@kmaimg) on [Unsplash](https://unsplash.com/s/photos/magician) ___ > Code is like humor. When you have to explain it, it’s bad. *Cory House* ___ # Code Smell 82 - Tests Violating Encapsulation *Objects work fine and fulfill business objectives. But we need to test them. Let's break them.*  > TL;DR: Don't write methods with the only purpose of being used in your tests. # Problems * Encapsulation Violation. * Bad interfaces * Coupling # Solutions 1. Don't break encapsulation. 2. Test must be in full control. 3. If you cannot control your object, you are coupled. Decouple them! # Sample Code ## Wrong ```php <? class Hangman { private $wordToGuess; function __construct() { $this->wordToGuess = getRandomWord(); //Test is not in control of this } public function getWordToGuess(): string { return $this->wordToGuess; //Sadly we need to reveal this } } class HangmanTest extends TestCase { function test01WordIsGuessed() { $hangmanGame = new Hangman(); $this->assertEquals('tests', $hangmanGame->wordToGuess()); //how can we make sure the word is guessed? } } ``` ## Right ```php <? class Hangman { private $wordToGuess; function __construct(WordRandomizer $wordRandomizer) { $this->wordToGuess = $wordRandomizer->newRandomWord(); } } class MockRandomizer implements WordRandomizer { function newRandomWord(): string { return 'tests'; } } class HangmanTest extends TestCase { function test01WordIsGuessed() { $hangmanGame = new Hangman(new MockRandomizer()); //We are in full control! $this->assertFalse($hangmanGame->wordWasGuessed()); $hangmanGame->play('t'); $this->assertFalse($hangmanGame->wordWasGuessed()); $hangmanGame->play('e'); $this->assertFalse($hangmanGame->wordWasGuessed()); $hangmanGame->play('s'); $this->assertTrue($hangmanGame->wordWasGuessed()); //We just test behavior } } ``` # Detection This is a design smell. We can detect we need a method just for test. # Tags * Information Hiding # Conclusion White-box tests are fragile. They test implementation instead of behavior. # Relations [Code Smell 52 - Fragile Tests](https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xi-sit35t1) [Code Smell 28 - Setters](https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-vi-cmj31om) # More Info * [Should I Test Private Methods](http://shoulditestprivatemethods.com/) # Credits This smell was inspired by @[Rodrigo](https://twitter.com/_rodrigomd) [Twitter](https://twitter.com/1408032157629485056) \ ___ > Nothing makes a system more flexible than a suite of tests. *Robert Martin* ___ # Code Smell 83 - Variables Reassignment *Variable reuse is something we see in big chunks of code.* \  \ > TL;DR: Don't reuse variable names. You break readability and refactor chances and gain nothing but laziness. # Problems * Readability * Refactor chances * Missed Optimization * Mutability * Garbage Collection Missed Opportunities # Solutions 1. Define, use and dispose variables. 2. Keep your Definition, Usage and Destroy variables short. # Sample Code ## Wrong ```python class Item: def __init__(self, name): self.name = name def taxesCharged(self): return 1; class Money: pass lastPurchase = Item('Soda'); # Do something with the purchase taxAmount = lastPurchase.taxesCharged(); # Lots of stuff related to the purchase # I drink the soda # I cannot extract method from below without passing # useless lastPurchase as parameter # a few hours later.. lastPurchase = Item('Whisky'); # I bough another drink taxAmount += lastPurchase.taxesCharged(); ``` ## Right ```python class Item: def __init__(self, name): self.name = name def taxesCharged(self): return 1; class Money: pass def buySupper(): supperPurchase = Item('Soda'); # Do something with the purchase # Lots of stuff related to the purchase # I drink the soda return supperPurchase; def buyDrinks(): # I could extract method! # a few hours later.. drinksPurchase = Item('Whisky'); # I bough another drink return drinksPurchase; taxAmount = buySupper().taxesCharged() + buyDrinks().taxesCharged(); ``` # Detection Many linters can warn us from reusing variables # Tags * Readability # Conclusion Reusing variables is a non-contextual copy and paste hint. # Relations [Code Smell 03 - Functions Are Too Long](https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-i-xqz3evd) # More Info * [The Evil power of Mutants](https://hackernoon.com/is-it-crystal-clear-for-everybody-that-a-date-should-not-mutate-wuoy3z03) * [Stack Exchange](https://softwareengineering.stackexchange.com/questions/115520/should-i-reuse-variables) * [Wikiversity](https://en.wikiversity.org/wiki/Software_Design/Don%27t_reuse_a_variable) # Credits Photo by [Robby McCullough](https://unsplash.com/@mybbor) on [Unsplash](https://unsplash.com/s/photos/spiral) [Twitter](https://twitter.com/1414832436547133440) ___ > Either way you look at it (DRY or laziness), the idea is the same: make your program flexible. When change comes (and it always does), you'll have a much easier time changing with it. *Chris Pine* \ ___ # Code Smell 84 - Max < Min (Javascript) *Some functions do not behave as expected. Sadly, most programmers accept them.* \  \ \ > TL;DR: Don't trust max() and min() functions. Just ignore them. # Problems * Principle of least astonishment * [Bijection](https://hackernoon.com/the-one-and-only-software-design-principle-1x983ylp) Violation. * Unexpected Results # Solutions 1. Use mature languages. 2. Avoid *max()* and *min()* functions. 3. Model Infinites carefully. # Sample Code ## Wrong ```javascript console.log(Math.max() > Math.min()); //returns false console.log(Math.max()); //returns -Infinite ``` ## Right ```javascript console.log(Math.max() > Math.min()); console.log(Math.max()); //returns Exception. Not enough arguments passed. //Max requires at least one argument ``` # Detection These functions belong to the standard Math library. Therefore, they are not easy to avoid. We can block them on our linters. # Tags * Javascript # Conclusion We need to be very careful using functions that violate real-world concepts using language tricks. # Relations [Code Smell 69 - Big Bang (JavaScript Ridiculous Castings)](https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xiv) # More Info * [Principle of least astonishment](https://en.wikipedia.org/wiki/Principle_of_least_astonishment) * [Bijection Principle](https://hackernoon.com/the-one-and-only-software-design-principle-1x983ylp) * [MAPPER](https://hackernoon.com/what-is-wrong-with-software-uh8j3y7k) # Credits Photo by [Cris Baron](https://unsplash.com/@cris024) on [Unsplash](https://unsplash.com/s/photos/infinite) Inspired by @@[Oliver Jumpertz](@OliverJumpertz) [Twitter](https://twitter.com/1416798870747684864) ___ > Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning. *Rick Cook* ___ # Code Smell 85 - And Functions  \ \ *Do not perform more than requested.* > TL;DR: Unless you need atomicity, do not perform more than one task. # Problems * Coupling * Single Responsibility Principle violation * Readability * Low Cohesion * Testability # Solutions 1. Break the function # Sample Code ## Wrong ```python def fetch_and_display_personnel(): data = # ... for person in data: print(person) ``` ## Right ```python def fetch_personnel(): return # ... def display_personnel(data): for person in data: print(person) ``` # Detection Functions including "and" are candidates. However, we need to check them carefully since there might be false positives. # Tags * Readability * Naming # Conclusion We should avoid doing more than needed, and our functions should be both minimal and atomic. # More Info * [What exactly is a name — Part II Rehab](https://hackernoon.com/what-exactly-is-a-name-rehab-part-ii-4st3uph) # Credits Photo by [Paul](https://unsplash.com/@causeimluap) on [Unsplash](https://unsplash.com/s/photos/train) This smell was inspired by [Twitter](https://twitter.com/1428027665529769985) ___ > If it takes more than a sentence to explain what you are doing, it’s almost always a sign that what you are doing is too complicated. *Sam Altman* ___ And that’s all for now… The next article will explain 5 more code smells!