Decompositie is het opdelen van een grote taak in kleinere, beheersbare subtaken of functies. Historisch gezien is decompositie ontstaan als een keyprincipe van modulair programmeren: het vergemakkelijkt het beheer van complexiteit, testbaarheid en herbruikbaarheid van code.
Probleem: Zonder decompositie wordt code een "monoliet": het is moeilijk leesbaar, moeilijk te onderhouden en te wijzigen, en het wordt lastiger om tests te schrijven en delen van het programma opnieuw te gebruiken.
Oplossing: In Python wordt decompositie geïmplementeerd door de logica in functies, klassen en modules op te splitsen; door duidelijke namen te gebruiken; door compositie en abstracties te gebruiken. Dit maakt het mogelijk om leesbare en schaalbare code te schrijven.
Codevoorbeeld:
# Niet-gecompacteerde monolithische code numbers = [1, 2, 3, 4] squares = [] for n in numbers: if n % 2 == 0: squares.append(n**2) print(squares) # Gedemonteerde versie def is_even(n): return n % 2 == 0 def square(n): return n ** 2 def filter_and_apply(numbers, predicate, func): return [func(n) for n in numbers if predicate(n)] numbers = [1, 2, 3, 4] result = filter_and_apply(numbers, is_even, square) print(result)
Belangrijke kenmerken:
Kan één functie alle businesslogica implementeren als deze klein is?
Vaak wordt aangenomen dat als een taak klein is, het is toegestaan om een "functie van 100 regels" te schrijven. Dit is een anti-patroon: zelfs een kleine taak wordt complexer bij de kleinste wijzigingen; microfuncties zijn veel eenvoudiger te testen en te onderhouden.
Kunnen functies met dezelfde logica maar verschillende namen worden beschouwd als decompositie?
Nee, code duplicatie is geen goede decompositie. Herhalende code duidt op onjuist gekozen grenzen van subtaken. Herhalende functionaliteit moet altijd naar hulpfuncties worden verplaatst.
Voorbeeld:
def add_user(): pass # logica def add_admin(): pass # dezelfde logica als hierboven!
Moet je hulptaken decomponeren als ze slechts op één plek worden gebruikt?
Ja, vaak kunnen dergelijke functies de code zelfs bij eenmalig gebruik eenvoudiger maken (bijvoorbeeld door voorwaarden of filtering in een aparte functie te plaatsen).
Een project met gegevensverwerking kwam binnen via één enorme functie van 300 regels. Elke bug veroorzaakte paniek: het was onmogelijk om snel te begrijpen wat en waar er fout ging, testbaarheid was vrijwel onmogelijk.
Voordelen:
Nadelen:
Hetzelfde project, refactoring — de code is gesplitst in kleine functies en klassen op basis van de belangrijkste logica (lezen, valideren, verwerken, gegevens opslaan).
Voordelen:
Nadelen: