I’m senior software engineer specialized in declarative designs and S.O.L.I.D. and Agile lover.
Yet more code smells? Plenty of!
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.
Code Smell 31 — Accidental Methods on Business Objects
Adding persistence, serialization, displaying, importing, exporting code to an object bloats its protocol and brings coupling.
- Keep your objects clean.
- Decouple business objects.
- Separate accidental concerns:
- Move Persistence, Formatting, Serialization to special objects.
- Keep essential protocol using bijection.
It is difficult (but not impossible) to create linting rules based on naming and hinting for suspect names.
- Some frameworks force us to inject dirty code in our objects. (For example identifiers).
We should try to use better languages/frameworks.
We are very used to see business objects polluted. This is normal. We need to reflect on the consequences and coupling from these designs.
Simple things should be simple, complex things should be possible.
Code Smell 32 — Singletons
The most used and (in)famous design pattern in the world is causing us great harm.
- Accidental implementation problems.
- Multi threading issues.
- Static methods polluting.
- Object creation contract violation.
- Bijection mismatch.
- Memory issues.
- Premature Optimization.
- Avoid it.
- Use contextual unique objects.
- Benchmark object creation.
- Database Access
God is the archetypical singleton example.
This is a design pattern. We should avoid it by policy.
We can add linter rules for patterns like ‘getInstance()’ so new developers cannot infect code with this anti-pattern.
This is an historical mistake already acknowledged by the community. Nevertheless, lazy developers bring it again and again. We need to reach a consensus on its drawbacks.
The Diagram is Not the Model. The model is not the diagram. It is an abstraction, a set of concepts and relationships between them.
Code Smell 33 — Abbreviations
Abbreviating is very important so that we look smart and save memory and mind space.
- Bad Naming
- Premature Optimization
Use meaningful and declarative names.
- Variable naming
- Function naming
- Package naming
- Class Naming
We can’t automate choosing what is a short name and a declarative.
Some “modern” and shinny languages enforce this bad practice. So we should wisely choose a good language instead.
Computer science was born from the mother of science (mathematics). In math, the assignment of single letter variables (i, j, x, y) is a good practice.
The concept of reference arose from the variable.
Many people wondered why mathematicians can work with such short variables, and computer scientists cannot.
For mathematicians, once entered into a formula, variables lose all semantics and become indistinguishable.
Our brain wastes a lot of energy figuring out what is the meaning of an abbreviation.
It is 2020, We need to write software for humans, not for compilers.
A long descriptive name is better than a short enigmatic name. A long descriptive name is better than a long descriptive comment.
Code Smell 34 — Too Many Attributes
A class defines objects with lots of attributes.
- Low Cohesion
- Find methods related to attributes.
- Cluster these methods.
- Break the object related to those clusters.
- Find real objects related to this new objects and replace existing references.
- Denormalized table rows
Most linters warn when you declare too many attributes. Setting a good warning threshold should be easy.
Bloated objects know too much and are very difficult to change due to cohesion.
Developers change these objects a lot, so they bring merge conflicts and are a common problems source.
So much complexity in software comes from trying to make one thing do two things.
Code Smell 35 — State as Properties
When an object changes its state the best solution is to change the attribute, isn’t it?
- Attributes polluting
- Model states as mathematical set inclusion.
- State is accidental, take it away from the object.
- State diagrams
If we want to be extreme, we should consider every setter to be a potential state change. Linters can warn us. But we might end up getting too many false positives.
- Over Design
- Performance issues (if a serious benchmark supports it).
This technique is very elegant but can lead to over design. For example changing a visual component’s color should be a counterexample to this smell.
We should be aware and very caution like with any other smell.
They are hints and not rigid rules.
First make the change easy (warning: this might be hard), then make the easy change.
Those were the first 35. Nevertheless, I keep getting more suggestions on twitter, so they won’t be the last!
Create your free account to unlock your custom reading experience.