## 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) * [Part XVII](https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xvii) \ Let's continue... --- # Code Smell 86 - Mutable Const Arrays *Const declares something to be constant. Can it mutate?* \  \ > TL;DR: Don't rely on languages cheating about directives. # Problems * Unexpected side effects * Accidental complexity # Solutions 1. Use better languages 2. Use [spread operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax) # Sample Code ## Wrong ```javascript const array = [1, 2]; array.push(3) //array => [1, 2, 3] //Wasn't it constant ? //constant != immutable ? ``` ## Right ```javascript const array = [1, 2]; const newArray = [...array,3 ] //array => [1, 2] Didn't mutate //newArray = [1, 2, 3] ``` # Detection Since this is a "language feature", we can explicitly forbid it. # Tags * Mutability * JavaScript # Conclusion We should always favour immutability on our designs and take extra care with side effects. # More Info * [The evil power of mutants](https://hackernoon.com/is-it-crystal-clear-for-everybody-that-a-date-should-not-mutate-wuoy3z03) # Credits Photo by [Zorik D](https://unsplash.com/@justzorik) on [Unsplash](https://unsplash.com/s/photos/zombie) [Twitter](https://twitter.com/1430154471921922049) ___ > Correctness is clearly the prime quality. If a system does not do what it is supposed to do, then everything else about it matters little. *Bertrand Meyer* ___ # Code Smell 87 - Inconsistent Parameters Sorting *Be consistent with the parameters you use. Code is prose.* \  > TL;DR: Don't confuse you readers. Keep the order. # Problems * Readability * Consistency # Solutions 1. Refactor and change parameters order. 2. Use [named parameters](https://en.wikipedia.org/wiki/Named_parameter) # Sample Code ## Wrong ```javascript function giveFirstDoseOfVaccine(person, vaccine) { // } function giveSecondDoseOfVaccine(vaccine, person) { // } giveFirstDoseOfVaccine(jane, pfizer); giveSecondDoseOfVaccine(jane, pfizer); //Unnoticed mistake ``` ## Right ```javascript function giveFirstDoseOfVaccine(person, vaccine) { // } function giveSecondDoseOfVaccine(person, vaccine) { // } giveFirstDoseOfVaccine(jane, pfizer); giveSecondDoseOfVaccine(jane, pfizer); //Jane is immunized ``` # Detection * Some very smart linters may be able to compare arguments and hint for possible mistakes. # Tags * Readability # Conclusion This is a very simple smell. Readability is very important to avoid mistakes. # Relations [Code Smell 10 - Too Many Arguments](https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-ii-o96s3wl4) # Credits Photo by [Lance Grandahl](https://unsplash.com/@lg17) on [Unsplash](https://unsplash.com/s/photos/disorder) [Twitter](https://twitter.com/1441462443364864006) ___ > Computers are good at following instructions, but not at reading your mind. *Donald Knuth* ___ # Code Smell 88 - Lazy Initialization *Yet another premature optimization pattern* \  > TL;DR: Do not use lazy initialization. Use an object provider instead. # Problems * Surprising Side Effects * Premature Optimization * Fail Fast Violation * Implementative Coupling * The Least Surprise Principle Violation * [Null Usage](https://hackernoon.com/null-the-billion-dollar-mistake-8t5z32d6) * Mutability * Transactional and Multi-threaded applications problems * [Debugging Problems](https://martinfowler.com/bliki/LazyInitialization.html) # Solutions 1. Inject Responsibilities with First Class Objects # Sample Code ## Wrong ```ruby class Employee def emails @emails ||= [] end def voice_mails @voice_mails ||= [] end end ``` ## Right ```ruby class Employee attr_reader :emails, :voice_mails def initialize @emails = [] @voice_mails = [] end end #We can also inject a design pattern to externally deal #with voice_mails so we can mock it in our tests ``` # Detection Lazy initialization is a common pattern when used checking for a non-initialized variable. It should be straightforward to detect them. # Tags * Premature Optimization # Conclusion [Singletons](https://hackernoon.com/singleton-pattern-the-root-of-all-evil-e4r3up7) are another antipattern often combined with lazy initialization. We must avoid premature optimizations. If we have *real* performance problems we should use a Proxy, Facade or more independent solution. # Relations [Code Smell 32 - Singletons](https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-vii-8dk31x0) [Code Smell 12 - Null](https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-iii-t7h3zkv) # More Info * [Wikipedia](https://en.wikipedia.org/wiki/Lazy_initialization) * [Martin Fowler](https://martinfowler.com/bliki/LazyInitialization.html) # Credits Photo by [Sam Solomon](https://unsplash.com/@samsolomon) on [Unsplash](https://unsplash.com/s/photos/lazy) ___ > We have to stop optimizing for programmers and start optimizing for users. *Jeff Atwood* ___ # Code Smell 89 - Math Feature Envy *One class calculating formulas for another class.* \  > TL;DR: Leave the formulas to the objects gathering the information. # Problems * Declaratively * Low reuse * Real-world concept missing * Encapsulation # Solutions 1. Move the math formula to the class 2. Search for [real-world abstractions](https://hackernoon.com/the-one-and-only-software-design-principle-1x983ylp) # Sample Code ## Wrong ```javascript function area(rectangle) { return rectange.width * rectangle.height; //Notice we are sending consecutive messages to //the same object and doing calculations } ``` ## Right ```javascript class Rectangle { constructor(width, height, color) { this.height = height; this.width = width; } area() { return this.width * this.height; } } ``` # Detection Since many cascading messages are sending to the same object, we can detect a pattern. # Tags * Encapsulation * Coupling # Conclusion This is a very basic smell. If we are manipulating another object characteristics, we should let it do it the maths for us. # Relations [Code Smell 63 - Feature Envy](https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xiii) # More Info * [The one and only one software principle](https://hackernoon.com/the-one-and-only-software-design-principle-1x983ylp) # Credits Photo by [Michal Matlon](https://unsplash.com/@michalmatlon) on [Unsplash](https://unsplash.com/s/photos/math) ___ > Computer science is not about machines, in the same way that astronomy is not about telescopes. There is an essential unity of mathematics and computer science. *Michael R. Fellows* \ ___ # Code Smell 90 - Implementative Callback Events *When creating events, we should decouple the trigger from the action.* \  > TL;DR: Name your functions acording to what happened. # Problems * [Observer Pattern](https://en.wikipedia.org/wiki/Observer_pattern) violation * Coupling # Solutions 1. Name the events after "what happened", not "what you should do". # Sample Code ## Wrong ```javascript const Item = ({name, handlePageChange)} => <li onClick={handlePageChange}> {name} </li> //handlePageChange is coupled to what you decide to do //instead of what really happened // //We cannot reuse this kind of callbacks ``` ## Right ```javascript const Item = ({name, onItemSelected)} => <li onClick={onItemSelected}> {name} </li> //onItemSelected will be called just when a item was selected. KISS //Parent can decide what to do (or do nothing) //We defer the decision ``` # Detection This is a semantic smell. We can detect it on peer code reviews. # Tags * Coupling * Naming # Conclusion Names are very important. We should delay implementation coupled names until the very last moment. # More Info * [What is exactly in a name](https://hackernoon.com/what-exactly-is-a-name-the-quest-part-i-fmw3udc) * [Refactoring Guru](https://refactoring.guru/es/design-patterns/observer) # Credits Photo by [Ashim D’Silva](https://unsplash.com/@randomlies) on [Unsplash](https://unsplash.com/s/photos/button-pressed) Thanks to Maciej for this tip [Twitter](https://twitter.com/1445692315360653318) ___ > Beyond basic mathematical aptitude, the difference between good programmers and great programmers is verbal ability. *Marissa Mayer* --- And that’s all for now… The next article will explain 5 more code smells!