Combinatorial Explosion — Code Smells Catalog Skip to content

Combinatorial Explosion

Bloaters Responsibility Code SmellDesign Smell Within Class

Dozens of methods that do almost the same thing, each differing by one small detail. Add a new feature and the count multiplies again. Good luck remembering which variant handles which edge case.

2 min read 1 source

Overview

The Combinatorial Explosion occurs when a lot of code does almost the same thing - here, the word “almost” is crucial. The number of cases needed to cover every possible path is massive, as is the number of methods. You can grasp a solid intuition of this smell by thinking about code blocks that differ from each other only by the quantities of data or objects used in them. Wake specifies that ”(…) this is a relative of Parallel Inheritance Hierarchies Code Smell, but everything has been folded into one hierarchy.” [1].

Causation

Instead, what should be an independent decision, gets implemented via a hierarchy. Let us suppose that someone organized the code so that it queries an API by a specific method with specific set-in conditions and data. Sooner or later, there are just so many of these methods as the need for different queries increases in demand.

Problems

Don't Repeat Yourself Principle Violation

Introducing new functionality requires multiple versions to be introduced in various places.

Open-Closed Principle Violation

Class is not closed for modification if it "prompts" the developer to add another elif.

Violated Principles
Open Closed
Violated Patterns
DecoratorStrategyState

Example

1class Minion:
2    name: str
3    state: 'ready'
4
5    def action(self):
6        if self.state == 'ready':
7            self.animate('standing')
8        elif self.state == 'fighting':
9            self.animate('fighting')
10        elif self.state == 'resting':
11            self.animate('resting')
12
13    def next_state(self):
14        if self.state == 'ready':
15            return 'fighting'
16        elif self.state == 'fighting':
17            return 'resting'
18        elif self.state == 'resting':
19            return 'ready'
20
21    def animate(self, animation: str):
22        print(f"{self.name} is {animation}!")
PYTHON

Refactoring

  • Replace Inheritance with Delegation
  • Tease Apart Inheritance

Sources

Browse All 56 Smells