Overview
Null check is widespread everywhere because the programming languages allow it. It causes a multitude of undefined or null checks everywhere: in guard checks, in condition blocks, and verifications clauses. Instead, special objects could be created that implement the missing-event behavior, errors could be thrown and catched, and many duplications would be removed. Even an anecdote sometimes appears here and there on discussion forums that the inventor of the null reference, Tony Hoare (also known as the creator of the QuickSort algorithm), apologizes for its invention and calls it a billion-dollar mistake.
Null Check is a special case of Special Case code smell.
Causation
The direct cause of null checking is the lack of a proper Null Object that might implement the object’s behavior in case it’s null. There is a strong opinion that null or undefined is a detrimentally bad idea in programming languages [1].
Problems
Usually, the null check reoccurs.
Special cases must be made for an object that might be undefined.
A null/undefined as a model is not in a one-to-one relationship with the domain. Moreover, there is no representation.
Example
1class BonusDamage(ABC):
2 @abstractmethod
3 def increase_damage(self, damage: float) -> float:
4 """ Increases the output damage """
5
6
7class Critical(BonusDamage):
8 multiplier: float
9
10 def increase_damage(self, damage: float):
11 def additional_damage() -> float:
12 return damage * self.multiplier * math.random(0, 2)
13
14 return damage + additional_damage()
15
16
17class Magical(BonusDamage):
18 multiplier: float
19
20 def increase_damage(self, damage: float):
21 return damage * multiplier
22
23
24bonus_damage: BonusDamage | None = perk.get_bonus_damage()
25
26def example_of_doing_something_with_bonus_damage(bonus_damage: BonusDamage | None) -> ... | None:
27 if not bonus_damage:
28 return
29
30 ...Exceptions
Similar to the if statements, one usually is not problematic. Creating a separate Null Object to handle this case (for example, when it is only in the Factory method [WAKE]) might not be worth the hassle.
---
Refactoring
- Introduce Null Object
- Introduce Maybe
- Introduce Optional
Sources
- ORIGIN2004 · ISBN 978-0321109293