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...
It is very nice to have lots of different exceptions. Your code is declarative and robust. Or not?
Photo by Nick van den Berg on Unsplash
Avoid creating anemic exceptions as globals.
Wrong
Right
New exceptions should override behavior methods.
No. code, description, resumable, etc are not behavioral.
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
[Key, values], magic, fast, malleable and error prune.
Photo by Melissa Askew on Unsplash
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.
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.
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
The first exercise junior programmers do. IDEs, tutorials and senior developers keep teaching them this anti-pattern.
Photo by Victor Rodriguez on Unsplash
Wrong
Mutation brings lots of problems
Information Hiding Violated
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.
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.
Creating incomplete and anemic objects is a very bad practice violating
mutability, fail fast principle and real world bijections.
Fail Fast Philosophy, Explained
Here is the full discussion on Setters
Nude Models - Part I : 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
Changing system behavior in a control board is the customer’s dream. And the software engineer’s nightmare.
Wrong
Right
This is an architectural pattern so it should be controlled/avoided by design policies.
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).
How to Get Rid of Annoying IFs Forever
Simplicity is the soul of efficiency.
Austin Freeman
Mocking is a great aid when testing behavior. Like with many other tools, we are abusing them.
Photo by Syed Ahmad on Unsplash
Wrong
Right
This is an architectural pattern. It will not be easy to create an automatic detection rule.
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?
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.