How to Find The Stinky Parts of Your Code (Part VI)

Written by mcsee | Published 2020/12/10
Tech Story Tags: code-smells | clean-code | programming | refactoring | pixel-face | software-engineering | software-development | hackernoon-top-story | web-monetization

TLDRvia the TL;DR App

Are we tired with code smells? Not yet!
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.
This is part V. Part I can be found here, Part II here, Part III is here, Part IV here and the last one (for now).
Let's continue...

Code Smell 26 — Exceptions Polluting

It is very nice to have lots of different exceptions. Your code is declarative and robust. Or not?

Problems

  • Over Design
  • Namespace Pollution

Solutions

Avoid creating anemic exceptions as globals.
  1. Create exceptions only if they behave differently.
  2. Model exceptions with objects. Classes are handy for lazy programmers.

Sample Code

Wrong
Right

Detection

New exceptions should override behavior methods.
No. codedescriptionresumable, etc are not behavioral.

Tags

  • Abuser
  • Naming

Conclusion

You would not create different classes for every Person instance, so they return different names. Why would you do it with exceptions.
How often do you catch a specific exception?.
Go out and check your code.
Is it necessary to be a class?
You are already coupled to the class. Couple to the description instead.
Exception instances should NOT be Singletons.
You will fall to ruin because you believe that exceptions to the rule make new rules.
Pierce Brown

Code Smell 27 — Associative Arrays

[Key, values], magic, fast, malleable and error prune.
Photo by Melissa Askew on Unsplash

Problems

  • Coupling
  • Information Hiding
  • Code Duplication
  • Fail Fast
  • Integrity

Solutions

  1. Reify objects
  2. Create cohesive small objects.
  3. Don’t leave them anemic, find their cohesive relations.

Sample Code

Wrong
Anemic
Validated
Right
Degrees deserves reification
Many people suffer from primitive obsession and believe this is over design. Designing software is about making decisions and comparing trade-offs. The performance argument is not valid nowadays since modern virtual machines can efficiently deal with small short-lived objects.

Detection

We cannot forbid Associative Arrays since they are very good as a first approach.
They will be fine for exporting data, serialization, persistence and other accidental implementation issues.
We should avoid them on our systems.

Tags

  • Primitive

Conclusion

When creating objects we must not think of them as data. This is a common misconception.
We should stay loyal to our Bijection and discover real world objects.
Most associative arrays have cohesion and represent real world entities, and we must treat them as first class objects.
There’s nothing more permanent than a temporary hack.
Kyle Simpson

Code Smell 28 — Setters

The first exercise junior programmers do. IDEs, tutorials and senior developers keep teaching them this anti-pattern.
Photo by Victor Rodriguez on Unsplash

Problems

  • Mutability
  • Information Hiding
  • Anemic Models
  • Fail Fast
  • Integrity
  • Duplicated Code

Solutions

  1. Avoid Setters
  2. Set essential attributes on private initialization.

Sample Code

Wrong
Mutation brings lots of problems
Information Hiding Violated

Right

Detection

First step will be to forbid public attributes (if language allows them).
Secondly, we will search for methods setXXXX(), analyzing method structure (should be an assignment to attribute xxxx).
We should not forbid methods setting accidental state since this is valid. They should not be named setters since they ask the object to change, but they don’t set anything.

Examples

  • DTOs

Exceptions

Setting attributes is safe for non-essential attributes.
Essential behavior is what distinguishes one object from another.
It is related to behavior and not data. It’s not a primary key definition.
Some patterns, like Builder require setting the parts in a controlled, incremental way. Validations are done at the end and the real entity metaphor requires it.
Setting accidental values has many drawbacks and considerations already mentioned.

Tags

  • Mutation
  • Information Hiding

Conclusion

Creating incomplete and anemic objects is a very bad practice violating
mutability, fail fast principle and real world bijections.

More Info

Here is the full discussion on Setters
Object-oriented programming languages support encapsulation, thereby improving the ability of software to be reused, refined, tested, maintained, and extended. The full benefit of this support can only be realized if encapsulation is maximized during the design process.
Rebecca Wirfs-Brock

Code Smell 29 — Settings/Configs

Changing system behavior in a control board is the customer’s dream. And the software engineer’s nightmare.

Problems

  • Duplicated Code
  • If Pollution
  • Global usage
  • Coupling
  • Testability and explosion of testing scenarios.
  • Complexity

Solutions

  1. Avoid Settings
  2. Create polymorphic objects. Inject them externally.

Sample Code

Wrong
Right

Detection

This is an architectural pattern so it should be controlled/avoided by design policies.

Examples

Exceptions

  • Sometimes we use Feature togging as a safeguard mechanism. This is acceptable in a legacy system. These toggles should be very short-lived in a CI/CD system.
  • Hyper parameter settings should be managed by configuration objects.

Tags

  • Globals

Conclusion

Setting runtime behavior is great for software systems.
We should configure our objects, so they can behave in different ways, and we should achieve it in an explicit way with explicit behavioral objects.
In this way, our code will be more declarative, clean and testable. It is not as easy as adding an IF Statement. This kind of lazy developers bring lots of coupling and unexpected issues on our systems.
A system with 300 Boolean configurations has more test combinations (2^300), than the number of atoms in the universe (10^80).

Also known as

Feature Toggles

More Info

Simplicity is the soul of efficiency.
Austin Freeman

Code Smell 30 — Mocking Business

Mocking is a great aid when testing behavior. Like with many other tools, we are abusing them.
Photo by Syed Ahmad on Unsplash

Problems

  • Complexity
  • False sense of security.
  • Parallel/Duplicated objects (Real and Mocks)
  • Maintainability

Solutions

  1. Mock just non-business entities.
  2. Remove mock if its interface has too much behavior.

Sample Code

Wrong
Right

Detection

This is an architectural pattern. It will not be easy to create an automatic detection rule.

Exceptions

  • Mocking accidental problems (serialization, databases, APIs) is a very good practice to avoid coupling.

Tags

  • Abuser

Conclusion

Mocks, like many other test doubles are excellent tools. Choosing wisely when to use them is an art.
Imagine a play in which each actor, instead of rehearsing with other actors, had to interact with 25 scriptwriters. The actors would never rehearse together. How would the result of the play be?

Also Known as

  • Faker
The pesticide paradox. Every method you use to prevent or find bugs leaves a residue of subtler bugs against which those methods are ineffective.
Boris Beizer
This is a never ending article. I hope, in a couple of decades, this series could be a piece of ancient history and old deprecated memories.

Written by mcsee | I’m senior software engineer specialized in declarative designs and S.O.L.I.D. and Agile lover.
Published by HackerNoon on 2020/12/10